11.4. Quarkus 함수 개발

Quarkus 함수 프로젝트를 생성한 후에는 지정된 템플릿 파일을 수정하여 비즈니스 로직을 함수에 추가할 수 있습니다. 여기에는 함수 호출 구성 및 반환된 헤더 및 상태 코드가 포함됩니다.

11.4.1. 사전 요구 사항

11.4.2. Quarkus 함수 템플릿 구조

Knative(kn) CLI를 사용하여 Quarkus 함수를 생성할 때 프로젝트 디렉터리는 일반적인 Maven 프로젝트와 유사합니다. 또한 프로젝트에는 함수 구성에 사용되는 func.yaml 파일이 포함되어 있습니다.

httpevent 트리거 함수 모두 동일한 템플릿 구조를 갖습니다.

템플릿 구조

.
├── func.yaml 1
├── mvnw
├── mvnw.cmd
├── pom.xml 2
├── README.md
└── src
    ├── main
    │   ├── java
    │   │   └── functions
    │   │       ├── Function.java 3
    │   │       ├── Input.java
    │   │       └── Output.java
    │   └── resources
    │       └── application.properties
    └── test
        └── java
            └── functions 4
                ├── FunctionTest.java
                └── NativeFunctionIT.java

1
이미지 이름과 레지스트리를 결정하는 데 사용됩니다.
2
POM(Project Object Model) 파일에는 종속성에 대한 정보와 같은 프로젝트 구성이 포함되어 있습니다. 이 파일을 수정하여 다른 종속 항목을 추가할 수 있습니다.

추가 종속 항목 예

...
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.assertj</groupId>
      <artifactId>assertj-core</artifactId>
      <version>3.8.0</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
...

종속성은 첫 번째 컴파일 중에 다운로드됩니다.

3
함수 프로젝트에는 @Funq 주석이 추가된 Java 메서드가 포함되어야 합니다. 이 메서드를 Function.java 클래스에 배치할 수 있습니다.
4
함수의 로컬 테스트에 사용할 수 있는 간단한 테스트 케이스가 포함되어 있습니다.

11.4.3. Quarkus 함수 호출 정보

클라우드 이벤트에 응답하는 Quarkus 프로젝트 또는 간단한 HTTP 요청에 응답하는 Quarkus 프로젝트를 생성할 수 있습니다. Knative의 클라우드 이벤트는 HTTP를 통해 POST 요청으로 전송되므로 두 기능 유형 모두 들어오는 HTTP 요청을 수신하고 응답할 수 있습니다.

들어오는 요청이 수신되면 Quarkus 함수가 허용된 유형의 인스턴스와 함께 호출됩니다.

표 11.1. 함수 호출 옵션

호출 메소드인스턴스에 포함된 데이터 유형데이터 예

HTTP POST 요청

요청 본문에 있는 JSON 오브젝트

{ "customerId": "0123456", "productId": "6543210" }

HTTP GET 요청

쿼리 문자열의 데이터

?customerId=0123456&productId=6543210

CloudEvent

data 속성의 JSON 개체

{ "customerId": "0123456", "productId": "6543210" }

다음 예제에서는 이전 표에 나열된 customerIdproductId 구매 데이터를 수신하고 처리하는 함수를 보여줍니다.

Quarkus 함수의 예

public class Functions {
    @Funq
    public void processPurchase(Purchase purchase) {
        // process the purchase
    }
}

구매 데이터를 포함하는 Purchase JavaBean 클래스는 다음과 같습니다.

클래스 예

public class Purchase {
    private long customerId;
    private long productId;
    // getters and setters
}

11.4.3.1. 호출 예

다음 예제 코드는 withBeans, withCloudEvent, withBinary라는 세 가지 함수를 정의합니다.

예제

import io.quarkus.funqy.Funq;
import io.quarkus.funqy.knative.events.CloudEvent;

public class Input {
    private String message;

    // getters and setters
}

public class Output {
    private String message;

    // getters and setters
}

public class Functions {
    @Funq
    public Output withBeans(Input in) {
        // function body
    }

    @Funq
    public CloudEvent<Output> withCloudEvent(CloudEvent<Input> in) {
        // function body
    }

    @Funq
    public void withBinary(byte[] in) {
        // function body
    }
}

Functions 클래스의 withBeans 함수는 다음을 통해 호출할 수 있습니다.

  • JSON 본문이 있는 HTTP POST 요청:

    $ curl "http://localhost:8080/withBeans" -X POST \
        -H "Content-Type: application/json" \
        -d '{"message": "Hello there."}'
  • 쿼리 매개변수가 있는 HTTP GET 요청:

    $ curl "http://localhost:8080/withBeans?message=Hello%20there." -X GET
  • 바이너리 인코딩의 CloudEvent 오브젝트:

    $ curl "http://localhost:8080/" -X POST \
      -H "Content-Type: application/json" \
      -H "Ce-SpecVersion: 1.0" \
      -H "Ce-Type: withBeans" \
      -H "Ce-Source: cURL" \
      -H "Ce-Id: 42" \
      -d '{"message": "Hello there."}'
  • 구조화된 인코딩의 CloudEvent 오브젝트:

    $ curl http://localhost:8080/ \
        -H "Content-Type: application/cloudevents+json" \
        -d '{ "data": {"message":"Hello there."},
              "datacontenttype": "application/json",
              "id": "42",
              "source": "curl",
              "type": "withBeans",
              "specversion": "1.0"}'

Functions 클래스의 withCloudEvent 함수는 withBeans 함수와 유사하게 CloudEvent 오브젝트를 사용하여 호출할 수 있습니다. 그러나 withBeans와 달리withCloudEvent는 일반 HTTP 요청으로 호출할 수 없습니다.

Functions 클래스의 withBinary 함수는 다음을 통해 호출할 수 있습니다.

  • 바이너리 인코딩의 CloudEvent 오브젝트:

    $ curl "http://localhost:8080/" -X POST \
      -H "Content-Type: application/octet-stream" \
      -H "Ce-SpecVersion: 1.0"\
      -H "Ce-Type: withBinary" \
      -H "Ce-Source: cURL" \
      -H "Ce-Id: 42" \
      --data-binary '@img.jpg'
  • 구조화된 인코딩의 CloudEvent 오브젝트:

    $ curl http://localhost:8080/ \
      -H "Content-Type: application/cloudevents+json" \
      -d "{ \"data_base64\": \"$(base64 --wrap=0 img.jpg)\",
            \"datacontenttype\": \"application/octet-stream\",
            \"id\": \"42\",
            \"source\": \"curl\",
            \"type\": \"withBinary\",
            \"specversion\": \"1.0\"}"

11.4.4. CloudEvent 속성

type 또는 subject와 같은 CloudEvent의 속성을 읽거나 작성해야 하는 경우 CloudEvent<T> 일반 인터페이스와 CloudEventBuilder 빌더를 사용할 수 있습니다. <T> 유형 매개변수는 허용된 유형 중 하나여야 합니다.

다음 예에서 CloudEventBuilder는 구매 처리 성공 또는 실패를 반환하는 데 사용됩니다.

public class Functions {

    private boolean _processPurchase(Purchase purchase) {
        // do stuff
    }

    public CloudEvent<Void> processPurchase(CloudEvent<Purchase> purchaseEvent) {
        System.out.println("subject is: " + purchaseEvent.subject());

        if (!_processPurchase(purchaseEvent.data())) {
            return CloudEventBuilder.create()
                    .type("purchase.error")
                    .build();
        }
        return CloudEventBuilder.create()
                .type("purchase.success")
                .build();
    }
}

11.4.5. Quarkus 함수 반환 값

함수는 허용된 유형 목록에서 모든 유형의 인스턴스를 반환할 수 있습니다. 또는 < T> 유형 매개변수가 허용된 유형의 모든 유형일 수 있는 Uni < T > 유형을 반환할 수 있습니다.

Uni<T> 유형은 반환된 오브젝트가 수신된 오브젝트와 동일한 형식으로 직렬화되기 때문에 함수가 비동기 API를 호출할 때 유용합니다. 예를 들면 다음과 같습니다.

  • 함수가 HTTP 요청을 수신하면 반환된 오브젝트가 HTTP 응답 본문에 전송됩니다.
  • 함수가 바이너리 인코딩으로 CloudEvent 오브젝트를 수신하는 경우 반환된 오브젝트는 바이너리 인코딩 CloudEvent 오브젝트의 데이터 속성으로 전송됩니다.

다음 예제에서는 구매 목록을 가져오는 함수를 보여줍니다.

명령 예

public class Functions {
    @Funq
    public List<Purchase> getPurchasesByName(String name) {
      // logic to retrieve purchases
    }
}

  • HTTP 요청을 통해 이 함수를 호출하면 응답 본문에서 구매한 목록을 포함하는 HTTP 응답이 생성됩니다.
  • 들어오는 CloudEvent 오브젝트를 통해 이 함수를 호출하면 data 속성에서 구매 목록이 포함된 CloudEvent 응답이 생성됩니다.

11.4.5.1. 허용된 유형

함수의 입력 및 출력은 void,String 또는 byte[] 유형 중 하나일 수 있습니다. 또한 기본 유형 및 해당 래퍼(예: intInteger )일 수 있습니다. 다음과 같은 복잡한 개체일 수도 있습니다. JavaBeans, map, lists, arrays, special CloudEvents<T> 유형.

맵, 목록, 배열, CloudEvents< T > 유형의 <T > 유형 매개변수 및 Javabeans의 속성은 여기에 나열된 유형만 사용할 수 있습니다.

예제

public class Functions {
    public List<Integer> getIds();
    public Purchase[] getPurchasesByName(String name);
    public String getNameById(int id);
    public Map<String,Integer> getNameIdMapping();
    public void processImage(byte[] img);
}

11.4.6. Quarkus 함수 테스트

Quarkus 함수는 컴퓨터에서 로컬로 테스트할 수 있습니다. kn func create 를 사용하여 함수를 생성할 때 생성되는 기본 프로젝트에는 basic Maven 테스트가 포함된labs /test/ 디렉터리가 있습니다. 이러한 테스트는 필요에 따라 확장할 수 있습니다.

사전 요구 사항

  • Quarkus 함수를 생성했습니다.
  • Knative(kn) CLI가 설치되어 있습니다.

절차

  1. 함수의 프로젝트 폴더로 이동합니다.
  2. Maven 테스트를 실행합니다.

    $ ./mvnw test

11.4.7. 다음 단계