6.4. Développer les fonctions de Quarkus
Après avoir créé un projet de fonction Quarkus, vous pouvez modifier les fichiers modèles fournis pour ajouter une logique commerciale à votre fonction. Cela inclut la configuration de l'invocation de la fonction et des en-têtes et codes d'état renvoyés.
6.4.1. Conditions préalables
- Avant de pouvoir développer des fonctions, vous devez effectuer les étapes de configuration dans Configuration des fonctions OpenShift Serverless.
6.4.2. Structure du modèle de fonction Quarkus
Lorsque vous créez une fonction Quarkus en utilisant la CLI Knative (kn
), le répertoire du projet ressemble à un projet Maven typique. En outre, le projet contient le fichier func.yaml
, qui est utilisé pour configurer la fonction.
Les fonctions de déclenchement http
et event
ont la même structure de modèle :
Structure du modèle
. ├── 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
- Utilisé pour déterminer le nom et le registre de l'image.
- 2
- Le fichier POM (Project Object Model) contient la configuration du projet, notamment des informations sur les dépendances. Vous pouvez ajouter des dépendances supplémentaires en modifiant ce fichier.
Exemple de dépendances supplémentaires
... <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.8.0</version> <scope>test</scope> </dependency> </dependencies> ...
Les dépendances sont téléchargées lors de la première compilation.
- 3
- Le projet de fonction doit contenir une méthode Java annotée avec
@Funq
. Vous pouvez placer cette méthode dans la classeFunction.java
. - 4
- Contient des cas de test simples qui peuvent être utilisés pour tester votre fonction localement.
6.4.3. A propos de l'invocation des fonctions de Quarkus
Vous pouvez créer un projet Quarkus qui répond aux événements cloud ou qui répond à de simples requêtes HTTP. Dans Knative, les événements cloud sont transportés par HTTP sous la forme d'une requête POST, de sorte que les deux types de fonctions peuvent écouter et répondre aux requêtes HTTP entrantes.
Lorsqu'une demande est reçue, les fonctions Quarkus sont invoquées avec une instance d'un type autorisé.
Méthode d'invocation | Type de données contenu dans l'instance | Exemple de données |
---|---|---|
Demande HTTP POST | Objet JSON dans le corps de la demande |
|
Demande HTTP GET | Données dans la chaîne de requête |
|
|
Objet JSON dans la propriété |
|
L'exemple suivant montre une fonction qui reçoit et traite les données d'achat customerId
et productId
énumérées dans le tableau précédent :
Exemple de fonction Quarkus
public class Functions { @Funq public void processPurchase(Purchase purchase) { // process the purchase } }
La classe JavaBean Purchase
correspondante qui contient les données d'achat se présente comme suit :
Exemple de classe
public class Purchase { private long customerId; private long productId; // getters and setters }
6.4.3.1. Exemples d'invocation
L'exemple de code suivant définit trois fonctions appelées withBeans
, withCloudEvent
et withBinary
;
Exemple :
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 } }
La fonction withBeans
de la classe Functions
peut être invoquée par :
Une requête HTTP POST avec un corps JSON :
$ curl "http://localhost:8080/withBeans" -X POST \ -H "Content-Type: application/json" \ -d '{"message": "Hello there."}'
Une requête HTTP GET avec des paramètres de requête :
$ curl "http://localhost:8080/withBeans?message=Hello%20there." -X GET
Un objet
CloudEvent
en codage binaire :$ 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."}'
Un objet
CloudEvent
dans un encodage structuré :$ 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"}'
La fonction withCloudEvent
de la classe Functions
peut être invoquée en utilisant un objet CloudEvent
, de la même manière que la fonction withBeans
. Cependant, contrairement à withBeans
, withCloudEvent
ne peut pas être invoquée avec une simple requête HTTP.
La fonction withBinary
de la classe Functions
peut être invoquée par :
Un objet
CloudEvent
en codage binaire :$ 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'
Un objet
CloudEvent
dans un encodage structuré :$ 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\"}"
6.4.4. Attributs du CloudEvent
Si vous devez lire ou écrire les attributs d'un CloudEvent, tel que type
ou subject
, vous pouvez utiliser l'interface générique CloudEvent<T>
et le constructeur CloudEventBuilder
. Le paramètre de type <T>
doit être l'un des types autorisés.
Dans l'exemple suivant, CloudEventBuilder
est utilisé pour renvoyer le succès ou l'échec du traitement de l'achat :
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(); } }
6.4.5. Valeurs de retour des fonctions Quarkus
Les fonctions peuvent renvoyer une instance de n'importe quel type de la liste des types autorisés. Elles peuvent également renvoyer le type Uni<T>
, où le paramètre de type <T>
peut être de n'importe quel type de la liste des types autorisés.
Le type Uni<T>
est utile si une fonction fait appel à des API asynchrones, car l'objet renvoyé est sérialisé dans le même format que l'objet reçu. En effet, l'objet retourné est sérialisé dans le même format que l'objet reçu :
- Si une fonction reçoit une requête HTTP, l'objet renvoyé est envoyé dans le corps de la réponse HTTP.
-
Si une fonction reçoit un objet
CloudEvent
en codage binaire, l'objet renvoyé est envoyé dans la propriété data d'un objetCloudEvent
codé en binaire.
L'exemple suivant montre une fonction qui récupère une liste d'achats :
Example command
public class Functions { @Funq public List<Purchase> getPurchasesByName(String name) { // logic to retrieve purchases } }
- L'invocation de cette fonction par le biais d'une requête HTTP produit une réponse HTTP qui contient une liste d'achats dans le corps de la réponse.
-
L'invocation de cette fonction par le biais d'un objet
CloudEvent
entrant produit une réponseCloudEvent
avec une liste d'achats dans la propriétédata
.
6.4.5.1. Types autorisés
L'entrée et la sortie d'une fonction peuvent être de l'un des types void
, String
ou byte[]
. En outre, il peut s'agir de types primitifs et de leurs enveloppes, par exemple int
et Integer
. Il peut également s'agir des objets complexes suivants : Javabeans, maps, lists, arrays et le type spécial CloudEvents<T>
.
Les cartes, les listes, les tableaux, le paramètre de type <T>
du type CloudEvents<T>
et les attributs des Javabeans ne peuvent être que des types énumérés ici.
Exemple :
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); }
6.4.6. Test des fonctions de Quarkus
Les fonctions Quarkus peuvent être testées localement sur votre ordinateur. Dans le projet par défaut qui est créé lorsque vous créez une fonction à l'aide de kn func create
, il y a le répertoire src/test/
, qui contient les tests Maven de base. Ces tests peuvent être étendus si nécessaire.
Conditions préalables
- Vous avez créé une fonction Quarkus.
-
Vous avez installé le CLI Knative (
kn
).
Procédure
- Accédez au dossier de projet de votre fonction.
Exécuter les tests Maven :
$ ./mvnw test
6.4.7. Prochaines étapes
- Construire et déployer une fonction.