Algorithm

[Xcode] 여러개 main.cpp을 한 프로젝트에서 실행하는 법 | [Xcode] How to Run Multiple main.cpp Files in a Single Project

백준알고리즘, 리트코드를 풀다보면 여러개의 solution.cpp 파일 혹은 main.cpp을 만들어서 실행해야하는 경우가 많습니다.한개의 Xcode 프로젝트에 여러개의 main.cpp를 만드는 방법을 포스팅하려 합니다.1. 새로운 Xcode 프로젝트를 생성합니다.이때 프로젝트의 Command Line Tool 으로 만들어 줍니다.2. 새로운 프로젝트의 옵션을 적어줍니다.3. Xcode project 프로젝트를 클릭합니다.4. 프로젝트의 하단을 보면 프로젝트와 타겟에 대해 적혀있는 바의 하단을 보면 + - 가 있습니다. 이때 +를 눌러서 새로운 Target을 생성해줍니다.Target 생성도 역시 1~2와 같이 Command Line Tool로 선택을 하고, Product Name을 지정해서 생성합니다.5..

[Xcode] 여러개 main.cpp을 한 프로젝트에서 실행하는 법 | [Xcode] How to Run Multiple main.cpp Files in a Single Project

728x90

백준알고리즘, 리트코드를 풀다보면 여러개의 solution.cpp 파일 혹은 main.cpp을 만들어서 실행해야하는 경우가 많습니다.
한개의 Xcode 프로젝트에 여러개의 main.cpp를 만드는 방법을 포스팅하려 합니다.

1. 새로운 Xcode 프로젝트를 생성합니다.
이때 프로젝트의 Command Line Tool 으로 만들어 줍니다.

2. 새로운 프로젝트의 옵션을 적어줍니다.

3. Xcode project 프로젝트를 클릭합니다.

4. 프로젝트의 하단을 보면 프로젝트와 타겟에 대해 적혀있는 바의 하단을 보면 + - 가 있습니다. 이때 +를 눌러서
새로운 Target을 생성해줍니다.

Target 생성도 역시 1~2와 같이 Command Line Tool로 선택을 하고, Product Name을 지정해서 생성합니다.

5. 다음과 같이 두개의 main이 생성되었습니다.

6. 편의를 위해 첫번째로 생성한 Target의 폴더 명 및 Products 이름을 first_main으로 바꿔주겠습니다.
자세한 과정은 펼치기 클릭

더보기

6-1. Xcode 프로젝트의 Target에서 algo 타겟을 더블클릭하여 바꿉니다.

6-2. 폴더 명 역시 바꾸어주고, first_main 폴더(구 algo 폴더) 안의 main.cpp의 타겟이 first_main product로 잘 선택되어있는지 확인합니다.

 6-3. 위에 있는 Run에는 여전히 algo로 떠있습니다. 이대로 실행을 할 경우에는 algo에서 first_main으로 target명만 바꾼 것이기 때문에 first_main > main.cpp를 새로 작성하고 재 컴파일을 해도 올바르게 컴파일이 됩니다. 하지만, 나중에 헷갈릴 가능성이 있기 때문에 run을 위해 사용하는 Target이름 명 역시 바꾸어 주기 위해 Run 옆에 있는 Target 선택에서 Manage Schemes를 클릭합니다.

6-4. Manage Scheme에서 실행할 Target들을 관리할 수 있습니다. 여기에서 - 를 이용하여 기존의 algo라는 이름의 scheme를 지워주고 + 를 first_main이라는 이름으로 schemes에 target을 추가해 줍니다.

7. 실행을 합니다! 이때 왼쪽 상단에서 어떤 Target으로 실행을 할지를 선택해주면,
알고리즘용으로 여러개의 main을 한개의 프로젝트에서 작동시킬 수 있습니다.

 

여기까지 Xcode로 여러개의 main.cpp 파일을 만들어야할 때 방법입니다.
알고리즘을 cpp로 풀고, git으로 한 폴더에 관리하려다 보니까 환경을 세팅하다보니까 이렇게 포스팅까지 하게되었습니다 :)
혹시 더 좋은 꿀팁이 있다면 댓글 달아주세요  감사합니다.

When solving problems on Baekjoon Online Judge or LeetCode, you often need to create and run multiple solution.cpp or main.cpp files.
I'm going to show you how to create multiple main.cpp files in a single Xcode project.

1. Create a new Xcode project.
Make sure to select Command Line Tool when creating the project.

2. Fill in the options for the new project.

3. Click on the Xcode project.

4. At the bottom of the project, you'll see a bar listing the project and targets. At the bottom of that bar, there are + and - buttons. Click the + button to
create a new Target.

Just like in steps 1–2, select Command Line Tool for the Target and specify a Product Name to create it.

5. Now you can see that two main files have been created.

6. For convenience, I'll rename the folder and Products name of the first Target to first_main.
Click the expand toggle for the detailed steps

더보기

6-1. Double-click the algo target under Targets in the Xcode project to rename it.

6-2. Rename the folder as well, then check that the main.cpp inside the first_main folder (formerly the algo folder) has its target correctly set to the first_main product.

 6-3. The Run button at the top still shows algo. If you run it as-is, it will still compile correctly since you only changed the target name from algo to first_main — even if you rewrite first_main > main.cpp and recompile. However, to avoid confusion later, let's also rename the Target used for running. Click on the Target selector next to Run and select Manage Schemes.

6-4. In Manage Schemes, you can manage the Targets available for running. Here, use the - button to remove the old scheme named algo, then use the + button to add a target to the schemes with the name first_main.

7. Run it! Just select which Target to run from the top-left corner,
and you can run multiple main files for algorithm problems within a single project.

 

And that's how you handle multiple main.cpp files in Xcode.
I ended up writing this post while setting up my environment to solve algorithm problems in C++ and manage them in a single folder with git :)
If you have any better tips, please leave a comment. Thanks!

댓글

Comments

Develop/Web

Image Styling with Web Components - 웹 컴포넌트를 사용한 이미지 스타일링 | Image Styling with Web Components

코드랩 세미나를 준비하기 위해 한글로 정리한 자료 입니다.https://codelabs.developers.google.com/codelabs/image-styling-web-components/#0 Image Styling with Web ComponentsYour Second Custom Element Let's now create a second custom element, codelab-effects. This element will render our image and possibly apply interesting visual effects to it. To start with, this is pretty much the same as the last element—with one extra ..

Image Styling with Web Components - 웹 컴포넌트를 사용한 이미지 스타일링 | Image Styling with Web Components

728x90

코드랩 세미나를 준비하기 위해 한글로 정리한 자료 입니다.

https://codelabs.developers.google.com/codelabs/image-styling-web-components/#0

 

Image Styling with Web Components

Your Second Custom Element Let's now create a second custom element, codelab-effects. This element will render our image and possibly apply interesting visual effects to it. To start with, this is pretty much the same as the last element—with one extra det

codelabs.developers.google.com

0. 소개

Web Component란?

HTML 페이지에 재사용 가능한 요소들을 작성할 수 있는 새로운 기술
새로 사용자가 정의한 이름을 갖는다 : 내가 원하는 태그들을 모아서 캡슐화 할 수 있다.

Custom Elements(codelab-dragdrop)와 shadow DOM(codelab-effects)을 사용해서 WebComponent를 만드는 과정이다. 이것들을 결합하여 페이지로 드래그되는 이미지를 조작 할 수있는 웹 사이트를 만든다.

  • Custom Elements를 선언하는 방법
  • Component에 리스너와 핸들러를 추가하는 방법
  • Custom Design을 캡슐화하기위한 Shadow Root를 만드는 방법
  • 여러 응용 프로그램을 구성하여 작은 응용 프로그램을 만드는 방법

깃허브 저장소 : https://github.com/googlecodelabs/image-styling-web-components

 

googlecodelabs/image-styling-web-components

Image Styling with Web Components. Contribute to googlecodelabs/image-styling-web-components development by creating an account on GitHub.

github.com

1. Custom Elements 만들기

1-1. 기본 HTML 틀 잡기

<!DOCTYPE html>
<html>
<head>
<script>
/* code will go here */
</script>
</head>
<body>

<h1>Image Styling with Web Components</h1>

<!-- elements will go here -->

</body>
</html>

1-2. 나의 첫번째 Custom Element 만들기

이미지를 이 페이지로 드래그앤 드롭을 하기 위한 코드를 작성해 보자.
<codelab-dragdrop></codelab-dragdrop> 태그를 생성할 예정이며, 이 태그는 파일이 드롭되는 위치를 표시하는 곳을 나타낼 것이다.

이에 대한 로직은 Javascript를 이용하여 구현할 예정이다.
1. 새로운 element를 정의
2. element를 사용(인스턴스 화)

<codelab-dragdrop></codelab-dragdrop>

1-3. Element 정의

Custom Element는 HTMLElement라는 ES6의 클래스를 상속받은 것 이다.

ES6는 ECMAScript6의 줄임말으로
ECMAScript6는 자바스크립트 표준 단체인 ECMA가 제정하는 자바스크립트 표준이다.

자바스크립트는 프로토타입 기반(prototype-based) 객체지향 언어다. 프로토타입 기반 프로그래밍은 클래스가 필요없는(class-free) 객체지향 프로그래밍 스타일로 프로토타입 체인과 클로저 등으로 객체 지향 언어의 상속, 캡슐화(정보 은닉) 등의 개념을 구현할 수 있다.

ES6의 클래스는 기존 프로토타입 기반 객체지향 프로그래밍보다 클래스 기반 언어에 익숙한 프로그래머가 보다 빠르게 학습할 수 있는 단순명료한 새로운 문법을 제시하고 있다. 그렇다고 ES6의 클래스가 기존의 프로토타입 기반 객체지향 모델을 폐지하고 새로운 객체지향 모델을 제공하는 것은 아니다. 
[출처] https://poiemaweb.com/es6-class

<script> 태그안에 Javascript 문법을 이용해서 나의 Custom Element를 정의한다.

/* code will go here */
class CodelabDragdrop extends HTMLElement {
  constructor() {
    super();
  }

  connectedCallback() {
    // we'll do stuff here later
    console.info('Element connected!');
  }
}
customElements.define('codelab-dragdrop', CodelabDragdrop);

connectedCallback() : document의 DOM에 정의한 custom element가 맨 처음 호출되었을 때 실행된다.
customElements.defind(DOMString, class, { extends: '[tag-name]' })
- DOMString : 사용자가 element에 전달하려는 이름 (즉, 태그 네임). 이때 커스텀 엘리먼트의 이름들은 dash('-')가 포함된 이름을 사용해야하므로 주의해야한다!
- class : element의 행위가 정의된 object이다.
- extends (optional) : 상속받을 태그를 지정할 수 있다. 만약 { extends: 'p'} 이렇게 지정한다면, p 태그의 inline 성질을 갖고있는 객체가 되는 듯

개발자도구( option+command+i / F12 )를 이용해서 확인해보면 connection이 완료되었다는 메세지를 확인 할 수 있다.

 

2. Drag and Drop

2-1. Target 생성하기

<!-- elements will go here -->
<codelab-dragdrop>
  <div style="width: 200px; height: 200px; background: red;">
  </div>
</codelab-dragdrop>

페이지를 새로 고침하면 큰 빨간색 상자가 나타난다. 
더 중요한 것은 페이지를 개발자 도구로 확인하면 codelab-dragdrop 내부에 빨간색 사각형을 보유하고 있기 때문에 현재 200 x 200 픽셀의 크기를 갖고있음을 알 수 있다.

2-2. Handler 추가하기

codelab-dragdrop에 파일을 끌어다 놓을 수 있도록 확장 해보자.

Web component가 가진 기능중에 하나는 캡슐화이다.
이를 수행할 수 있는 방법은 element defind 안에 코드를 추가하는 것이다.
이전에 작성한 ES6 클래스의 constructor element 자체에 리스너를 추가하여 메소드를 업데이트 할 것이다.

 constructor() {
    super();  // you always need super

    this.addEventListener('dragover', (ev) => {
      ev.preventDefault();
    });
    this.addEventListener('drop', (ev) => {
      ev.preventDefault();
      const file = ev.dataTransfer.files[0] || null;
      file && this._gotFile(file);
    });
  }

super()는 항상 필요하다. Web Element와 관련한 클래스인 HTMLElement 클래스를 상속받고,  그 기능을 온전히 사용하기 위해서.

ev.preventDefault() : 이벤트를 취소할 수 있는 경우, 이벤트의 전파를 막지않고 그 이벤트를 취소한다.
이전에 되어있던 이벤트 내역을 취소해 두는 느낌 인 것 같다
https://developer.mozilla.org/ko/docs/Web/API/Event/preventDefault

https://developer.mozilla.org/samples/domref/dispatchEvent.html

여기서 드래그 앤 드롭과 관련된 두 가지 이벤트를 처리합니다. 
여기서 중요한 것은 drop 핸들러이다. 첫 번째 파일 (있는 경우)을 드래그하여  _getFile() 이라는 메소드를 호출하게 되어있다.

2-3. Event 방출하기

이 코드랩의 목표는 Image를 조작할 수 있는 것(조작기 - manipulator)을 만드는 것이다. 따라서 우리는 이미지를 만들고, 해당하는 조작기에 이미지를 넘겨주는 것을 목적으로 한다.

이 작업을 수행할 일반 인터페이스를 제공하는 가장 좋은 방법은 HTML 자체를 이용해서 우리가 사용 가능할 수 있게 하는 것이다.
이전 단계의 drop과 같이 event를 생성해 볼 것이다. drop된 파일에서 하나의 유효한 이미지를 생성하는 것 같이 이 이벤트는 우리의 목표에 맞게 구체적으로 설정되어있다.
(추가하면 더 많은 작업을 할 수 있다 - 예 : 이미지의 크기를 먼저 조정한 다음 보낼 수 있다.)

이 코드에서 보는 것처럼 _getFile() 이라는 메소드를 작성한다. 이것은 File을 하나의 Image로 Load하며, custom한 Image로 방출한다.

  _gotFile(file) {
    const image = new Image();
    const reader = new FileReader();
    reader.onload = (event) => {
      // when the reader is ready
      image.src = event.target.result;
      image.onload = () => {
        // when the image is ready
        const params = {
          detail: image,
          bubbles: true,
        };
        const ev = new CustomEvent('image', params);
        this.dispatchEvent(ev);
      };
    };
    reader.readAsDataURL(file);
  }

reader가 준비가 된 경우, image객체의 src(경로) 속성에 drop 이벤트를 받은 타겟인 image의 결과값을 저장한다.
그렇게 해서 image가 준비가 잘 되었을 경우에 param이라는 변수를 정의하는데 이때 detail과 bubbles라는 속성을 지정하며.
우리가 image가 잘 들어왔는지 확인을 하기 위해서 CustomEvent라는 객체를 새로 생성한다.
this.dispatchEvent(ev) : 적어도 하나의 이벤트 핸들러가 해당하는 이벤트를 처리하면서 이 메소드를 호출했다면 false를 반환하고, 그렇지 않으면 true를 반환한다.

2-4. 시도하기

개발자 도구를 열고 다음을 붙여 넣는다.

document.querySelector('codelab-dragdrop').addEventListener('image',
    (ev) => console.info('got image', ev.detail));

해당하는 곳에 image가 drop 된다면 console에 해당하는 image에 대한 정보를 보여주는 것이다.
위에서 설정한 CustomEvent가 설정되는 것.

 

3. Connecting Element

3-1. 나의 두번째 Custom Element 만들기

codelab-effects라는 두번째 Custom Element를 만들어 보자. 
이 요소는 이미지를 렌더링하고 흥미로운 시각적 효과를 적용 할 수 있다.

class CodelabEffects extends HTMLElement {
  constructor() {
    super();
    this.root = this.attachShadow({mode: 'open'});
  }
}
customElements.define('codelab-effects', CodelabEffects);

3-2. Shadow Root 생성하기

Shadow DOM을 사용하면 실제로는 페이지에 없는 요소인 custom HTML을 추가하는 것을 허용해준다.
이때 Shadow DOM을 사용하기 위한 method가 attachShadow()인 것이다.

attachShadow()의 모드에 따라서 개발자 도구에서 해당 element의 내부에 있는 html 코드를 볼 수 있는지 없는지 여부를 판단할 수 있다.

실제 개발자 도구에서는 볼 수 없는 Element 이며, 이 것은 일반적으로 document.querySelector() 또는 getElementById()를 이용해서 호출을 할 수 있다.

모든 Custom Element에 Shadow Root가 필요한 것은 아니다.
실제로 <codelab-dragdrop> element는 새롭게 하나를 생성하지 않고도 drop된 파일을 조작하는 복잡한 로직을 수행한다. 그러나 이것은 정말 강력한 API이다.

Shadow DOM 내부의 HTML을 몇개의 코드를 추가해서 템플릿을 정의할 수 있다.

    this.root = this.attachShadow({mode: 'open'});
    this.root.innerHTML = `
<style>
:host {
    background: #fff;
    border: 1px solid black;
    display: inline-block;
}
</style>
<canvas id="canvas" width="512" height="512"></canvas>
<table>
  <tr>
    <td>AMOUNT</td>
    <td><input id="amount" type="range" min="3" max="40" value="10"></td>
  </tr>
</table>
`;

 

마지막으로 이 element를 codelab-dragdrop element 안에 넣는다. 
이때 이전에 있던 빨간색 상자는 제거한다. 
이제 codelab-effect element가 target image를 제공하는 데 도움이 된다.

<!-- elements will go here -->
<codelab-dragdrop>
  <codelab-effects></codelab-effects>
</codelab-dragdrop>

3-3. Putting It Together

이전 단계에 개발자 도구를 이용해서 event를 확인하려고 넣었던 스크립트를 기억하는가?
이 스크립트를 이용해서 이벤트를 연결해 보자!

<!-- elements will go here -->
<codelab-dragdrop id="dragdrop">
  <codelab-effects id="effects"></codelab-effects>
</codelab-dragdrop>
<script>
dragdrop.addEventListener('image', (ev) => {
  effects.image = ev.detail;  // set the image that we got in dragdrop
});
</script>

이제 image 이벤트가 발생하면(즉 image를 drop 했다는 이벤트가 발생하면) codelab-effects 요소에 있는 image 속성을 설정하도록 코드가 장성되어있다. 이제 이렇게 제공한 이미지의 픽셀 데이터를 가져오는 것을 코드에 추가해 보자.

 constructor() {
    super();
    this.root = this.attachShadow({mode: 'open'});
    // Leave the root.innerHTML part alone
  }

  // Add this method
  set image(image) {
    const canvas = this.root.getElementById('canvas');

    // resize image to something reasonable
    canvas.width = Math.min(1024, Math.max(256, image.width));
    canvas.height = (image.height * (canvas.width / image.width));

    // clone buffer to get one of same size
    const buf = canvas.cloneNode(true);
    const ctx = buf.getContext('2d');
    ctx.drawImage(image, 0, 0, buf.width, buf.height);
    this.data = ctx.getImageData(0, 0, buf.width, buf.height).data;
    console.info(this.data);
  }

setter는 클래스 필드에 값을 할당할 때마다 클래스 필드의 값을 조작하는 행위가 필요할 때 사용한다. setter는 메소드 이름 앞에 
set 키워드를 사용해 정의한다. 이때 메소드 이름은 클래스 필드 이름처럼 사용된다.
다시 말해 setter는 호출하는 것이 아니라 프로퍼티처럼 값을 할당하는 형식으로 사용하며 할당 시에 메소드가 호출된다.

이제 이 곳에 이미지를 Drag and Drop 하면 해당하는 이미지의 픽셀 데이터를 console에서 확인 할 수 있다.

3-4. 기본 스타일링

console.log()를 이용해서 데이터 숫자값만 보기 보다는 데이터를 가져와서 실제 캔버스로 그리는 작업을 해보자.
set image 메서드 내부에서 만든 이미지 데이터를 보고 캔버스에 그린다.
이 코드랩은 캔버스 사용 및 이미지 데이터 작업에 관한 것이 아니라 웹 구성 요소를 시연하는데 도움이 되며 흥미로운 효과를 기대할 수 있다.

    // Replace console.info with:
    this.draw();
  }

  // And add this method
  draw() {
    const canvas = this.root.getElementById('canvas');
    canvas.width = canvas.width;  // clear canvas
    const context = canvas.getContext('2d');

    const amount = +this.root.getElementById('amount').value;
    const size = amount * .8;

    for (let y = amount; y < canvas.height; y += amount * 2) {
      for (let x = amount; x < canvas.width; x += amount * 2) {
        const index = ((y * canvas.width) + x) * 4;
        const [r,g,b] = this.data.slice(index, index+3);
        const color = `rgb(${r},${g},${b})`;

        context.beginPath();
        context.arc(x, y, size, 0, 360, false);
        context.fillStyle = color;
        context.fill();
      }
    }
  }

페이지를 새로 고침하고 좋아하는 이미지를 페이지로 드래그하면 점묘 효과가 나타난다.

4. Saving Images

4-1. Click To Download

방금 만든 점묘화의 이미지를 공유하거나 사용하기 위해서는 마우스 오른쪽 버튼을 클릭해서 이미지를 다운로드 해야한다.
대신 canvas 아래에 링크를 추가하여 이미지를 자동으로 다운로드를 할 수 있도록 환경을 만들어 볼 예정이다.

    this.root.innerHTML = `
...
<canvas id="canvas" width="512" height="512"></canvas>
<br /><a href="#" id="link">Download</a>
...
`;

그리고 이 link라는 id값을 받아서 download 할 수 있도록 이벤트 핸들러를 설정한다.

    // And add this handler
    const link = this.root.getElementById('link');
    link.addEventListener('click', (ev) => {
      link.href = this.root.getElementById('canvas').toDataURL();
      link.download = 'pointify.png';
    });

다운로드 완료!!

 

5. Control 추가

5-1. 응답하기

"AMOUNT" 슬라이더를 활용해보자! 이 것을 활용해서 우리가 그리는 점묘화의 점의 크기를 제어할 수 있다. 그러나 현재는 이미지 자체가 드롭될 때 한번만 발생하기 때문에 코드를 수정해보자

CodeLabEffects 클래스의 생성자 안에 리스너를 추가해 보자.
다시 리마인드 하면 이것은 this.root는 AMOUNT 슬라이더를 포함한 모든 Shadow DOM이 있는 곳이다.
이것은 Shadow DOM element에 의해 생긴 모든 변경에 응답하고 draw 메소드를 호출한다.

...
      link.download = 'pointify.png';
    });

    //add these two new listeners
    this.root.addEventListener('input', (ev) => this.draw());
    this.root.addEventListener('change', (ev) => this.draw());

  }

input이나 change와 관련한 이벤트가 들어왔을 경우에 draw()를 다시 실행한다.

5-2. 고급 컨트롤

shadow DOM에 컨트롤을 추가한다.

    this.root.innerHTML = `
... <!-- add some new <tr>'s at the bottom -->
  <tr>
    <td>SIZE</td>
    <td><input id="size" type="range" min="0" max="4" step="0.01" value="1"></td>
  </tr>
  <tr>
    <td>OPACITY</td>
    <td><input id="opacity" type="range" min="0" max="1" step="0.01" value="1"></td>
  </tr>
  <tr>
    <td>ATTENUATION</td>
    <td><input id="attenuation" type="checkbox"></td>
  </tr>

</table>
`;

렌더링 코드인 draw() 역시 컨트롤에 따라 조금 수정해준다.

draw() {
    const canvas = this.root.getElementById('canvas');
    canvas.width = canvas.width;  // clear canvas
    const context = canvas.getContext('2d');

    const attenuation = this.root.getElementById('attenuation').checked;
    const amount = +this.root.getElementById('amount').value;
    const size = this.root.getElementById('size').value * amount;
    const opacity = this.root.getElementById('opacity').value;

    for (let y = amount; y < canvas.height; y += amount * 2) {
      for (let x = amount; x < canvas.width; x += amount * 2) {
        const index = ((y * canvas.width) + x) * 4;
        const [r,g,b] = this.data.slice(index, index+3);
        const color = `rgba(${r},${g},${b},${opacity})`;

        const weight = 1 - ( this.data[ index ] / 255 );
        const radius = (attenuation ? size * weight : size);

        context.beginPath();
        context.arc(x, y, radius, 0, 360, false);
        context.fillStyle = color;
        context.fill();
      }
    }
  }

size : 원의 기본 반경을 제어한다
opacity : 원의 투명도를 제어한다.
attenuation : 각 원의 어두운 정도에 따라 원의 크기를 조정한다.

5-3. 추가 기능

이미지 전체를 색조로 만드는 컬러 필터
다른 모양을 사용
정렬되지 않은 배치 등

이 component element 에는 많은 가능성이 있다!

Polymer와 같은 다양한 Web Component Element 라이브러리도 있다.
이 라이브러리에는 지금 렌더링 수준의 그림 하나하나 생각했던 것과 같은 Low Level의 Component Element보다 좀더 High Level 계층의 추상화된 라이브러리를 제공한다.

This is a summary I put together in Korean to prepare for a codelab seminar.

https://codelabs.developers.google.com/codelabs/image-styling-web-components/#0

 

Image Styling with Web Components

Your Second Custom Element Let's now create a second custom element, codelab-effects. This element will render our image and possibly apply interesting visual effects to it. To start with, this is pretty much the same as the last element—with one extra det

codelabs.developers.google.com

0. Introduction

What is a Web Component?

A new technology that lets you create reusable elements for HTML pages.
They have custom user-defined names: you can bundle the tags you want and encapsulate them.

This is the process of creating a WebComponent using Custom Elements (codelab-dragdrop) and shadow DOM (codelab-effects). By combining these, we'll build a website that can manipulate images dragged onto the page.

  • How to declare Custom Elements
  • How to add listeners and handlers to a Component
  • How to create a Shadow Root to encapsulate Custom Design
  • How to compose multiple components to build a small application

GitHub repository: https://github.com/googlecodelabs/image-styling-web-components

 

googlecodelabs/image-styling-web-components

Image Styling with Web Components. Contribute to googlecodelabs/image-styling-web-components development by creating an account on GitHub.

github.com

1. Creating Custom Elements

1-1. Setting Up the Basic HTML Structure

<!DOCTYPE html>
<html>
<head>
<script>
/* code will go here */
</script>
</head>
<body>

<h1>Image Styling with Web Components</h1>

<!-- elements will go here -->

</body>
</html>

1-2. Creating My First Custom Element

Let's write the code for dragging and dropping an image onto this page.
<codelab-dragdrop></codelab-dragdrop> — we're going to create this tag, and it will indicate the area where files can be dropped.

The logic for this will be implemented using Javascript.
1. Define a new element
2. Use the element (instantiate it)

<codelab-dragdrop></codelab-dragdrop>

1-3. Defining the Element

A Custom Element is an ES6 class that extends HTMLElement.

ES6 stands for ECMAScript 6.
ECMAScript 6 is a JavaScript standard established by ECMA, the JavaScript standards body.

JavaScript is a prototype-based object-oriented language. Prototype-based programming is a class-free object-oriented programming style that can implement concepts like inheritance and encapsulation (information hiding) through prototype chains and closures.

ES6 classes provide a cleaner, simpler syntax that makes it easier for programmers familiar with class-based languages to learn quickly, compared to the traditional prototype-based object-oriented programming. That said, ES6 classes don't replace the existing prototype-based object-oriented model with a new one. 
[Source] https://poiemaweb.com/es6-class

We define our Custom Element using Javascript syntax inside the <script> tag.

/* code will go here */
class CodelabDragdrop extends HTMLElement {
  constructor() {
    super();
  }

  connectedCallback() {
    // we'll do stuff here later
    console.info('Element connected!');
  }
}
customElements.define('codelab-dragdrop', CodelabDragdrop);

connectedCallback(): This is called when the custom element is first inserted into the document's DOM.
customElements.define(DOMString, class, { extends: '[tag-name]' })
- DOMString: The name you want to give the element (i.e., the tag name). Note that custom element names must include a dash ('-'), so keep that in mind!
- class: An object that defines the element's behavior.
- extends (optional): You can specify a tag to inherit from. For example, if you set { extends: 'p'}, the resulting object seems to take on the inline properties of a p tag.

If you check using the developer tools (option+command+i / F12), you can confirm the connection completed message.

 

2. Drag and Drop

2-1. Creating the Target

<!-- elements will go here -->
<codelab-dragdrop>
  <div style="width: 200px; height: 200px; background: red;">
  </div>
</codelab-dragdrop>

When you refresh the page, a big red box appears. 
More importantly, if you inspect the page with developer tools, you can see that the red square is contained inside codelab-dragdrop, so it currently has a size of 200 x 200 pixels.

2-2. Adding Handlers

Let's extend codelab-dragdrop so that files can be dragged and dropped onto it.

One of the features of Web Components is encapsulation.
The way to achieve this is by adding code inside the element definition.
We'll update the constructor of the ES6 class we wrote earlier by adding listeners to the element itself.

 constructor() {
    super();  // you always need super

    this.addEventListener('dragover', (ev) => {
      ev.preventDefault();
    });
    this.addEventListener('drop', (ev) => {
      ev.preventDefault();
      const file = ev.dataTransfer.files[0] || null;
      file && this._gotFile(file);
    });
  }

super() is always required — to inherit from HTMLElement, the class related to Web Elements, and to fully use its features.

ev.preventDefault(): If the event is cancelable, it cancels the event without stopping its propagation.
It feels like it clears out any previously set event behavior.
https://developer.mozilla.org/ko/docs/Web/API/Event/preventDefault

https://developer.mozilla.org/samples/domref/dispatchEvent.html

Here we handle two events related to drag and drop. 
The important one here is the drop handler. It takes the first file (if there is one) from the drag and  calls a method called _getFile().

2-3. Emitting Events

The goal of this codelab is to build something that can manipulate images (a manipulator). So our objective is to create an image and pass it to the corresponding manipulator.

The best way to provide a general interface for this is to make it available to us through HTML itself.
Just like the drop event from the previous step, we're going to create an event. Like generating a single valid image from a dropped file, this event is specifically tailored to our goal.
(You can do more if you add to it — for example, you could resize the image first before sending it.)

As you can see in this code, we write a method called _getFile(). It loads a File as an Image and emits it as a custom Image event.

  _gotFile(file) {
    const image = new Image();
    const reader = new FileReader();
    reader.onload = (event) => {
      // when the reader is ready
      image.src = event.target.result;
      image.onload = () => {
        // when the image is ready
        const params = {
          detail: image,
          bubbles: true,
        };
        const ev = new CustomEvent('image', params);
        this.dispatchEvent(ev);
      };
    };
    reader.readAsDataURL(file);
  }

When the reader is ready, the result of the drop event target image is stored in the image object's src (path) property.
Once the image is successfully loaded, we define a variable called params with detail and bubbles properties.
To verify that the image was received correctly, we create a new CustomEvent object.
this.dispatchEvent(ev): Returns false if at least one event handler that handled the event called this method, and true otherwise.

2-4. Trying It Out

Open the developer tools and paste the following:

document.querySelector('codelab-dragdrop').addEventListener('image',
    (ev) => console.info('got image', ev.detail));

If an image is dropped onto the designated area, it shows the image information in the console.
This is where the CustomEvent we set up earlier kicks in.

 

3. Connecting Element

3-1. Creating My Second Custom Element

Let's create a second Custom Element called codelab-effects. 
This element will render the image and can apply interesting visual effects to it.

class CodelabEffects extends HTMLElement {
  constructor() {
    super();
    this.root = this.attachShadow({mode: 'open'});
  }
}
customElements.define('codelab-effects', CodelabEffects);

3-2. Creating a Shadow Root

Shadow DOM allows you to add custom HTML that isn't actually part of the page's main DOM.
The method used to enable Shadow DOM is attachShadow().

Depending on the mode of attachShadow(), you can control whether the HTML code inside the element is visible in the developer tools or not.

It's an element that isn't visible in the actual developer tools, and it can typically be accessed using document.querySelector() or getElementById().

Not every Custom Element needs a Shadow Root.
In fact, the <codelab-dragdrop> element performs complex logic for manipulating dropped files without creating a new one. But it's a really powerful API.

You can define a template by adding a few lines of code for the HTML inside the Shadow DOM.

    this.root = this.attachShadow({mode: 'open'});
    this.root.innerHTML = `
<style>
:host {
    background: #fff;
    border: 1px solid black;
    display: inline-block;
}
</style>
<canvas id="canvas" width="512" height="512"></canvas>
<table>
  <tr>
    <td>AMOUNT</td>
    <td><input id="amount" type="range" min="3" max="40" value="10"></td>
  </tr>
</table>
`;

 

Finally, we place this element inside the codelab-dragdrop element. 
Remove the red box from before. 
Now the codelab-effects element helps provide the target image.

<!-- elements will go here -->
<codelab-dragdrop>
  <codelab-effects></codelab-effects>
</codelab-dragdrop>

3-3. Putting It Together

Remember the script we pasted in the developer tools to check the event in the previous step?
Let's use this script to connect the events!

<!-- elements will go here -->
<codelab-dragdrop id="dragdrop">
  <codelab-effects id="effects"></codelab-effects>
</codelab-dragdrop>
<script>
dragdrop.addEventListener('image', (ev) => {
  effects.image = ev.detail;  // set the image that we got in dragdrop
});
</script>

Now the code is set up so that when an image event fires (i.e., when an image is dropped), it sets the image property on the codelab-effects element. Let's now add code to grab the pixel data from the provided image.

 constructor() {
    super();
    this.root = this.attachShadow({mode: 'open'});
    // Leave the root.innerHTML part alone
  }

  // Add this method
  set image(image) {
    const canvas = this.root.getElementById('canvas');

    // resize image to something reasonable
    canvas.width = Math.min(1024, Math.max(256, image.width));
    canvas.height = (image.height * (canvas.width / image.width));

    // clone buffer to get one of same size
    const buf = canvas.cloneNode(true);
    const ctx = buf.getContext('2d');
    ctx.drawImage(image, 0, 0, buf.width, buf.height);
    this.data = ctx.getImageData(0, 0, buf.width, buf.height).data;
    console.info(this.data);
  }

A setter is used when you need to manipulate the value of a class field every time a value is assigned to it. A setter is defined by placing the 
set keyword before the method name. The method name is then used as if it were a class field name.
In other words, a setter isn't called like a regular method — it's used in the format of assigning a value like a property, and the method is invoked upon assignment.

Now if you drag and drop an image here, you can see the pixel data of that image in the console.

3-4. Basic Styling

Rather than just looking at data numbers via console.log(), let's actually grab the data and draw it on the canvas.
We take the image data created inside the set image method and draw it on the canvas.
This codelab isn't about working with canvas or image data — it's about demonstrating Web Components, and you can look forward to some interesting effects.

    // Replace console.info with:
    this.draw();
  }

  // And add this method
  draw() {
    const canvas = this.root.getElementById('canvas');
    canvas.width = canvas.width;  // clear canvas
    const context = canvas.getContext('2d');

    const amount = +this.root.getElementById('amount').value;
    const size = amount * .8;

    for (let y = amount; y < canvas.height; y += amount * 2) {
      for (let x = amount; x < canvas.width; x += amount * 2) {
        const index = ((y * canvas.width) + x) * 4;
        const [r,g,b] = this.data.slice(index, index+3);
        const color = `rgb(${r},${g},${b})`;

        context.beginPath();
        context.arc(x, y, size, 0, 360, false);
        context.fillStyle = color;
        context.fill();
      }
    }
  }

Refresh the page and drag your favorite image onto it — you'll see a pointillism effect appear.

4. Saving Images

4-1. Click To Download

To share or use the pointillism image we just created, you'd have to right-click and download the image.
Instead, we're going to add a link below the canvas so that the image can be downloaded automatically.

    this.root.innerHTML = `
...
<canvas id="canvas" width="512" height="512"></canvas>
<br /><a href="#" id="link">Download</a>
...
`;

Then we set up an event handler using the link id to enable the download.

    // And add this handler
    const link = this.root.getElementById('link');
    link.addEventListener('click', (ev) => {
      link.href = this.root.getElementById('canvas').toDataURL();
      link.download = 'pointify.png';
    });

Download complete!!

 

5. Adding Controls

5-1. Responding to Input

Let's make use of the "AMOUNT" slider! We can use it to control the size of the dots in our pointillism image. But right now, the drawing only happens once when the image is dropped, so let's fix the code.

Let's add a listener inside the constructor of the CodelabEffects class.
As a reminder, this.root is where all the Shadow DOM lives, including the AMOUNT slider.
This will respond to any changes made by Shadow DOM elements and call the draw method.

...
      link.download = 'pointify.png';
    });

    //add these two new listeners
    this.root.addEventListener('input', (ev) => this.draw());
    this.root.addEventListener('change', (ev) => this.draw());

  }

When an input or change event comes in, it re-executes draw().

5-2. Advanced Controls

Let's add controls to the shadow DOM.

    this.root.innerHTML = `
... <!-- add some new <tr>'s at the bottom -->
  <tr>
    <td>SIZE</td>
    <td><input id="size" type="range" min="0" max="4" step="0.01" value="1"></td>
  </tr>
  <tr>
    <td>OPACITY</td>
    <td><input id="opacity" type="range" min="0" max="1" step="0.01" value="1"></td>
  </tr>
  <tr>
    <td>ATTENUATION</td>
    <td><input id="attenuation" type="checkbox"></td>
  </tr>

</table>
`;

The rendering code, draw(), also needs a slight update to accommodate the controls.

draw() {
    const canvas = this.root.getElementById('canvas');
    canvas.width = canvas.width;  // clear canvas
    const context = canvas.getContext('2d');

    const attenuation = this.root.getElementById('attenuation').checked;
    const amount = +this.root.getElementById('amount').value;
    const size = this.root.getElementById('size').value * amount;
    const opacity = this.root.getElementById('opacity').value;

    for (let y = amount; y < canvas.height; y += amount * 2) {
      for (let x = amount; x < canvas.width; x += amount * 2) {
        const index = ((y * canvas.width) + x) * 4;
        const [r,g,b] = this.data.slice(index, index+3);
        const color = `rgba(${r},${g},${b},${opacity})`;

        const weight = 1 - ( this.data[ index ] / 255 );
        const radius = (attenuation ? size * weight : size);

        context.beginPath();
        context.arc(x, y, radius, 0, 360, false);
        context.fillStyle = color;
        context.fill();
      }
    }
  }

size: Controls the base radius of the circles.
opacity: Controls the transparency of the circles.
attenuation: Adjusts the size of each circle based on how dark it is.

5-3. Additional Features

A color filter that tints the entire image
Using different shapes
Randomized placement, etc.

There are so many possibilities with this component element!

There are also various Web Component element libraries like Polymer.
These libraries provide higher-level abstractions rather than the low-level component elements we were working with here, where we had to think about each individual rendering detail.

'Develop > Web' 카테고리의 다른 글

Thrift 뽀개기 | Cracking Thrift  (0) 2023.02.23
web & server - DSC Ewha 세션 | web & server - DSC Ewha Session  (0) 2019.10.15

댓글

Comments

Blog

Mac 적응기 - 커맨드 편 | Mac Adaptation Journey - Command Edition

Mac Pro를 드디어 샀습니다!! 근데, 윈도우랑 너무 다르다 보니까 아무래도 적응하는데 시간이 걸리더군요! 그래서 각종 커맨드 부터 제가 사용하는 tool 커맨드까지 모두 정리하려 합니다Mac Command키보드 키는 기호랑 연결지어서 알면 좋을 것 같습니다 :)command ⌘shift ⇧option ⌥control ⌃윈도우랑 매칭 가능윈도우의 control이 mac의 command와 매칭이 되는 것 같아요! 기본적인 커맨드 입니다.복사 : ⌘ + c붙여넣기 : ⌘ + v잘라내기 : ⌘ + x되돌리기 : ⌘ + z전체선택 : ⌘ + a저장 : ⌘ + s찾기 : ⌘ + f윈도우와 매칭이 어려운 커맨드애플리케이션 닫기 : ⌘ + q탭닫기 : ⌘ + w 파일 삭제 : ⌘ + delete파일 들어가기 &..

Mac 적응기 - 커맨드 편 | Mac Adaptation Journey - Command Edition

728x90

Mac Pro를 드디어 샀습니다!! 근데, 윈도우랑 너무 다르다 보니까 아무래도 적응하는데 시간이 걸리더군요! 
그래서 각종 커맨드 부터 제가 사용하는 tool 커맨드까지 모두 정리하려 합니다

Mac Command

키보드 키는 기호랑 연결지어서 알면 좋을 것 같습니다 :)

command ⌘
shift ⇧
option ⌥
control ⌃

윈도우랑 매칭 가능

윈도우의 control이 mac의 command와 매칭이 되는 것 같아요! 기본적인 커맨드 입니다.

복사 : + c
붙여넣기  :  + v
잘라내기 :  + x
되돌리기 :  + z
전체선택 :  + a
저장 :  + s
찾기 :  + f

윈도우와 매칭이 어려운 커맨드

애플리케이션 닫기 :  + q
탭닫기 :  + w
파일 삭제 : ⌘ + delete
파일 들어가기 & 하위 폴더로 들어가기 : ⌘ + ↓
상위 폴더로 나가기 : ⌘ + ↑

내 HD내 모든 파일 찾기 : ⌘ + space

전체 캡쳐 : + shift+ 3 
부분 캡쳐 : + shift + 4
캡쳐 선택 : + shift + 5

페이지 뒤로가기 : ⌘ + [
페이지 앞으로가기 : ⌘ + ]

창 숨기기 :  + h
창 이동 : ⌃ + 화살표 , 손가락 3개쓸기, ⌘ + tab

텍스트 편집시 유용

한 줄 맨앞 맨뒤 이동 : + 화살표
한 단어 맨앞 맨뒤 이동 : + 화살표
텍스트 선택 : shift + 화살표   // 응용 : shift +  + 화살표 , shift +  + 화살표
이모티콘 및 특수문자 입력 : ⌃ + ⌘ + space

Shell 명령어

shell에서 finder열기 : open .


Intellij Mac Command

preference : ⌘ + ,
전체 파일 검색 : ⌘ + shift + f
action 검색 : ⌘ + shift + a
연결한 server의 task name 검색 : + shift + n

이전에 작업한 커서 위치에서 보기 :  ⌘ + [
이후에 작업한 커서 위치에서 보기 :  ⌘ + ]

이전 탭으로 이동하기 :  ⌘ + shift + [
이후 탭으로 이동하기 :  ⌘ + shift + ]

줄 자동 정렬 : ⌥ + ⌘ + l

I finally bought a Mac Pro!! But since it's so different from Windows, it definitely took some time to get used to! 
So I'm going to organize everything from basic commands to the tool commands I personally use.

Mac Command

It's helpful to associate the keyboard keys with their symbols :)

command ⌘
shift ⇧
option ⌥
control ⌃

Matching with Windows

It seems like Windows' control matches up with Mac's command! These are the basic commands.

Copy : + c
Paste  :  + v
Cut :  + x
Undo :  + z
Select All :  + a
Save :  + s
Find :  + f

Commands Hard to Match with Windows

Quit Application :  + q
Close Tab :  + w
Delete File : ⌘ + delete
Open File & Enter Subfolder : ⌘ + ↓
Go to Parent Folder : ⌘ + ↑

Search All Files on HD : ⌘ + space

Full Screen Capture : + shift+ 3 
Partial Capture : + shift + 4
Capture Selection : + shift + 5

Page Back : ⌘ + [
Page Forward : ⌘ + ]

Hide Window :  + h
Switch Windows : ⌃ + Arrow Keys, Three-Finger Swipe, ⌘ + tab

Useful for Text Editing

Jump to Beginning/End of Line : + Arrow Keys
Jump to Beginning/End of Word : + Arrow Keys
Select Text : shift + Arrow Keys   // Tip : shift +  + Arrow Keys , shift +  + Arrow Keys
Emoji & Special Character Input : ⌃ + ⌘ + space

Shell Commands

Open Finder from Shell : open .


Intellij Mac Command

Preferences : ⌘ + ,
Search All Files : ⌘ + shift + f
Search Actions : ⌘ + shift + a
Search Connected Server Task Name : + shift + n

Navigate to Previous Cursor Position :  ⌘ + [
Navigate to Next Cursor Position :  ⌘ + ]

Move to Previous Tab :  ⌘ + shift + [
Move to Next Tab :  ⌘ + shift + ]

Auto-Format Line : ⌥ + ⌘ + l

댓글

Comments

Blog

티스토리 이미지 업로드 오류 해결법 | How to Fix Tistory Image Upload Errors

티스토리 웹 에디터로 블로깅을 하다보면 ctrl+c ctrl+v를 이용해서 이미지를 업로드 해야하는 경우가 많습니다.근데 이때 생기는 치명적인 오류가 있는데요.구글링으로 얻은 이미지를 ctrl+c 해서 tistory에 ctrl+v를 할 때 간혹붙여넣기 및 이미지 업로드 중입니다이 글이 뜬 창 상태에서 멈추는 경우가 있어요ㅠㅠㅠ 이럴경우 새로 고침을 하면 그동안 쓴 글도 임시저장이 안되있는 상황이라서 날아가면 맘이 찢어집니다이럴때 야매로 안에 있는 글이라도 복사할 수 있게 해결하는 방법을 포스팅 하려합니다.이 상태에서 멈추었을 때 Ctrl + S 를 이용해서 HTML 파일로 저장합니다.저장된 HTML 파일을 여는 동시에 Ctrl+A Ctrl+C 를 이용해서 전체 내용을 복사합니다.이때 이 html 파일을..

티스토리 이미지 업로드 오류 해결법 | How to Fix Tistory Image Upload Errors

728x90

티스토리 웹 에디터로 블로깅을 하다보면 ctrl+c ctrl+v를 이용해서 이미지를 업로드 해야하는 경우가 많습니다.

근데 이때 생기는 치명적인 오류가 있는데요.

구글링으로 얻은 이미지를 ctrl+c 해서 tistory에 ctrl+v를 할 때 간혹

붙여넣기 및 이미지 업로드 중입니다

이 글이 뜬 창 상태에서 멈추는 경우가 있어요ㅠㅠㅠ 

이럴경우 새로 고침을 하면 그동안 쓴 글도 임시저장이 안되있는 상황이라서 날아가면 맘이 찢어집니다

이럴때 야매로 안에 있는 글이라도 복사할 수 있게 해결하는 방법을 포스팅 하려합니다.


이 상태에서 멈추었을 때  Ctrl + S 를 이용해서 HTML 파일로 저장합니다.

저장된 HTML 파일을 여는 동시에 Ctrl+A Ctrl+C 를 이용해서 전체 내용을 복사합니다.
이때 이 html 파일을 블러올 때 역시 일정 시간 (요청을 처리하는 시간)이 지나면 위에와 같은 "붙여넣기 및 이미지 업로드 중입니다" 창이 뜨게 되니 빠르게 Ctrl+A Ctrl+C를 해줍니다.

이후 복사한 내용을 새 Tistory 창을 열어서 복붙을 하면 내용만 가져올 수 있습니다 :)

 

긴 글을 쓰다가 저 창이 떠서 전부 날린적이 있는데 어떻게든 복구하고 싶어서 이것저것 해보다가 찾아낸 방법입니다ㅎㅎ 다들 꼭 임시저장을 활성화 하시길ㅠㅠ

+ 추가로 이 글을 해보면서 실험을 해보니
아이폰에서 카카오톡으로 이미지를 보냈는데 카카오톡에서 그 이미지를 바로 Ctrl+C 한 후 Tistory에서 Ctrl+V 하는 경우에 저런 "붙여넣기 및 이미지 업로드 중입니다" 이게 뜨는 것 같습니다!

아이폰에서 찍은 이미지는 확장자가 .HEIC인데, 이 파일을 그대로 Ctrl+C Ctrl+V하는 경우 에러가 뜨는 것으로 추측이 됩니다! (12/30 추가)

When you're blogging with the Tistory web editor, there are many cases where you need to upload images using ctrl+c ctrl+v.

But there's a critical bug that happens during this process.

When you ctrl+c an image you found on Google and ctrl+v it into Tistory, sometimes

Pasting and uploading image

It gets stuck on this popup and freezes 😭😭😭 

If you refresh the page in this situation, everything you've written isn't auto-saved, so losing it all is absolutely heartbreaking.

So I'm going to share a workaround to at least copy the text that's still inside the editor.


When it's frozen in this state, use Ctrl + S to save the page as an HTML file.

Open the saved HTML file and immediately use Ctrl+A Ctrl+C to copy all the content.
Note that when you open this HTML file, after a certain amount of time (the time it takes to process the request), the same "Pasting and uploading image" popup will appear again, so make sure to Ctrl+A Ctrl+C quickly.

Then open a new Tistory editor window and paste the copied content — you'll be able to recover just the text :)

 

I was writing a long post when that popup appeared and I lost everything — I was so desperate to recover it that I tried all sorts of things and discovered this method haha. Please make sure to enable auto-save, everyone 😭😭

+ Also, while experimenting with this, I found something:
When you send an image from an iPhone via KakaoTalk and then directly Ctrl+C the image from KakaoTalk and Ctrl+V it into Tistory, that seems to be when the "Pasting and uploading image" popup appears!

Images taken on iPhones have a .HEIC extension, and I suspect the error occurs when you try to Ctrl+C Ctrl+V that file as-is! (Added 12/30)

댓글

Comments

Develop/Springboot

springboot Junit5 + assertJ TestCode | springboot Junit5 + assertJ TestCode

0. build.gradletest { useJUnitPlatform()}dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' testCompile("org.assertj:assertj-core:3.11.1")}1. assertAllUser user = new User();assertAll( () -> asssertThat(user.getId()).isEqualTo(1L), //1 () -> asssertThat(user.getName()).isEqualTo("jyami"), //2 () -> asssertThat(user.getEmail()).isEqualTo(..

springboot Junit5 + assertJ TestCode | springboot Junit5 + assertJ TestCode

728x90

0. build.gradle

test {
    useJUnitPlatform()
}

dependencies {
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testCompile("org.assertj:assertj-core:3.11.1")
}

1. assertAll

User user = new User();
assertAll(
    () -> asssertThat(user.getId()).isEqualTo(1L),    //1
    () -> asssertThat(user.getName()).isEqualTo("jyami"),    //2
    () -> asssertThat(user.getEmail()).isEqualTo("mor222293@gmail.com")    //3
);

이전의 Junit4에서는
assertEquals을 검증할 때, 위에부터 하나씩 실행하는데, 위에서 실패하면 아래에있는 assertEquals를 실행하지 않는다.즉, 주석의 1번의 assertEquals에서 실패했으면 2, 3번의 assertEquals는 실행하지 않는다.
그러나 assertAll을 사용하면, 1번에서 실패했어도 2번 3번도 실행한다.

2. @DisplayName

@DisplayName("유저 테스트")
public class UserTest {

    @DisplayName("유저의 이름을 테스트 해보자!")
    @Test
    void someTest() {
        User user = new User();
        assertThat(user.getName()).isEqualTo("jyami");
    }

이렇게 할 경우에는, DisplayName을 이용해서 test의 목적을 명확히 명시할 수 있다.

3. assertThrows

@Test
void checkThrow() {
	Assertions.assertThrows(
		Exception.class, () -> {int a = 10/0;}
	);
}

익셉션을 처리할 때 junit5의 assertThrow 안에 throw 체크를 하려고하는 로직을 담으면 된다.

 


AssertJ

1. contains()

@Test
void containsTest() {
	List<Integer> integers = Arrays.asList(1, 2, 3);
	assertThat(integers).contains(1, 2, 3);	//테스트 통과
	assertThat(integers).contains(2, 1, 3);	//테스트 통과
}

contains는 순서와 상관 없이 실제 그룹이 주어진 값들을 포함하고 있는지를 테스트한다.
그래서 위 두 줄의 테스트는 모두 통과한다.

2. containsExactly()

@Test
void containsExactlyTest() {
	List<Integer> integers = Arrays.asList(1, 2, 3);
	assertThat(integers).containsExactly(1, 2, 3);	//테스트 통과
	assertThat(integers).containsExactly(2, 1, 3);	//테스트 통과 X
	assertThat(integers).containsExactly(1, 2);	//테스트 통과 X
}

contains는 순서까지 고려해서 실제 그룹이 주어진 값들을 포함하고 있는지를 테스트한다
그래서 첫번째 줄의 테스트는 통과하지만, 두번째 줄의 테스트는 통과하지 못한다.

이때 주의할 점은 원소 하나라도 빠지면 테스트를 통과하지 못한다. 정말로 정확하게 일치하는 list여야 하는 것!

 


업데이트 예정인 게시글 입니다.

0. build.gradle

test {
    useJUnitPlatform()
}

dependencies {
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testCompile("org.assertj:assertj-core:3.11.1")
}

1. assertAll

User user = new User();
assertAll(
    () -> asssertThat(user.getId()).isEqualTo(1L),    //1
    () -> asssertThat(user.getName()).isEqualTo("jyami"),    //2
    () -> asssertThat(user.getEmail()).isEqualTo("mor222293@gmail.com")    //3
);

In the previous JUnit4,
when verifying with assertEquals, it executes them one by one from the top, and if one fails, it doesn't execute the ones below it. In other words, if assertEquals #1 in the comments fails, assertEquals #2 and #3 won't run.
However, if you use assertAll, even if #1 fails, #2 and #3 still get executed.

2. @DisplayName

@DisplayName("유저 테스트")
public class UserTest {

    @DisplayName("유저의 이름을 테스트 해보자!")
    @Test
    void someTest() {
        User user = new User();
        assertThat(user.getName()).isEqualTo("jyami");
    }

By doing this, you can use DisplayName to clearly state the purpose of each test.

3. assertThrows

@Test
void checkThrow() {
	Assertions.assertThrows(
		Exception.class, () -> {int a = 10/0;}
	);
}

When handling exceptions, you just need to put the logic you want to check for throws inside JUnit5's assertThrows.

 


AssertJ

1. contains()

@Test
void containsTest() {
	List<Integer> integers = Arrays.asList(1, 2, 3);
	assertThat(integers).contains(1, 2, 3);	//테스트 통과
	assertThat(integers).contains(2, 1, 3);	//테스트 통과
}

contains tests whether the actual group contains the given values regardless of order.
So both lines of tests above will pass.

2. containsExactly()

@Test
void containsExactlyTest() {
	List<Integer> integers = Arrays.asList(1, 2, 3);
	assertThat(integers).containsExactly(1, 2, 3);	//테스트 통과
	assertThat(integers).containsExactly(2, 1, 3);	//테스트 통과 X
	assertThat(integers).containsExactly(1, 2);	//테스트 통과 X
}

containsExactly tests whether the actual group contains the given values while also considering the order.
So the first line's test passes, but the second line's test does not.

One thing to note here is that if even a single element is missing, the test will fail. The list really has to match exactly!

 


This is a post that will be updated in the future.

댓글

Comments

Daily/Code Fest

Google Cloud OnBoard 후기 & 정리본 링크 | Google Cloud OnBoard Review & Summary Notes Link

2019년 11월 26일 세종대학교에서 열린 Google Cloud OnBoard에 다녀왔습니다.11월 초 summit에 다녀오긴 했는데 실제로 핸즈온 세션이 열린다고 해서 갔다왔습니다. https://inthecloud.withgoogle.com/onboard-global/core-ko-register.html?utm_content=summit-invite&utm_source=summit&utm_medium=event&utm_campaign=FY19-Q4-apac-onboard-operational-er-KROnBoardSeoul_EV_summit Cloud OnBoardCloud OnBoard is a free, instructor-led training event, that gives you a h..

Google Cloud OnBoard 후기 & 정리본 링크 | Google Cloud OnBoard Review & Summary Notes Link

728x90

2019년 11월 26일 세종대학교에서 열린 Google Cloud OnBoard에 다녀왔습니다.

11월 초 summit에 다녀오긴 했는데 실제로 핸즈온 세션이 열린다고 해서 갔다왔습니다.

 

https://inthecloud.withgoogle.com/onboard-global/core-ko-register.html?utm_content=summit-invite&utm_source=summit&utm_medium=event&utm_campaign=FY19-Q4-apac-onboard-operational-er-KROnBoardSeoul_EV_summit

 

Cloud OnBoard

Cloud OnBoard is a free, instructor-led training event, that gives you a headstart on your journey to developing on Google Cloud Platform (GCP).

inthecloud.withgoogle.com

 

요약하자면 기대와는 다르게 핸즈온 세션보다 그냥 듣는 세미나가 더 길었는데, 그래도 학교를 빠지고 하루를 투자해서 갔다온 행사였어서 최대한 여기에서의 정보를 활용할 수 있는 방법을 고민하다가 결국 블로그 포스팅을 하게되었습니다.

 

1. 자료집 워드본

나눠준 자료집을 한번 워드로 옮기면서 머리속에 어떤 제품이 있는지 메모해두고, 앞으로 백엔드 개발하면서 제 글을 참고해서 인프라 구축할 때 도움이 될 것 같아서 정리한 링크는 아래와 같습니다.

 

https://jyami.tistory.com/28

 

[Cloud OnBoard] 1 - Google Cloud Platform 소개

2019년 11월 26일 세종대학교에서 있었던 Google Cloud OnBoard에서 나누어준 자료집의 정리본입니다 모듈1 Google Cloud Platform 소개 0. 추가 자료 GCP를 선택해야하는 이유 : https://cloud.google.com/why-go..

jyami.tistory.com

 

https://jyami.tistory.com/29

 

[Cloud OnBoard] 2 - 가상머신 및 스토리지

2019년 11월 26일 세종대학교에서 있었던 Google Cloud OnBoard에서 나누어준 자료집의 정리본입니다 모듈2 가상머신 및 스토리지 0. 추가 자료 Google Compute Engine : https://cloud.google.com/compute/docs G..

jyami.tistory.com

https://jyami.tistory.com/30

 

[Cloud OnBoard] 3 - 컨테이너 및 앱 개발, 배포, 모니터링

2019년 11월 26일 세종대학교에서 있었던 Google Cloud OnBoard에서 나누어준 자료집의 정리본입니다 모듈3 컨테이너 및 앱 개발, 배포, 모니터링 0. 추가자료 Kubernetes Engine : https://cloud.google.com/kube..

jyami.tistory.com

https://jyami.tistory.com/31

 

[Cloud OnBoard] 4 - 빅데이터 및 머신러닝

2019년 11월 26일 세종대학교에서 있었던 Google Cloud OnBoard에서 나누어준 자료집의 정리본입니다 모듈4 빅데이터 및 머신러닝 0. 추가자료 Google 빅데이터 플랫폼 : https://cloud.google.com/products/big-d..

jyami.tistory.com

 

2.  행사

행사 자체는 Summit하고 굉장히 비슷했어요 GCP에 대한 전반적인 소개, 각 제품의 특징을 소개하는 세미나로 이루어 졌습니다.

그래도 중간에 quiklab 쿠폰이나 Coursera 쿠폰을 주셔서 줍줍 했네요ㅋㅋ

 

행사장 가는길 그리고 기념품

이번 행사는 끝나면 Cloud 팝소켓을 주더라구요! 수료증도 준다고 해서, 학교 빠진 것때문에 끝까지 앉아있다 왔습니다.

 

Google Cloud 행사에는 항상 게임기가 있네요ㅋㅋ

세션에 대한 정리는 위를 참고하시면 될 것 같구요.

사실 핸즈온 세션의 비중이 높은줄 알고왔지만 세션이 다 끝나고 있던 클라우드 히어로가 아무래도 직접 킥랩을 풀어보는 세션이라 그런지 가장 기억에 남네요

 

Google Cloud Platform 과 관련해서 문제를 푸는거였는데요 킥랩을 얼마나 많이 빨리 푸느냐에 따라 점수가 달라졌습니다. 아무래도 저는 GCP를 접한지 얼마 안되서 1번 2번을 풀다가 그만 했어요ㅋㅋ 3번은 kubernetes를 내 킥랩계정에 설정하는거였는데 kubernetes까지는 어렵더군요!

그래서 약 1시간동안 다같이 cloud hero문제를 풀고 1등부터 10등까지 랭킹에 드신분들에게는 히어로 망토랑 cloud 백팩을 주셨습니다!

 

근데 행사 당시 아무래도 인원이 많아서 그런지 인터넷도 너무 안좋았고, Gshell도 갑자기 너무 많은 요청이 들어와서 그런지 프로비저닝이 끝나지 않아서ㅠㅠㅠ 기다리던 시간이 조금 많았는데, 

만약 제가 정말 GCP를 잘아는 사람이라서 망토를 노릴 정도였다면 많이 아쉬웠을 것 같아요.

 

3. 세미나 요약 표!

그래서 아무래도 전체 행사가 세미나로 이루어져 있다보니까 집에 돌아와서 세미나내용이라도 얼추 제대로 읽어보기라도 하자 생각해서 하게된게 블로그 포스팅이었습니다ㅋㅋ

 

온보딩에 못가서 어떤걸 했는지 아쉬웠던 분들은 참고 하시면 좋을 것 같아요

 

1. 컴퓨팅 옵션 비교

2. 부하 분산 옵션 비교

3. 상호 연결 옵션 비교

4. 스토리지 옵션 비교

5. Google Cloud Storage 클래스 중에서 선택하기

On November 26, 2019, I attended Google Cloud OnBoard held at Sejong University.

I had already been to the summit in early November, but I went again because they said there would be hands-on sessions.

 

https://inthecloud.withgoogle.com/onboard-global/core-ko-register.html?utm_content=summit-invite&utm_source=summit&utm_medium=event&utm_campaign=FY19-Q4-apac-onboard-operational-er-KROnBoardSeoul_EV_summit

 

Cloud OnBoard

Cloud OnBoard is a free, instructor-led training event, that gives you a headstart on your journey to developing on Google Cloud Platform (GCP).

inthecloud.withgoogle.com

 

To sum it up, contrary to my expectations, the seminar portion was longer than the hands-on sessions. Still, since I skipped school and invested a whole day to attend this event, I was thinking about how to make the most of the information I got — and that's how I ended up writing this blog post.

 

1. Handout Material — Word Transcription

I transferred the handout materials into a Word document to keep a mental note of what products are available. I figured it would come in handy as a reference when setting up infrastructure for backend development in the future. Here are the organized links:

 

https://jyami.tistory.com/28

 

[Cloud OnBoard] 1 - Introduction to Google Cloud Platform

This is a summary of the handout materials from Google Cloud OnBoard held at Sejong University on November 26, 2019. Module 1: Introduction to Google Cloud Platform. 0. Additional Resources. Why choose GCP: https://cloud.google.com/why-go..

jyami.tistory.com

 

https://jyami.tistory.com/29

 

[Cloud OnBoard] 2 - Virtual Machines and Storage

This is a summary of the handout materials from Google Cloud OnBoard held at Sejong University on November 26, 2019. Module 2: Virtual Machines and Storage. 0. Additional Resources. Google Compute Engine: https://cloud.google.com/compute/docs G..

jyami.tistory.com

https://jyami.tistory.com/30

 

[Cloud OnBoard] 3 - Containers, App Development, Deployment, and Monitoring

This is a summary of the handout materials from Google Cloud OnBoard held at Sejong University on November 26, 2019. Module 3: Containers, App Development, Deployment, and Monitoring. 0. Additional Resources. Kubernetes Engine: https://cloud.google.com/kube..

jyami.tistory.com

https://jyami.tistory.com/31

 

[Cloud OnBoard] 4 - Big Data and Machine Learning

This is a summary of the handout materials from Google Cloud OnBoard held at Sejong University on November 26, 2019. Module 4: Big Data and Machine Learning. 0. Additional Resources. Google Big Data Platform: https://cloud.google.com/products/big-d..

jyami.tistory.com

 

2.  The Event

The event itself was very similar to the Summit. It consisted of seminars that gave a general overview of GCP and introduced the features of each product.

But they did give out Qwiklabs coupons and Coursera coupons during the event, so I snagged those lol

 

On the way to the venue, and the swag

At this event, they gave out Cloud PopSockets when it was over! They also said they'd give out certificates of completion, so since I had already skipped school for this, I stayed until the very end.

 

There's always an arcade machine at Google Cloud events lol

You can refer to the links above for the session summaries.

I actually came expecting a heavy focus on hands-on sessions, but the Cloud Hero activity at the end — where you actually solve Qwiklabs challenges yourself — ended up being the most memorable part.

 

It was about solving problems related to Google Cloud Platform, and your score depended on how many Qwiklabs challenges you solved and how fast. Since I was pretty new to GCP, I only managed to solve problems 1 and 2 before calling it quits lol. Problem 3 was about setting up Kubernetes on your Qwiklabs account, and that was just too hard for me!

So after about an hour of everyone solving Cloud Hero challenges together, the top 10 ranked participants received hero capes and Cloud backpacks!

 

But since there were so many people at the event, the internet was really bad, and Google Cloud Shell seemed overwhelmed by all the requests — provisioning just wouldn't finish 😭😭😭 There was quite a bit of waiting around.

If I had actually been someone who knew GCP well enough to compete for the cape, I would've been pretty frustrated.

 

3. Seminar Summary Charts!

Since pretty much the entire event was seminars, I came home thinking I should at least properly read through the seminar content — and that's what led me to write this blog post lol

 

If you missed the onboarding event and were curious about what was covered, hopefully this will be helpful!

 

1. Comparing Compute Options

2. Comparing Load Balancing Options

3. Comparing Interconnect Options

4. Comparing Storage Options

5. Choosing Among Google Cloud Storage Classes

댓글

Comments

Develop/DevOps

[Cloud OnBoard] 4 - 빅데이터 및 머신러닝 | [Cloud OnBoard] 4 - Big Data and Machine Learning

2019년 11월 26일 세종대학교에서 있었던 Google Cloud OnBoard에서 나누어준 자료집의 정리본입니다모듈4 빅데이터 및 머신러닝0. 추가자료Google 빅데이터 플랫폼 : https://cloud.google.com/products/big-dataGoogle AI Platform : https://cloud.google.com/products/ai1. Google Cloud 빅데이터 플랫폼1-1.Google Cloud의 빅데이터 서비스확장가능한 완전 관리형 서비스Cloud Dataproc : 관리형 Hadoop 맵리듀스, Spark, Pig, Hive 서비스Cloud Dataflow : 스트리밍 및 일괄 처리, 파이프라인 통합 및 관소화BigQuery : 분석 데이터베이스, 데이터 스트리..

[Cloud OnBoard] 4 - 빅데이터 및 머신러닝 | [Cloud OnBoard] 4 - Big Data and Machine Learning

728x90

2019년 11월 26일 세종대학교에서 있었던 Google Cloud OnBoard에서 나누어준 자료집의 정리본입니다


모듈4 빅데이터 및 머신러닝

0. 추가자료

Google 빅데이터 플랫폼 : https://cloud.google.com/products/big-data

Google AI Platform : https://cloud.google.com/products/ai

1. Google Cloud 빅데이터 플랫폼

1-1.Google Cloud의 빅데이터 서비스

  • 확장가능한 완전 관리형 서비스
  1. Cloud Dataproc : 관리형 Hadoop 맵리듀스, Spark, Pig, Hive 서비스
  2. Cloud Dataflow : 스트리밍 및 일괄 처리, 파이프라인 통합 및 관소화
  3. BigQuery : 분석 데이터베이스, 데이터 스트리밍 속도 초당 100,000원
  4. Cloud Pub/Sub : 확장 가능하고 유연한 엔터프라이즈 메시징
  5. Cloud Datalab : 대화형 데이터 탐색

1-2. Cloud Dataproc

  • 특징
    • 관리형 Hadoop
    • GCP Hadoop 및 Spark/Hive/Pig를 관리형으로 빠르고 쉽게 실행하는 방법
    • 클러스터 생성 시간 평균 90초 이하
    • 작업 실행 중에도 클러스터 규모 확장 및 축소
  • 사용해야하는 이유
    • 온프레미스 Hadoop 작업을 클라우드로 손쉽게 마이그레이션 합니다.
    • Cloud Storage에 저장된 로그 등의 데이터를 빠르게 분석하고, 평균 90초 이내에 클러스터를 생성하고, 즉시 삭제 합니다.
    • Spark/Spark SQL을 사용하여 데이터 마이닝 및 분석을 빠르게 수행합니다.
    • Spark 머신러닝 라이브러리(MLlib)를 사용하여 분류 알고리즘을 실행합니다.

1-3. Cloud Dataflow

  • 특징
    • 관리형 데이터 파이프라인
    • Compute Engine 인스턴스를 사용하여 데이터 처리
      • 클러스터 크기 자동 조절
      • 자동화된 확장, 인스턴스 프로비저닝이 필요하지 않음
    • 코드를 한 번만 작성하여 일괄 처리 및 스트리밍
      • 변환 기반 프로그래밍 모델
    • Dataflow 파이프라인으로 변환을 통해 소스의 데이터가 이동
  • 사용해야하는 이유
    • ETL (추출/변환/로드) 파이프라인으로 데이터 이동, 필터링, 다변화 및 형성
    • 데이터 분석: 일괄 연선 또는 스트리밍을 사용한 연속 연산
    • 오케스트레이션 : 외부 서비스를 포함하여 여러 서비스를 조율하는 파이프라인 작성
    • Cloud Storage, Cloud Pub/Sub, BigQuery, Bigtable 등의 GCP 서비스와 통합
      • 오픈 소스 Java 및 Python SDK

1-4. BigQuery

  • 완전 관리형 데이터 웨어하우스
    • 방대한 데이터세트 (수백 TB)에 대한 실시간에 가까운 대화형 분석 제공
    • SQL 구문(SQL 2011)을 사용하는 쿼리
    • 클러스터 유지보수가 필요하지 않음
  • Google의 고성능 인프라에서 실행
    • 컴퓨팅과 스토리지가 테라비트급 네트워크로 분리됨
    • 사용된 스토리지 및 처리에 대해서만 지불
    • 장기 데이터 스토리지 자동할인

1-5. Cloud Pub/Sub

  • 특징
    • 확장가능하고 안정적인 메시징
    • 다대다 비동기 메시징 지원 : 애플리케이션 구성요소에서 주제에 대한 push/pull 구독 작성
    • 오프라인 소비자 지원 포함
    • 검증된 Google 기술 활용
  • 사용해야하는 이유
    • Dataflow, 사물인터넷(IoT), 마케팅 분석의 데이터 수집을 위한 구성 요소
    • Dataflow 스트리밍의 기반
    • 클라우드 기반 애플리케이션의 푸시 알림
    • Google Cloud Platform에 속하는 여러 애플리케이션 연결(Compute Engine과 App Engine 사이에 push/pull)

1-6. Cloud Datalab

  • 특징
    • 대화형 데이터 탐색 제공
    • 대규모 데이터 탐색, 변환, 분석, 시각화를 위한 대화형 도구
    • 통합, 오픈 소스 : Jupyter(Ipython)를 기반으로함
  • 사용해야하는 이유
    • 코드, 문서, 결과, 시각화를 직관적인 메모장 형식으로 생성 및 관리
      손쉬운 시각화를 위해 Google Charts 또는 matplotlib 사용
    • Python SQL, 자바스크립트를 사용하여 BigQuery, ComputeEngine, Cloud Storage에서 데이터를 분석
    • BigQuery에 모델을 손쉽게 배포

2. Google Cloud AI Platform

2-1. Cloud AI Platform

  • 신경망 모델을 빌드 및 실행하는 오픈 소스 도구
    • 폭넓은 플랫폼 지원 : CPU 또는 GPU, 모바일, 서버, 클라우드
  • 완전 관리형 머신러닝 서비스
    • 익숙한 메모장 기반 개발자 환경
    • Google 인프라에 최적화, BigQuery 및 Cloud Storage와 통합
  • Google에서 빌드한 선행 학습된 머신러닝 모델
    • 음성: 결과를 실시간으로 스트리밍 하고, 80개의 언어를 이해함
    • 비전: 객체, 랜드마크, 텍스트, 콘텐츠 식별
    • 번역: 언어 감지 및 번역
    • 자연어: 텍스트의 의미, 구조
  • 구조화된 데이터 : 분류 및 회귀 / 추천 / 이상감지
  • 구조화되지 않은 데이터 : 이미지 및 동영상 분석 / 텍스트 분석

2-2. Cloud Vision API

  • 단순한 REST API로 이미지 분석
    • 로고 감지, 라벨 인식 등
  • Cloud Vision API에서 제공하는 기능
    • 이미지에서 유용한 정보 확보
    • 부적절한 콘텐츠 감지
    • 정서 분석
    • 텍스트 추출

2-3. Cloud Speech API

  • 80개 이상 언어 및 변형어 인식
  • 실시간으로 텍스트 반환 가능
  • 소음이 심환 환경에서도 높은 정확도 제공
  • 모든 기기에서 액세스
  • Google 머신러닝 기반

2-4. Cloud Natural Language API

  • 머신러닝 모델을 사용하여 텍스트의 구조와 의미를 파악합니다
  • 텍스문서, 뉴스기사, 블로그 글에서 언급된 사안에 관한 정보를 추출합니다.
  • 요청시 업로드된 텍스트를 분석하거나 Cloud Storage와 통합합니다.

2-5. Cloud Translation API

  • 수많은 언어 쌍 사이에서 임의 문자열 번역
  • 문서의 언어를 프로그래매틱 방식으로 감지
  • 수십 개의 언어 지원

2-6. Cloud Video Intelligence API

  • 동영상 콘텐츠에 특수효과 적용
  • 장면 변화 감지
  • 부적절한 콘텐츠 신고
  • 다양한 동영상 형식 지원

This is a summary of the materials distributed at the Google Cloud OnBoard event held at Sejong University on November 26, 2019.


Module 4: Big Data and Machine Learning

0. Additional Resources

Google Big Data Platform: https://cloud.google.com/products/big-data

Google AI Platform: https://cloud.google.com/products/ai

1. Google Cloud Big Data Platform

1-1. Google Cloud Big Data Services

  • Scalable, fully managed services
  1. Cloud Dataproc: Managed Hadoop MapReduce, Spark, Pig, Hive service
  2. Cloud Dataflow: Stream and batch processing, unified pipeline integration and simplification
  3. BigQuery: Analytics database, data streaming at 100,000 rows per second
  4. Cloud Pub/Sub: Scalable and flexible enterprise messaging
  5. Cloud Datalab: Interactive data exploration

1-2. Cloud Dataproc

  • Features
    • Managed Hadoop
    • A fast and easy way to run GCP Hadoop and Spark/Hive/Pig as a managed service
    • Average cluster creation time under 90 seconds
    • Scale clusters up and down even while jobs are running
  • Why you should use it
    • Easily migrate on-premises Hadoop workloads to the cloud.
    • Quickly analyze data such as logs stored in Cloud Storage, create clusters in under 90 seconds on average, and delete them immediately.
    • Perform data mining and analysis quickly using Spark/Spark SQL.
    • Run classification algorithms using the Spark machine learning library (MLlib).

1-3. Cloud Dataflow

  • Features
    • Managed data pipelines
    • Processes data using Compute Engine instances
      • Automatic cluster size adjustment
      • Automated scaling, no instance provisioning required
    • Write code once for both batch and stream processing
      • Transform-based programming model
    • Data moves from sources through transformations in a Dataflow pipeline
  • Why you should use it
    • Move, filter, enrich, and shape data with ETL (Extract/Transform/Load) pipelines
    • Data analytics: Batch computation or continuous computation using streaming
    • Orchestration: Build pipelines that coordinate multiple services, including external services
    • Integrates with GCP services such as Cloud Storage, Cloud Pub/Sub, BigQuery, and Bigtable
      • Open source Java and Python SDKs

1-4. BigQuery

  • Fully managed data warehouse
    • Provides near real-time interactive analysis on massive datasets (hundreds of TB)
    • Queries using SQL syntax (SQL 2011)
    • No cluster maintenance required
  • Runs on Google's high-performance infrastructure
    • Compute and storage separated by a terabit-class network
    • Pay only for storage used and processing performed
    • Automatic discounts for long-term data storage

1-5. Cloud Pub/Sub

  • Features
    • Scalable and reliable messaging
    • Supports many-to-many asynchronous messaging: Create push/pull subscriptions to topics from application components
    • Includes offline consumer support
    • Leverages proven Google technology
  • Why you should use it
    • A building block for data ingestion in Dataflow, Internet of Things (IoT), and marketing analytics
    • Foundation for Dataflow streaming
    • Push notifications for cloud-based applications
    • Connect multiple applications within Google Cloud Platform (push/pull between Compute Engine and App Engine)

1-6. Cloud Datalab

  • Features
    • Provides interactive data exploration
    • An interactive tool for large-scale data exploration, transformation, analysis, and visualization
    • Integrated, open source: Built on Jupyter (IPython)
  • Why you should use it
    • Create and manage code, documentation, results, and visualizations in an intuitive notebook format
      Use Google Charts or matplotlib for easy visualization
    • Analyze data from BigQuery, Compute Engine, and Cloud Storage using Python, SQL, and JavaScript
    • Easily deploy models to BigQuery

2. Google Cloud AI Platform

2-1. Cloud AI Platform

  • An open source tool for building and running neural network models
    • Broad platform support: CPU or GPU, mobile, server, cloud
  • Fully managed machine learning service
    • Familiar notebook-based developer environment
    • Optimized for Google infrastructure, integrated with BigQuery and Cloud Storage
  • Pre-trained machine learning models built by Google
    • Speech: Streams results in real time and understands 80 languages
    • Vision: Identifies objects, landmarks, text, and content
    • Translation: Language detection and translation
    • Natural Language: Meaning and structure of text
  • Structured data: Classification and regression / Recommendations / Anomaly detection
  • Unstructured data: Image and video analysis / Text analysis

2-2. Cloud Vision API

  • Analyze images with a simple REST API
    • Logo detection, label recognition, and more
  • Features provided by Cloud Vision API
    • Extract useful information from images
    • Detect inappropriate content
    • Sentiment analysis
    • Text extraction

2-3. Cloud Speech API

  • Recognizes over 80 languages and variants
  • Can return text in real time
  • Provides high accuracy even in noisy environments
  • Accessible from any device
  • Powered by Google machine learning

2-4. Cloud Natural Language API

  • Uses machine learning models to understand the structure and meaning of text
  • Extracts information about topics mentioned in text documents, news articles, and blog posts.
  • Analyzes uploaded text on request or integrates with Cloud Storage.

2-5. Cloud Translation API

  • Translates arbitrary strings between numerous language pairs
  • Programmatically detects the language of a document
  • Supports dozens of languages

2-6. Cloud Video Intelligence API

  • Annotate video content
  • Detect scene changes
  • Flag inappropriate content
  • Supports various video formats

댓글

Comments

Develop/DevOps

[Cloud OnBoard] 3 - 컨테이너 및 앱 개발, 배포, 모니터링 | [Cloud OnBoard] 3 - Container and App Development, Deployment, Monitoring

2019년 11월 26일 세종대학교에서 있었던 Google Cloud OnBoard에서 나누어준 자료집의 정리본입니다 모듈3 컨테이너 및 앱 개발, 배포, 모니터링0. 추가자료Kubernetes Engine : https://cloud.google.com/kubernetes-engine/docsKubernetes : https://kubernetes.ioGoogle Cloud Build : https://cloud.google.com/cloud-build/docsGoogle Container Registry : https://cloud.google.com/container-regitry/docsGoogle App Engine : https://cloud.google.com/appengine/docsGoo..

[Cloud OnBoard] 3 - 컨테이너 및 앱 개발, 배포, 모니터링 | [Cloud OnBoard] 3 - Container and App Development, Deployment, Monitoring

728x90

2019년 11월 26일 세종대학교에서 있었던 Google Cloud OnBoard에서 나누어준 자료집의 정리본입니다

 


모듈3 컨테이너 및 앱 개발, 배포, 모니터링

0. 추가자료

Kubernetes Engine : https://cloud.google.com/kubernetes-engine/docs

Kubernetes : https://kubernetes.io

Google Cloud Build : https://cloud.google.com/cloud-build/docs

Google Container Registry : https://cloud.google.com/container-regitry/docs

Google App Engine : https://cloud.google.com/appengine/docs

Google App Engine 가변형 환경 : https://cloud.google.com/appengine/docs/flexible

Google App Engine 표준 환경 : https://cloud.google.com/appengine/docs/standard

Google Cloud Endpoints : https://cloud.google.com/endpoints/docs

Apigee Edge : https://cloud.google.com/api-services/content/what-apigee-edge

Cloud Source Repositories : https://cloud.google.com/source-repositories/docs

Deployment Manager : https://cloud.google.com/deployment-manager/docs

Google Stackdriver : https://cloud.google.com/stackdriver/docs

1. 복습 : IaaS와 PasS

 

IaaS: Infrastructure as a Service - AWS EC2

인프라 스트럭쳐 레벨을 제공하는 서비스이다. 고객이 OS와 어플리케이션을 직접 관리한다.

PaaS : Platform as a Service - heroku

개발자가 어플리케이션을 개발, 서비스하기위해 사용가능한 기능들이 제공되는 클라우드 서비스. 사용자는 어플리케이션과 데이터만 관리

2. 컨테이너 소개

  • IaaS : 하드웨어를 가상화 하고, 리소스를 공유할 수 있다.
  • 하지만 유연성에는 부팅시간(분)과 리소스(GB)가 부과된다.
  • App Engine
    • 프로그래밍 서비스에 대한 액세스를 제공
    • 앱 수요가 늘어날 수록 워크로드 및 인프라에 따라 독립적으로 앱을 신속하게 확장하는 플랫폼

2-1. 컨테이너

  • 컨테이너에서 제공하는 사항
    • IaaS와 PaaS의 확장성을 제공한다.
    • 하드웨어 및 OS의 추상화 레이어
    • 격리된 파티션으로 나눈 파일 시스템, RAM 네트워킹에 대한 구성 가능한 액세스를 제공하는 보이지 않는 상자
    • 빠른 시작
  • 컨테이너의 기능
    • 구성이 가능하며 독립적이고 이식성이 우수하다.
    • 자체 하드웨어, OS, 소프트웨어 스택 구성 정의
    • OS 및 하드웨어를 블랙박스처럼 이용하여 개발에서 스테이징, 프로덕션에 이르기까지 또는 노트북에서 클라우드로 마이그레이션 하는 과정에서 아무것도 변경하거나 다시 빌드할 필요가 없다.

컨테이너는 앱 + 라이브러리 : 컨테이너 인터페이스를 구현한게 OS/하드웨어

2-2. 클러스터

  • 클러스터의 기능
    • 공동의 호스트 구성으로 컨테이너를 서버 그룹에 배포가 가능하다.
    • 네트워크 연결을 사용해서 여러 컨테이너를 연결
    • 모듈식 코드 작성
    • 손쉬운 배포
    • 컨테이너 및 호스트의 독립적인 확장으로 최대 효율과 절약 달성

3. Kubernetes 및 Kubernetes Engine

3-1. Kubernetes

여러 호스트의 많은 컨테이너를 쉽게 조정한다.

 

  1. 앱을 컨테이너로 빌드해 실행해보기
    • Docker : 앱, 종속항목, 시스템 설정을 번들로 묶는다
    • Google Cloud Build 등의 다른 도구도 사용이 가능하다. 코드 예시 : hello world를 표시하는 python flask 앱
[app.py]

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "helloworld!"

if __name__ == "__main__":
    app.run(host='0.0.0.0');

 

  1. 앱을 Kubernetes로 가져오기 - Docker 파일을 사용해 4가지 지정

    • Flask 종속 항목의 requirements.txt 파일
    • Python의 OS 이미지 및 버전
    • Python 설치 방법
    • 앱 실행 방법
[requirement.txt]
Flask==0.12
uwsgi==2.0.15

 

FROM ubuntu:18.10
RUN apt-get update -y && \
    apt-get install -y python3-pip python3-dev
COPY requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip3 install -r requirements.txt
COPY ./app
ENDPOINT ["python3", "app.py"]

 

  1. 컨테이너를 이미지로 빌드해 실행하기

    • docker build로 컨테이너를 빌드하여 로컬에 실행 가능한 이미지로 저장
    • 공유를 위해 레지스트리 서비스 (Google Container Registry 등)에 이미지 업로드 기능
    • docker run으로 컨테이너 이미지를 시작
$> docker build -t py-server .
$> docker run -d py-server

 

  1. Kubernetes API를 사용해 컨테이너를 클러스터라고 부르는 노드 모음에 배포하기

    • 마스터는 제어영역을 실행
    • 노드는 컨테이너를 실행
    • 노드는 VM(GKE에서는 GCE인스턴스로 사용됨)
    • 사용자가 앱을 설명하면 Kubernetes가 구현방법 파악
  2. Kubernetes Engine 부트 스트랩하기
    • GKE 클러스터에서 다음 사항을 지정 가능 > 머신 유형 > 노드수 > 네트워크 설정 등
$> gcloud container clusters create k1
  1. 컨테이너를 노드에 배포할때 Pod라고 부르는 래퍼 사용하기
  1. Kubectl run을 사용해 Pod에서 컨테이너 실행하기

    • Kubectl은 Kubernetes API에 대한 명령줄 클라이언트임
    • 이 명령어로 Pod에서 실행 중인 컨테이너에 배포를 시작
    • 이 경우 컨테이너는 NGINX 서버의 이미지임
$> kubectl run nginx --image=nginx:1.15.7
      1. 배포
        • 앱 또는 워크로드의 복제본 Pod 모음을 관리하고 원하는 수의 Pod가 실행되고 정상상태를 유지하도록 한다
$> kubectl get pods
  1. 기본적으로 클러스터 안에서만 사용되며, 임시 IP를 가져오는 Pod

    • 고정 IP에서 공개적으로 사용할 수 있도록 Kubectl expose를 실행하여 부하 분산기를 배포에 연결가능
    • Kubernetes에서 Pod의 고정 IP를 사용해 서비스를 만들며 컨트롤러에 'I need to attach an external load balancer with a public IP address'라는 메세지가 표시됨
$> kubectl expose deployments nginx --port=80 --type=LoadBalancer
  1. 이 IP에 도달한 클라이언트는 서비스 뒤에 있는 Pod로 라우팅 됨
    • 예를 들어 프런트엔드 및 백엔드라는 이름의 Pod 모음을 2개 만들어 자체 서비스 뒤에 배치할 경우 백엔드 Pod에서 변경이 발생해도 프런트엔드 Pod에서 이를 알지 못한다. 백엔드 서비스를 참조할 뿐
  1. kubectl get services를 실행해 서비스의 공개 IP를 가져오기
$> kubectl get services
NAME     TYPE             CLUSTER-IP     EXTERNAL-IP     PORT(S) AGE
nginx    LoadBalancer    10.0.65.118    104.198.149.140    80/TCP    5m
  1. kubectl scale을 실행해 배포 확장하기
$> kubectl scale nginx ==replicas=3
  1. 각종 매개변수를 사용해 자동확장을 실행하거나 지능적 관리를 위해 프로그래밍 로직 뒤에 자동 확장 배치 가능
$> kubectl autoscale nginx --min=10 --max=15 --cpu=80

 

  1. 선언적 방법을 사용할 때 Kubernetes의 진정한 강점이 발휘
    • 예 : 구성 파일을 가져오는 방법
$> kubectl get pods -l "app=nginx"

 

[nginx-development.yaml]
apiVersion: v1
kind: Deployment
metadata:
    name: nginx
    labels:
        app: nginx
spec:
    replicas: 3
    selector:
        matchLabels:
            app: nginx
        template:
            metadata:
                labels:
                    app: nginx
            spec:
                containers:
                    - name: nginx
                      image: nginx:1.15.7
                      ports:
                          - continerPort: 80
  1. kubectl apply -f 를 실행해 변경사항을 선언적으로 적용하기
$> kubectl apply -f nginx-deployment.yaml

 

  1. kubectl get replicasets를 실행해 업데이트 상태 확인하기
$> kubectl get replicasets

 

NAME                DESIRED    CURRENT    READY    AGE
nginx-2035384211    5        3        3        2s

 

  1. kubectl get pods를 실행해 Pod가 온라인으로 전환되는 것 확인하기
$> kubectl get pods

 

NAME                    READY    STATUS    RESTARTS    AGE
nginx-203584211-7ci7o    1/1        Running    0            18s
nginx-203584211-he3h3    1/1        Running    0            18s
nginx-203584211-qqcnn    1/1        Running    0            18s
nginx-203584211-abbcc    1/1        Running    0            18s
nginx-203584211-knlen    1/1        Running    0            18s

 

  1. kubectl get deployments 실행으로 배포를 설명해 적절한 수의 복제본 실행하기
$> kubectl get deployments

 

NAME    DESIRED    CURRENT    UP-TO-DATE    AVAILABLE    AGE
nginx    5        5        5            5            18s

 

  1. 컨테이너를 빌드하고 이미지 실행하기
$> kubectl get services

 

NAME     TYPE             CLUSTER-IP     EXTERNAL-IP     PORT(S) AGE
nginx    LoadBalancer    10.0.65.118    104.198.149.140    80/TCP    5m

 

4. Google App Engine

  • 확장 가능한애플리케이션을 빌드할 수 있는 PaaS
  • App Engine으로 배포 유지보수, 확장이 쉬워지므로 혁신에만 집중할 수 있음
  • 확장가능한 웹 애플리케이션 및 모바일 백엔드를 빌드하는데 특히 적합함

5. Google App Engine 표준환경

  • 손쉬운 애플리케이션 배포
  • 수요에 대응하여 워크로드 자동 확장
  • 경제성
    • 무료 일일 할당량 / 사용량 기준 가격 책정
  • 개발, 테스트, 배포용 SDK
  • 특정 버전의 자바, Python, PHP, Go가 지원됨
  • 애플리케이션이 샌드박스 제약을 준수해야함
    • 로컬 파일 시스템에 쓰기 금지
    • 모든 요청에 타임아웃 60초가 적용됨
    • 타사 소프트웨어 설치가 제한됨

예시 웹 애플리케이션

6. Google App Engine 가변형 환경

  • 클릭 한번으로 컨테이너형 앱 빌드 및 배포
  • 샌드박스 제약 없음
  • App Engine 리소스에 액세스 가능
  • 표준 런타임 : Python, 자바, Go, Node.js
  • 커스텀 런타임 지원: HTTP요청을 지원하는 모든 언어
  • 런타임을 Dockerfile로 패키지화

App Engine 환경 비교

7. Google Cloud Endpoints 및 ApiGee Edge

  • 애플리케이션 프로그래밍 인터페이스로 세부정보를 숨기고 계약을 시행 [그림]

7-1. Cloud Endpoints

  • API의 생성 및 유지보수를 지원
  • API 콘솔을 통해 분산된 API 관리
  • RESTful 인터페이스를 사용하여 API 노출
  • JSON 웹 토큰 및 Google API 키를 사용하여 액세스 제어 및 호출 유효성 검사
    -> Auth0 및 Firebase 인증을 통해 웹, 모바일 사용자 신원 확인
  • 클라이언트 라이브러리 생성
  • 지원되는 플랫폼 [그림]

7-2. Apigee Edge

  • API의 보안과 수익 창출을 지원
  • 곡객과 파트너가 API를 사용할 수 있는 플랫폼
  • 분석, 수익 창출, 개발자 포털 제공

8. 클라우드에서 개발, 배포 모니터링

8-1. Cloud Source Repositories

  • Google Cloud Platform에 호스팅된 완전한 Git 저장소
  • 클라우드 앱의 공동 개발 지원
  • Stackdriver Debugger 와의 통합 기능 제공

8-2. Cloud Functions

  • 서버 또는 런타임 없이 이벤트에 응답하는 단일 목적의 함수 생성
    이벤트 예시: 새로운 인스턴스가 생성됨. 파일이 Cloud Storage에 추가됨
  • Javascript로 작성됨, Google Cloud Platform의 관리형 Node.js 환경에서 실행함

8-3. Deployment Manager

  • 인프라 관리 서비스
  • 환경을 설명하는 .yaml 템플릿을 만들고 Deployment Manager를 사용하여 리소스 생성
  • 반복 가능한 배포 제공

8-4. Stackdriver

  1. Monitoring
    • 플랫폼, 시스템, 애플리케이션 측정항목
    • 업타임/상태 확인
    • 대시보드 및 알림
  2. Logging
    • 플랫폼, 시스템, 애플리케이션 로그
    • 로그 검색, 뷰, 필터, 내보내기
    • 로그 기반 측정 항목
  3. Trace
    • 지연 시간 보고 및 샘플링
    • URL별 지연 시간 및 통계
  4. Error Reporting
    • 오류 알림
    • 오류 대시보드
  5. Debugger
    • 애플리케이션 디버깅
  6. Profiler
    • CPU 및 메모리 사용량에 대한 지속적인 프로파일링

This is a summary of the materials handed out at the Google Cloud OnBoard event held at Sejong University on November 26, 2019.

 


Module 3: Containers and App Development, Deployment, Monitoring

0. Additional Resources

Kubernetes Engine : https://cloud.google.com/kubernetes-engine/docs

Kubernetes : https://kubernetes.io

Google Cloud Build : https://cloud.google.com/cloud-build/docs

Google Container Registry : https://cloud.google.com/container-regitry/docs

Google App Engine : https://cloud.google.com/appengine/docs

Google App Engine Flexible Environment : https://cloud.google.com/appengine/docs/flexible

Google App Engine Standard Environment : https://cloud.google.com/appengine/docs/standard

Google Cloud Endpoints : https://cloud.google.com/endpoints/docs

Apigee Edge : https://cloud.google.com/api-services/content/what-apigee-edge

Cloud Source Repositories : https://cloud.google.com/source-repositories/docs

Deployment Manager : https://cloud.google.com/deployment-manager/docs

Google Stackdriver : https://cloud.google.com/stackdriver/docs

1. Review: IaaS and PaaS

 

IaaS: Infrastructure as a Service - AWS EC2

A service that provides the infrastructure level. The customer directly manages the OS and applications.

PaaS : Platform as a Service - heroku

A cloud service that provides developers with the capabilities needed to develop and serve applications. Users only manage applications and data.

2. Introduction to Containers

  • IaaS : Virtualizes hardware and allows resource sharing.
  • However, flexibility comes at the cost of boot time (minutes) and resources (GB).
  • App Engine
    • Provides access to programming services
    • A platform that rapidly scales apps independently based on workload and infrastructure as app demand grows

2-1. Containers

  • What containers provide
    • Offers the scalability of both IaaS and PaaS.
    • An abstraction layer over hardware and OS
    • An invisible box that provides configurable access to file systems, RAM, and networking divided into isolated partitions
    • Fast startup
  • Container capabilities
    • Configurable, independent, and highly portable.
    • Define your own hardware, OS, and software stack configuration
    • By treating the OS and hardware as a black box, there's no need to change or rebuild anything when migrating from development to staging to production, or from a laptop to the cloud.

A container is app + libraries: the OS/hardware implements the container interface

2-2. Clusters

  • Cluster capabilities
    • Allows deploying containers to server groups with a shared host configuration.
    • Connects multiple containers using network connections
    • Write modular code
    • Easy deployment
    • Achieve maximum efficiency and savings through independent scaling of containers and hosts

3. Kubernetes and Kubernetes Engine

3-1. Kubernetes

Easily orchestrates many containers across multiple hosts.

 

  1. Build and run an app as a container
    • Docker : Bundles the app, dependencies, and system settings together
    • Other tools like Google Cloud Build can also be used. Code example: a Python Flask app that displays hello world
[app.py]

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "helloworld!"

if __name__ == "__main__":
    app.run(host='0.0.0.0');

 

  1. Bring the app to Kubernetes - Specify 4 things using a Docker file

    • The requirements.txt file for Flask dependencies
    • The OS image and version for Python
    • How to install Python
    • How to run the app
[requirement.txt]
Flask==0.12
uwsgi==2.0.15

 

FROM ubuntu:18.10
RUN apt-get update -y && \
    apt-get install -y python3-pip python3-dev
COPY requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip3 install -r requirements.txt
COPY ./app
ENDPOINT ["python3", "app.py"]

 

  1. Build the container into an image and run it

    • Use docker build to build the container and save it as a locally runnable image
    • Upload images to a registry service (such as Google Container Registry) for sharing
    • Start the container image with docker run
$> docker build -t py-server .
$> docker run -d py-server

 

  1. Deploy containers to a collection of nodes called a cluster using the Kubernetes API

    • The master runs the control plane
    • Nodes run the containers
    • Nodes are VMs (used as GCE instances in GKE)
    • You describe the app, and Kubernetes figures out how to implement it
  2. Bootstrapping Kubernetes Engine
    • In a GKE cluster, you can specify the following > Machine type > Number of nodes > Network settings, etc.
$> gcloud container clusters create k1
  1. Use a wrapper called a Pod when deploying containers to nodes
  1. Run a container in a Pod using Kubectl run

    • Kubectl is a command-line client for the Kubernetes API
    • This command starts a deployment with a container running in a Pod
    • In this case, the container is an image of an NGINX server
$> kubectl run nginx --image=nginx:1.15.7
      1. Deployment
        • Manages a set of replica Pods for an app or workload, ensuring the desired number of Pods are running and remain healthy
$> kubectl get pods
  1. Pods are only accessible within the cluster by default and have ephemeral IPs

    • Run Kubectl expose to attach a load balancer to the deployment so it's publicly accessible at a static IP
    • Kubernetes creates a service using the Pod's static IP, and the controller displays a message saying 'I need to attach an external load balancer with a public IP address'
$> kubectl expose deployments nginx --port=80 --type=LoadBalancer
  1. Clients reaching this IP are routed to the Pods behind the service
    • For example, if you create two sets of Pods named frontend and backend and place them behind their own services, changes in the backend Pods won't be noticed by the frontend Pods. They simply reference the backend service.
  1. Run kubectl get services to get the public IP of the service
$> kubectl get services
NAME     TYPE             CLUSTER-IP     EXTERNAL-IP     PORT(S) AGE
nginx    LoadBalancer    10.0.65.118    104.198.149.140    80/TCP    5m
  1. Run kubectl scale to scale the deployment
$> kubectl scale nginx ==replicas=3
  1. Use various parameters to enable autoscaling, or place autoscaling behind programming logic for intelligent management
$> kubectl autoscale nginx --min=10 --max=15 --cpu=80

 

  1. The true power of Kubernetes shines when using the declarative approach
    • Example: How to use a configuration file
$> kubectl get pods -l "app=nginx"

 

[nginx-development.yaml]
apiVersion: v1
kind: Deployment
metadata:
    name: nginx
    labels:
        app: nginx
spec:
    replicas: 3
    selector:
        matchLabels:
            app: nginx
        template:
            metadata:
                labels:
                    app: nginx
            spec:
                containers:
                    - name: nginx
                      image: nginx:1.15.7
                      ports:
                          - continerPort: 80
  1. Run kubectl apply -f to declaratively apply changes
$> kubectl apply -f nginx-deployment.yaml

 

  1. Run kubectl get replicasets to check the update status
$> kubectl get replicasets

 

NAME                DESIRED    CURRENT    READY    AGE
nginx-2035384211    5        3        3        2s

 

  1. Run kubectl get pods to verify the Pods are coming online
$> kubectl get pods

 

NAME                    READY    STATUS    RESTARTS    AGE
nginx-203584211-7ci7o    1/1        Running    0            18s
nginx-203584211-he3h3    1/1        Running    0            18s
nginx-203584211-qqcnn    1/1        Running    0            18s
nginx-203584211-abbcc    1/1        Running    0            18s
nginx-203584211-knlen    1/1        Running    0            18s

 

  1. Run kubectl get deployments to describe the deployment and verify the correct number of replicas are running
$> kubectl get deployments

 

NAME    DESIRED    CURRENT    UP-TO-DATE    AVAILABLE    AGE
nginx    5        5        5            5            18s

 

  1. Build the container and run the image
$> kubectl get services

 

NAME     TYPE             CLUSTER-IP     EXTERNAL-IP     PORT(S) AGE
nginx    LoadBalancer    10.0.65.118    104.198.149.140    80/TCP    5m

 

4. Google App Engine

  • A PaaS for building scalable applications
  • App Engine makes deployment, maintenance, and scaling easy, so you can focus solely on innovation
  • Particularly well-suited for building scalable web applications and mobile backends

5. Google App Engine Standard Environment

  • Easy application deployment
  • Automatic workload scaling in response to demand
  • Cost-effective
    • Free daily quota / usage-based pricing
  • SDKs for development, testing, and deployment
  • Supports specific versions of Java, Python, PHP, and Go
  • Applications must comply with sandbox constraints
    • No writing to the local file system
    • A 60-second timeout applies to all requests
    • Third-party software installation is restricted

Example web application

6. Google App Engine Flexible Environment

  • Build and deploy containerized apps with a single click
  • No sandbox constraints
  • Access to App Engine resources
  • Standard runtimes: Python, Java, Go, Node.js
  • Custom runtime support: Any language that supports HTTP requests
  • Package the runtime as a Dockerfile

App Engine Environment Comparison

7. Google Cloud Endpoints and Apigee Edge

  • Application programming interfaces hide implementation details and enforce contracts [diagram]

7-1. Cloud Endpoints

  • Supports API creation and maintenance
  • Distributed API management through the API console
  • Expose APIs using RESTful interfaces
  • Access control and call validation using JSON Web Tokens and Google API keys
    -> Verify web and mobile user identity through Auth0 and Firebase Authentication
  • Client library generation
  • Supported platforms [diagram]

7-2. Apigee Edge

  • Supports API security and monetization
  • A platform where customers and partners can use APIs
  • Provides analytics, monetization, and developer portal

8. Development, Deployment, and Monitoring in the Cloud

8-1. Cloud Source Repositories

  • Fully-featured Git repositories hosted on Google Cloud Platform
  • Supports collaborative development of cloud apps
  • Provides integration with Stackdriver Debugger

8-2. Cloud Functions

  • Create single-purpose functions that respond to events without a server or runtime
    Event examples: A new instance is created. A file is added to Cloud Storage.
  • Written in Javascript, runs in a managed Node.js environment on Google Cloud Platform

8-3. Deployment Manager

  • Infrastructure management service
  • Create .yaml templates that describe your environment and use Deployment Manager to create resources
  • Provides repeatable deployments

8-4. Stackdriver

  1. Monitoring
    • Platform, system, and application metrics
    • Uptime/health checks
    • Dashboards and alerts
  2. Logging
    • Platform, system, and application logs
    • Log search, view, filter, and export
    • Log-based metrics
  3. Trace
    • Latency reporting and sampling
    • Per-URL latency and statistics
  4. Error Reporting
    • Error notifications
    • Error dashboard
  5. Debugger
    • Application debugging
  6. Profiler
    • Continuous profiling of CPU and memory usage

댓글

Comments