diff --git a/README.md b/README.md index fcd9fb4..7ceea4c 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,31 @@ -> A template for new C8 inbound Connectors. +> A Connector template for new C8 inbound connector > > To use this template update the following resources to match the name of your connector: > > * [README](./README.md) (title, description) -> * [Element Template](./element-templates/inbound-template-connector.json) +> * [Element Template](./element-templates/template-connector-message-start-event.json) > * [POM](./pom.xml) (artifact name, id, description) -> * [Connector Executable](./src/main/java/io/camunda/connector/inbound/MyConnectorExecutable.java) (rename, implement, update `InboundConnector` annotation) -> * [Service Provider Interface (SPI)](./src/main/resources/META-INF/services/io.camunda.connector.api.inbound.InboundConnectorExecutable) (rename) +> * [Connector Executable](src/main/java/io/camunda/connector/inbound/MyConnectorExecutable.java) (rename, implement, + update + `InboundConnector` annotation) +> * [Service Provider Interface (SPI)](./src/main/resources/META-INF/services/io.camunda.connector.api.inbound.InboundConnectorExecutable) ( + rename) > > ...and delete this hint. -> -> Read more about [creating Connectors](https://docs.camunda.io/docs/components/connectors/custom-built-connectors/connector-sdk/#creating-a-custom-connector) -> +> +> Read more +> +about [creating Connectors](https://docs.camunda.io/docs/components/connectors/custom-built-connectors/connector-sdk/#creating-a-custom-connector) +> > Check out the [Connectors SDK](https://github.com/camunda/connector-sdk) - -# Inbound Connector Template +# Connector Template Camunda Inbound Connector Template +Emulates a simple inbound connector function that start process X times per minutes(to be specified in the element +template) + ## Build You can package the Connector by running the following command: @@ -30,39 +37,39 @@ mvn clean package This will create the following artifacts: - A thin JAR without dependencies. -- An uber JAR containing all dependencies, potentially shaded to avoid classpath conflicts. This will not include the SDK artifacts since those are in scope `provided` and will be brought along by the respective Connector Runtime executing the Connector. +- A fat JAR containing all dependencies, potentially shaded to avoid classpath conflicts. This will not include the SDK + artifacts since those are in scope `provided` and will be brought along by the respective Connector Runtime executing + the Connector. +- All element templates ### Shading dependencies You can use the `maven-shade-plugin` defined in the [Maven configuration](./pom.xml) to relocate common dependencies -that are used in other Connectors and the [Connector Runtime](https://github.com/camunda-community-hub/spring-zeebe/tree/master/connector-runtime#building-connector-runtime-bundles). -This helps to avoid classpath conflicts when the Connector is executed. +that are used in other Connectors and +the [Connector Runtime](https://github.com/camunda-community-hub/spring-zeebe/tree/master/connector-runtime#building-connector-runtime-bundles). +This helps to avoid classpath conflicts when the Connector is executed. Use the `relocations` configuration in the Maven Shade plugin to define the dependencies that should be shaded. -The [Maven Shade documentation](https://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html) +The [Maven Shade documentation](https://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html) provides more details on relocations. ## API -### Connector Properties - -This Connector can be configured with the following properties: +### Input -| Name | Description | Example | Can be a secret | -|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------------| -| sender | Value of the `sender` field of the messages generated by [`MockSubscription`](https://github.com/camunda/connector-template-inbound/blob/main/src/main/java/io/camunda/connector/inbound/subscription/MockSubscription.java) | `Alice` | Yes | -| messagesPerMinute | How many messages per minute should MockSubscription produce (1-10) | `3` | No | +| Name | Description | Example | +|--------------------|--------------------------------------|---------| +| Sender | Message sender | `alice` | +| Message per minute | Number of message created per minute | 6 | ### Output -This Connector produces the following output: - ```json { - "event": { - "sender": ".....", - "message": ".....", - "code": 999 + "event":{ + "sender":"test", + "code":4, + "message":"56b020ef-e51a-4a4b-b9a4-8df521a2e78f" } } ``` @@ -77,11 +84,82 @@ mvn clean verify ### Test with local runtime -Use the [Camunda Connector Runtime](https://github.com/camunda-community-hub/spring-zeebe/tree/master/connector-runtime#building-connector-runtime-bundles) to run your function as a local Java application. +To ensure the seamless functionality of your custom Camunda connector, please follow the steps below: + +#### Prerequisites: + +1. Camunda Modeler, which is available in two variants: + - [Desktop Modeler](https://camunda.com/download/modeler/) for a local installation. + - [Web Modeler](https://camunda.com/download/modeler/) for an online experience. + +2. [Docker](https://www.docker.com/products/docker-desktop), which is required to run the Camunda platform. + +#### Setting Up the Environment: + +1. Clone the Camunda Platform repository from GitHub: + + ```shell + git clone https://github.com/camunda/camunda-platform.git + ``` + +Navigate to the cloned directory and open docker-compose-core.yaml with your preferred text editor. + +Locate the connector image section and comment it out using the # symbol, as you will be executing your connector +locally. + +Initiate the Camunda suite with the following Docker command: -In your IDE you can also simply navigate to the `LocalContainerRuntime` class in test scope and run it via your IDE. -If necessary, you can adjust `application.properties` in test scope. + ```shell + docker compose -f docker-compose-core.yaml up + ``` + +### Configuring Camunda Modeler + +1. Install the Camunda Modeler if not already done. +2. Add the `element-templates/template-connector-message-start-event.json` to your Modeler configuration as per + the [Element Templates documentation](https://docs.camunda.io/docs/components/modeler/desktop-modeler/element-templates/configuring-templates/). + +### Launching Your Connector + +1. Run `io.camunda.example.LocalConnectorRuntime` to start your connector. +2. Create and initiate a process that utilizes your newly created connector within the Camunda + Modeler. ![Connector in Camunda Modeler](img/img.png) +3. Verify that the process is running smoothly by accessing Camunda Operate at [localhost:8081](http://localhost:8081). + +Follow these instructions to test and use your custom Camunda connector effectively. + +### Test with SaaS + +#### Prerequisites: + +None required. + +#### Setting Up the Environment: + +1. Navigate to Camunda [SaaS](https://console.camunda.io). +2. Create a cluster using the latest version available. +3. Select your cluster, then go to the `API` section and click `Create new Client`. +4. Ensure the `zeebe` checkbox is selected, then click `Create`. +5. Copy the configuration details displayed under the `Spring Boot` tab. +6. Paste the copied configuration into your `application.properties` file within your project. + +### Launching Your Connector + +1. Start your connector by executing `io.camunda.connector.inbound.LocalConnectorRuntime` in your development environment. +2. Access the Web Modeler and create a new project. +3. Click on `Create new`, then select `Upload files`. Upload the connector template from the repository you have. +4. In the same folder, create a new BPMN diagram. +5. Design and start a process that incorporates your new connector. + +By adhering to these steps, you can validate the integration of your custom Camunda connector with the SaaS environment. ## Element Template -The element templates can be found in the [element-templates/inbound-template-connector.json](element-templates/inbound-template-connector.json) file. +The element template for this sample connector is generated automatically based on the connector +input class using +the [Element Template Generator](https://github.com/camunda/connectors/tree/main/element-template-generator/core). + +The generation is embedded in the Maven build and can be triggered by running `mvn clean package`. + +The generated element template can be found +in [element-templates/template-connector.json](./element-templates/template-connector-message-start-event.json). diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml new file mode 100644 index 0000000..77cb70a --- /dev/null +++ b/dependency-reduced-pom.xml @@ -0,0 +1,191 @@ + + + 4.0.0 + io.camunda.connector + connector-template-inbound + connector-template-inbound + 0.1.0-SNAPSHOT + Camunda Inbound Connector Template + + + + maven-shade-plugin + + + package + + shade + + + + + + io.camunda.connector + element-template-generator-maven-plugin + ${version.connectors} + + + package + + generate-templates + + + + + + + io.camunda.connector.inbound.MyConnectorExecutable + + + io.camunda.connectors.inbound.EmailMessageStartEvent.v1 + email-inbound-connector-start-event.json + + + io.camunda.connectors.inbound.EmailIntermediate.v1 + email-inbound-connector-intermediate.json + + + io.camunda.connectors.inbound.EmailBoundary.v1 + email-inbound-connector-boundary.json + + + + + + + + + + + + + false + + connectors + Connectors Repository + https://artifacts.camunda.com/artifactory/connectors/ + + + + false + + + connectors-snapshots + Connectors Snapshot Repository + https://artifacts.camunda.com/artifactory/connectors-snapshots/ + + + + + io.camunda.connector + connector-core + 8.7.0-SNAPSHOT + provided + + + io.camunda.connector + connector-test + 8.7.0-SNAPSHOT + test + + + connector-runtime-core + io.camunda.connector + + + connector-validation + io.camunda.connector + + + + + org.junit.jupiter + junit-jupiter + 5.10.2 + test + + + junit-jupiter-api + org.junit.jupiter + + + junit-jupiter-params + org.junit.jupiter + + + junit-jupiter-engine + org.junit.jupiter + + + + + org.mockito + mockito-junit-jupiter + 5.11.0 + test + + + mockito-core + org.mockito + + + junit-jupiter-api + org.junit.jupiter + + + + + org.assertj + assertj-core + 3.25.3 + test + + + byte-buddy + net.bytebuddy + + + + + io.camunda.connector + spring-boot-starter-camunda-connectors + 8.7.0-SNAPSHOT + test + + + connector-runtime-spring + io.camunda.connector + + + spring-boot-starter-camunda-sdk + io.camunda + + + spring-core + org.springframework + + + spring-boot-starter-web + org.springframework.boot + + + spring-boot-starter-actuator + org.springframework.boot + + + connector-validation + io.camunda.connector + + + + + + 21 + 3.25.3 + 5.11.0 + UTF-8 + UTF-8 + 5.10.2 + 8.7.0-SNAPSHOT + + diff --git a/element-templates/inbound-template-connector.json b/element-templates/inbound-template-connector.json deleted file mode 100644 index 4623ba2..0000000 --- a/element-templates/inbound-template-connector.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json", - "name": "Test inbound Connector", - "id": "io.camunda.connectors.InboundTest.v1", - "version": 1, - "description": "Emulates subscription", - "category": { - "id": "connectors", - "name": "Connectors" - }, - "appliesTo": [ - "bpmn:StartEvent" - ], - "elementType": { - "value": "bpmn:StartEvent" - }, - "groups": [ - { - "id": "config", - "label": "Connector Configuration" - }, - { - "id": "output", - "label": "Output" - } - ], - "properties": [ - { - "type": "Hidden", - "value": "io.camunda:mytestinbound:1", - "binding": { - "type": "zeebe:property", - "name": "inbound.type" - } - }, - { - "type": "String", - "label":"Frequency", - "feel": "optional", - "group":"config", - "description":"Messages per minute (1-10)", - "value": "3", - "binding": { - "type": "zeebe:property", - "name": "messagesPerMinute" - } - }, - { - "type": "String", - "label":"Sender", - "feel": "optional", - "group":"config", - "description":"Message sender name", - "value": "Alice", - "binding": { - "type": "zeebe:property", - "name": "sender" - } - }, - { - "label": "Result variable", - "type": "String", - "group": "output", - "optional": true, - "binding": { - "type": "zeebe:property", - "name": "resultVariable" - }, - "description": "Name of variable to store the contents of the event" - }, - { - "label": "Variable expression", - "type": "String", - "group": "output", - "feel": "required", - "optional": true, - "binding": { - "type": "zeebe:property", - "name": "resultExpression" - }, - "description": "Expression to map elements of the event to process variables" - } - ] -} \ No newline at end of file diff --git a/element-templates/template-connector-boundary-event.json b/element-templates/template-connector-boundary-event.json new file mode 100644 index 0000000..ca3a19d --- /dev/null +++ b/element-templates/template-connector-boundary-event.json @@ -0,0 +1,173 @@ +{ + "$schema" : "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json", + "name" : "Template connector (Boundary Event)", + "id" : "io.camunda.connector.Template.v1:BoundaryEvent", + "description" : "Describe this connector", + "metadata" : { + "keywords" : [ ] + }, + "documentationRef" : "https://docs.camunda.io/docs/components/connectors/out-of-the-box-connectors/available-connectors-overview/", + "version" : 1, + "category" : { + "id" : "connectors", + "name" : "Connectors" + }, + "appliesTo" : [ "bpmn:BoundaryEvent" ], + "elementType" : { + "value" : "bpmn:BoundaryEvent", + "eventDefinition" : "bpmn:MessageEventDefinition" + }, + "groups" : [ { + "id" : "properties", + "label" : "Properties" + }, { + "id" : "activation", + "label" : "Activation" + }, { + "id" : "correlation", + "label" : "Correlation", + "tooltip" : "Learn more about message correlation in the documentation." + }, { + "id" : "output", + "label" : "Output mapping" + } ], + "properties" : [ { + "value" : "io.camunda:my-inbound-connector:1", + "binding" : { + "name" : "inbound.type", + "type" : "zeebe:property" + }, + "type" : "Hidden" + }, { + "id" : "sender", + "label" : "Sender", + "optional" : false, + "constraints" : { + "notEmpty" : true + }, + "feel" : "optional", + "group" : "properties", + "binding" : { + "name" : "sender", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "messagesPerMinute", + "label" : "Message per minute", + "optional" : false, + "feel" : "optional", + "group" : "properties", + "binding" : { + "name" : "messagesPerMinute", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "activationCondition", + "label" : "Activation condition", + "description" : "Condition under which the Connector triggers. Leave empty to catch all events", + "optional" : true, + "feel" : "required", + "group" : "activation", + "binding" : { + "name" : "activationCondition", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "correlationKeyProcess", + "label" : "Correlation key (process)", + "description" : "Sets up the correlation key from process variables", + "constraints" : { + "notEmpty" : true + }, + "feel" : "required", + "group" : "correlation", + "binding" : { + "name" : "correlationKey", + "type" : "bpmn:Message#zeebe:subscription#property" + }, + "type" : "String" + }, { + "id" : "correlationKeyPayload", + "label" : "Correlation key (payload)", + "description" : "Extracts the correlation key from the incoming message payload", + "constraints" : { + "notEmpty" : true + }, + "feel" : "required", + "group" : "correlation", + "binding" : { + "name" : "correlationKeyExpression", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "messageIdExpression", + "label" : "Message ID expression", + "description" : "Expression to extract unique identifier of a message", + "optional" : true, + "feel" : "required", + "group" : "correlation", + "binding" : { + "name" : "messageIdExpression", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "messageTtl", + "label" : "Message TTL", + "description" : "Time-to-live for the message in the broker (ISO-8601 duration)", + "optional" : true, + "constraints" : { + "notEmpty" : false, + "pattern" : { + "value" : "^(PT.*|)$", + "message" : "must be an ISO-8601 duration" + } + }, + "feel" : "optional", + "group" : "correlation", + "binding" : { + "name" : "messageTtl", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "messageNameUuid", + "generatedValue" : { + "type" : "uuid" + }, + "group" : "correlation", + "binding" : { + "name" : "name", + "type" : "bpmn:Message#property" + }, + "type" : "Hidden" + }, { + "id" : "resultVariable", + "label" : "Result variable", + "description" : "Name of variable to store the response in", + "group" : "output", + "binding" : { + "name" : "resultVariable", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "resultExpression", + "label" : "Result expression", + "description" : "Expression to map the response into process variables", + "feel" : "required", + "group" : "output", + "binding" : { + "name" : "resultExpression", + "type" : "zeebe:property" + }, + "type" : "Text" + } ], + "icon" : { + "contents" : "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTgiIHdpZHRoPSIxOCIgdmlld0JveD0iMCAwIDEwIDEwIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+PHRpdGxlPlNsYWNrPC90aXRsZT48ZyBmaWxsPSJub25lIj48cGF0aCBkPSJNMCwwIEwwLDEwIEwxMCwxMCBMMTAsMCB6IiBmaWxsPSIjZWNiMTJmIi8+PC9nPjwvc3ZnPg==" + } +} \ No newline at end of file diff --git a/element-templates/template-connector-intermediate-catch-event.json b/element-templates/template-connector-intermediate-catch-event.json new file mode 100644 index 0000000..9d0b210 --- /dev/null +++ b/element-templates/template-connector-intermediate-catch-event.json @@ -0,0 +1,173 @@ +{ + "$schema" : "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json", + "name" : "Template connector (Intermediate Catch Event)", + "id" : "io.camunda.connector.Template.v1:IntermediateCatchEvent", + "description" : "Describe this connector", + "metadata" : { + "keywords" : [ ] + }, + "documentationRef" : "https://docs.camunda.io/docs/components/connectors/out-of-the-box-connectors/available-connectors-overview/", + "version" : 1, + "category" : { + "id" : "connectors", + "name" : "Connectors" + }, + "appliesTo" : [ "bpmn:IntermediateCatchEvent", "bpmn:IntermediateThrowEvent" ], + "elementType" : { + "value" : "bpmn:IntermediateCatchEvent", + "eventDefinition" : "bpmn:MessageEventDefinition" + }, + "groups" : [ { + "id" : "properties", + "label" : "Properties" + }, { + "id" : "activation", + "label" : "Activation" + }, { + "id" : "correlation", + "label" : "Correlation", + "tooltip" : "Learn more about message correlation in the documentation." + }, { + "id" : "output", + "label" : "Output mapping" + } ], + "properties" : [ { + "value" : "io.camunda:my-inbound-connector:1", + "binding" : { + "name" : "inbound.type", + "type" : "zeebe:property" + }, + "type" : "Hidden" + }, { + "id" : "sender", + "label" : "Sender", + "optional" : false, + "constraints" : { + "notEmpty" : true + }, + "feel" : "optional", + "group" : "properties", + "binding" : { + "name" : "sender", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "messagesPerMinute", + "label" : "Message per minute", + "optional" : false, + "feel" : "optional", + "group" : "properties", + "binding" : { + "name" : "messagesPerMinute", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "activationCondition", + "label" : "Activation condition", + "description" : "Condition under which the Connector triggers. Leave empty to catch all events", + "optional" : true, + "feel" : "required", + "group" : "activation", + "binding" : { + "name" : "activationCondition", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "correlationKeyProcess", + "label" : "Correlation key (process)", + "description" : "Sets up the correlation key from process variables", + "constraints" : { + "notEmpty" : true + }, + "feel" : "required", + "group" : "correlation", + "binding" : { + "name" : "correlationKey", + "type" : "bpmn:Message#zeebe:subscription#property" + }, + "type" : "String" + }, { + "id" : "correlationKeyPayload", + "label" : "Correlation key (payload)", + "description" : "Extracts the correlation key from the incoming message payload", + "constraints" : { + "notEmpty" : true + }, + "feel" : "required", + "group" : "correlation", + "binding" : { + "name" : "correlationKeyExpression", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "messageIdExpression", + "label" : "Message ID expression", + "description" : "Expression to extract unique identifier of a message", + "optional" : true, + "feel" : "required", + "group" : "correlation", + "binding" : { + "name" : "messageIdExpression", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "messageTtl", + "label" : "Message TTL", + "description" : "Time-to-live for the message in the broker (ISO-8601 duration)", + "optional" : true, + "constraints" : { + "notEmpty" : false, + "pattern" : { + "value" : "^(PT.*|)$", + "message" : "must be an ISO-8601 duration" + } + }, + "feel" : "optional", + "group" : "correlation", + "binding" : { + "name" : "messageTtl", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "messageNameUuid", + "generatedValue" : { + "type" : "uuid" + }, + "group" : "correlation", + "binding" : { + "name" : "name", + "type" : "bpmn:Message#property" + }, + "type" : "Hidden" + }, { + "id" : "resultVariable", + "label" : "Result variable", + "description" : "Name of variable to store the response in", + "group" : "output", + "binding" : { + "name" : "resultVariable", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "resultExpression", + "label" : "Result expression", + "description" : "Expression to map the response into process variables", + "feel" : "required", + "group" : "output", + "binding" : { + "name" : "resultExpression", + "type" : "zeebe:property" + }, + "type" : "Text" + } ], + "icon" : { + "contents" : "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTgiIHdpZHRoPSIxOCIgdmlld0JveD0iMCAwIDEwIDEwIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+PHRpdGxlPlNsYWNrPC90aXRsZT48ZyBmaWxsPSJub25lIj48cGF0aCBkPSJNMCwwIEwwLDEwIEwxMCwxMCBMMTAsMCB6IiBmaWxsPSIjZWNiMTJmIi8+PC9nPjwvc3ZnPg==" + } +} \ No newline at end of file diff --git a/element-templates/template-connector-message-start-event.json b/element-templates/template-connector-message-start-event.json new file mode 100644 index 0000000..7f7a622 --- /dev/null +++ b/element-templates/template-connector-message-start-event.json @@ -0,0 +1,201 @@ +{ + "$schema" : "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json", + "name" : "Template connector (Message Start Event)", + "id" : "io.camunda.connector.Template.v1:MessageStartEvent", + "description" : "Describe this connector", + "metadata" : { + "keywords" : [ ] + }, + "documentationRef" : "https://docs.camunda.io/docs/components/connectors/out-of-the-box-connectors/available-connectors-overview/", + "version" : 1, + "category" : { + "id" : "connectors", + "name" : "Connectors" + }, + "appliesTo" : [ "bpmn:StartEvent" ], + "elementType" : { + "value" : "bpmn:StartEvent", + "eventDefinition" : "bpmn:MessageEventDefinition" + }, + "groups" : [ { + "id" : "properties", + "label" : "Properties" + }, { + "id" : "activation", + "label" : "Activation" + }, { + "id" : "correlation", + "label" : "Correlation", + "tooltip" : "Learn more about message correlation in the documentation." + }, { + "id" : "output", + "label" : "Output mapping" + } ], + "properties" : [ { + "value" : "io.camunda:my-inbound-connector:1", + "binding" : { + "name" : "inbound.type", + "type" : "zeebe:property" + }, + "type" : "Hidden" + }, { + "id" : "sender", + "label" : "Sender", + "optional" : false, + "constraints" : { + "notEmpty" : true + }, + "feel" : "optional", + "group" : "properties", + "binding" : { + "name" : "sender", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "messagesPerMinute", + "label" : "Message per minute", + "optional" : false, + "feel" : "optional", + "group" : "properties", + "binding" : { + "name" : "messagesPerMinute", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "activationCondition", + "label" : "Activation condition", + "description" : "Condition under which the Connector triggers. Leave empty to catch all events", + "optional" : true, + "feel" : "required", + "group" : "activation", + "binding" : { + "name" : "activationCondition", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "correlationRequired", + "label" : "Subprocess correlation required", + "description" : "Indicates whether correlation is required. This is needed for event-based subprocess message start events", + "value" : "notRequired", + "group" : "correlation", + "binding" : { + "name" : "correlationRequired", + "type" : "zeebe:property" + }, + "type" : "Dropdown", + "choices" : [ { + "name" : "Correlation not required", + "value" : "notRequired" + }, { + "name" : "Correlation required", + "value" : "required" + } ] + }, { + "id" : "correlationKeyProcess", + "label" : "Correlation key (process)", + "description" : "Sets up the correlation key from process variables", + "constraints" : { + "notEmpty" : true + }, + "feel" : "required", + "group" : "correlation", + "binding" : { + "name" : "correlationKey", + "type" : "bpmn:Message#zeebe:subscription#property" + }, + "condition" : { + "property" : "correlationRequired", + "equals" : "required", + "type" : "simple" + }, + "type" : "String" + }, { + "id" : "correlationKeyPayload", + "label" : "Correlation key (payload)", + "description" : "Extracts the correlation key from the incoming message payload", + "constraints" : { + "notEmpty" : true + }, + "feel" : "required", + "group" : "correlation", + "binding" : { + "name" : "correlationKeyExpression", + "type" : "zeebe:property" + }, + "condition" : { + "property" : "correlationRequired", + "equals" : "required", + "type" : "simple" + }, + "type" : "String" + }, { + "id" : "messageTtl", + "label" : "Message TTL", + "description" : "Time-to-live for the message in the broker (ISO-8601 duration)", + "optional" : true, + "constraints" : { + "notEmpty" : false, + "pattern" : { + "value" : "^(PT.*|)$", + "message" : "must be an ISO-8601 duration" + } + }, + "feel" : "optional", + "group" : "correlation", + "binding" : { + "name" : "messageTtl", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "messageIdExpression", + "label" : "Message ID expression", + "description" : "Expression to extract unique identifier of a message", + "optional" : true, + "feel" : "required", + "group" : "correlation", + "binding" : { + "name" : "messageIdExpression", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "messageNameUuid", + "generatedValue" : { + "type" : "uuid" + }, + "group" : "correlation", + "binding" : { + "name" : "name", + "type" : "bpmn:Message#property" + }, + "type" : "Hidden" + }, { + "id" : "resultVariable", + "label" : "Result variable", + "description" : "Name of variable to store the response in", + "group" : "output", + "binding" : { + "name" : "resultVariable", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "resultExpression", + "label" : "Result expression", + "description" : "Expression to map the response into process variables", + "feel" : "required", + "group" : "output", + "binding" : { + "name" : "resultExpression", + "type" : "zeebe:property" + }, + "type" : "Text" + } ], + "icon" : { + "contents" : "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTgiIHdpZHRoPSIxOCIgdmlld0JveD0iMCAwIDEwIDEwIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+PHRpdGxlPlNsYWNrPC90aXRsZT48ZyBmaWxsPSJub25lIj48cGF0aCBkPSJNMCwwIEwwLDEwIEwxMCwxMCBMMTAsMCB6IiBmaWxsPSIjZWNiMTJmIi8+PC9nPjwvc3ZnPg==" + } +} \ No newline at end of file diff --git a/element-templates/template-connector-start-event.json b/element-templates/template-connector-start-event.json new file mode 100644 index 0000000..53603d2 --- /dev/null +++ b/element-templates/template-connector-start-event.json @@ -0,0 +1,98 @@ +{ + "$schema" : "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json", + "name" : "Template connector (Start Event)", + "id" : "io.camunda.connector.Template.v1:StartEvent", + "description" : "Describe this connector", + "metadata" : { + "keywords" : [ ] + }, + "documentationRef" : "https://docs.camunda.io/docs/components/connectors/out-of-the-box-connectors/available-connectors-overview/", + "version" : 1, + "category" : { + "id" : "connectors", + "name" : "Connectors" + }, + "appliesTo" : [ "bpmn:StartEvent" ], + "elementType" : { + "value" : "bpmn:StartEvent" + }, + "groups" : [ { + "id" : "properties", + "label" : "Properties" + }, { + "id" : "activation", + "label" : "Activation" + }, { + "id" : "output", + "label" : "Output mapping" + } ], + "properties" : [ { + "value" : "io.camunda:my-inbound-connector:1", + "binding" : { + "name" : "inbound.type", + "type" : "zeebe:property" + }, + "type" : "Hidden" + }, { + "id" : "sender", + "label" : "Sender", + "optional" : false, + "constraints" : { + "notEmpty" : true + }, + "feel" : "optional", + "group" : "properties", + "binding" : { + "name" : "sender", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "messagesPerMinute", + "label" : "Message per minute", + "optional" : false, + "feel" : "optional", + "group" : "properties", + "binding" : { + "name" : "messagesPerMinute", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "activationCondition", + "label" : "Activation condition", + "description" : "Condition under which the Connector triggers. Leave empty to catch all events", + "optional" : true, + "feel" : "required", + "group" : "activation", + "binding" : { + "name" : "activationCondition", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "resultVariable", + "label" : "Result variable", + "description" : "Name of variable to store the response in", + "group" : "output", + "binding" : { + "name" : "resultVariable", + "type" : "zeebe:property" + }, + "type" : "String" + }, { + "id" : "resultExpression", + "label" : "Result expression", + "description" : "Expression to map the response into process variables", + "feel" : "required", + "group" : "output", + "binding" : { + "name" : "resultExpression", + "type" : "zeebe:property" + }, + "type" : "Text" + } ], + "icon" : { + "contents" : "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTgiIHdpZHRoPSIxOCIgdmlld0JveD0iMCAwIDEwIDEwIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+PHRpdGxlPlNsYWNrPC90aXRsZT48ZyBmaWxsPSJub25lIj48cGF0aCBkPSJNMCwwIEwwLDEwIEwxMCwxMCBMMTAsMCB6IiBmaWxsPSIjZWNiMTJmIi8+PC9nPjwvc3ZnPg==" + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8596411..937a490 100644 --- a/pom.xml +++ b/pom.xml @@ -1,258 +1,153 @@ - - 4.0.0 - - connector-template-inbound - Camunda Inbound Connector Template - io.camunda.connector - connector-template-inbound - jar - 0.1.0-SNAPSHOT - - - 21 - UTF-8 - UTF-8 - - - 8.5.8 - - - 3.27.0 - 5.11.4 - 5.14.2 - 2.0.16 - 2.18.2 - - - 3.4.0 - 3.13.0 - 3.8.1 - 3.1.3 - 3.4.2 - 3.3.1 - 3.6.0 - 3.5.2 - - - - - io.camunda.connector - connector-core - ${version.connectors} - provided - - - io.camunda.connector - connector-validation - ${version.connectors} - provided - - - org.slf4j - slf4j-api - ${version.slf4j} - - - - com.fasterxml.jackson.core - jackson-annotations - ${version.jackson} - - - com.fasterxml.jackson.core - jackson-core - ${version.jackson} - - - com.fasterxml.jackson.core - jackson-databind - ${version.jackson} - - - com.fasterxml.jackson.datatype - jackson-datatype-jdk8 - ${version.jackson} - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - ${version.jackson} - - - com.fasterxml.jackson.module - jackson-module-parameter-names - ${version.jackson} - - - - - org.junit.jupiter - junit-jupiter - ${version.junit-jupiter} - test - - - - org.mockito - mockito-junit-jupiter - ${version.mockito} - test - - - - org.assertj - assertj-core - ${version.assertj} - test - - - - org.slf4j - slf4j-jdk14 - ${version.slf4j} - test - - - - - io.camunda.connector - spring-boot-starter-camunda-connectors - ${version.connectors} - test - - - ch.qos.logback - logback-classic - - - - - - - - - - org.apache.maven.plugins - maven-clean-plugin - ${plugin.version.maven-clean-plugin} - - - org.apache.maven.plugins - maven-dependency-plugin - ${plugin.version.maven-dependency-plugin} - - - org.apache.maven.plugins - maven-resources-plugin - ${plugin.version.maven-resources-plugin} - - - org.apache.maven.plugins - maven-compiler-plugin - ${plugin.version.maven-compiler-plugin} - - - org.apache.maven.plugins - maven-jar-plugin - ${plugin.version.maven-jar-plugin} - - false - - - - org.apache.maven.plugins - maven-install-plugin - ${plugin.version.maven-install-plugin} - - - org.apache.maven.plugins - maven-shade-plugin - ${plugin.version.maven-shade-plugin} - - true - with-dependencies - - false - - - *:* - - module-info.class - META-INF/MANIFEST.MF - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - - - - - false - - - - - - - - - package - - shade - - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${plugin.version.maven-surefire-plugin} - - - - - - - org.apache.maven.plugins - maven-shade-plugin - - - - - - - - true - - - false - - connectors - Connectors Repository - https://artifacts.camunda.com/artifactory/connectors/ - - - - - false - - - true - - connectors-snapshots - Connectors Snapshot Repository - https://artifacts.camunda.com/artifactory/connectors-snapshots/ - - + + 4.0.0 + + connector-template-inbound + Camunda Inbound Connector Template + io.camunda.connector + connector-template-inbound + jar + 0.1.0-SNAPSHOT + + + 21 + UTF-8 + UTF-8 + 8.7.0-SNAPSHOT + 3.25.3 + 5.10.2 + 5.11.0 + + + + + io.camunda.connector + connector-core + ${version.connectors} + provided + + + + + io.camunda.connector + element-template-generator-core + ${version.connectors} + + + + + io.camunda.connector + connector-test + ${version.connectors} + test + + + + org.junit.jupiter + junit-jupiter + ${version.junit-jupiter} + test + + + + org.mockito + mockito-junit-jupiter + ${version.mockito} + test + + + + org.assertj + assertj-core + ${version.assertj} + test + + + + + io.camunda.connector + spring-boot-starter-camunda-connectors + ${version.connectors} + test + + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + + io.camunda.connector + element-template-generator-maven-plugin + ${version.connectors} + + + package + + generate-templates + + + + + + + io.camunda.connector.inbound.MyConnectorExecutable + + + io.camunda.connectors.inbound.EmailMessageStartEvent.v1 + email-inbound-connector-start-event.json + + + io.camunda.connectors.inbound.EmailIntermediate.v1 + email-inbound-connector-intermediate.json + + + io.camunda.connectors.inbound.EmailBoundary.v1 + email-inbound-connector-boundary.json + + + + + + + + + + + + + + true + + + false + + connectors + Connectors Repository + https://artifacts.camunda.com/artifactory/connectors/ + + + + false + + + true + + connectors-snapshots + Connectors Snapshot Repository + https://artifacts.camunda.com/artifactory/connectors-snapshots/ + + diff --git a/src/main/java/io/camunda/connector/inbound/MyConnectorExecutable.java b/src/main/java/io/camunda/connector/inbound/MyConnectorExecutable.java index cfa54e3..e200f71 100644 --- a/src/main/java/io/camunda/connector/inbound/MyConnectorExecutable.java +++ b/src/main/java/io/camunda/connector/inbound/MyConnectorExecutable.java @@ -3,10 +3,22 @@ import io.camunda.connector.api.annotation.InboundConnector; import io.camunda.connector.api.inbound.InboundConnectorContext; import io.camunda.connector.api.inbound.InboundConnectorExecutable; +import io.camunda.connector.generator.java.annotation.ElementTemplate; import io.camunda.connector.inbound.subscription.MockSubscription; import io.camunda.connector.inbound.subscription.MockSubscriptionEvent; @InboundConnector(name = "My Inbound Connector", type = "io.camunda:my-inbound-connector:1") +@ElementTemplate( + id = "io.camunda.connector.Template.v1", + name = "Template connector", + version = 1, + description = "Describe this connector", + icon = "icon.svg", + documentationRef = "https://docs.camunda.io/docs/components/connectors/out-of-the-box-connectors/available-connectors-overview/", + propertyGroups = { + @ElementTemplate.PropertyGroup(id = "properties", label = "Properties"), + }, + inputDataClass = MyConnectorProperties.class) public class MyConnectorExecutable implements InboundConnectorExecutable { private MockSubscription subscription; @@ -21,7 +33,7 @@ public void activate(InboundConnectorContext connectorContext) { } private void onEvent(MockSubscriptionEvent rawEvent) { - context.correlate(new MyConnectorEvent(rawEvent)); + context.correlateWithResult(new MyConnectorEvent(rawEvent)); } @Override diff --git a/src/main/java/io/camunda/connector/inbound/MyConnectorProperties.java b/src/main/java/io/camunda/connector/inbound/MyConnectorProperties.java index dea0314..3e20250 100644 --- a/src/main/java/io/camunda/connector/inbound/MyConnectorProperties.java +++ b/src/main/java/io/camunda/connector/inbound/MyConnectorProperties.java @@ -1,5 +1,7 @@ package io.camunda.connector.inbound; +import io.camunda.connector.generator.dsl.Property; +import io.camunda.connector.generator.java.annotation.TemplateProperty; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotNull; @@ -11,6 +13,19 @@ * @param messagesPerMinute */ public record MyConnectorProperties( - @NotNull String sender, + @NotNull + @TemplateProperty( + id = "sender", + label = "Sender", + group = "properties", + binding = @TemplateProperty.PropertyBinding(name = "sender"), + feel = Property.FeelMode.optional) + String sender, + @TemplateProperty( + id = "messagesPerMinute", + label = "Message per minute", + group = "properties", + binding = @TemplateProperty.PropertyBinding(name = "messagesPerMinute"), + feel = Property.FeelMode.optional) @Max(10) @Min(1) int messagesPerMinute ) {} diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 6a47812..98b2b70 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -1,23 +1,3 @@ -# Configuration for running connectors locally in bundle with connector-runtime server.port=9898 -zeebe.client.broker.gateway-address=localhost:26500 -zeebe.client.security.plaintext=true - -camunda.connector.polling.enabled=true -camunda.connector.polling.interval=5000 - -operate.client.enabled=true - -# Configuration for Operate Keycloak auth (for use with docker-compose.yml) - -camunda.operate.client.url=http://localhost:8081 -camunda.operate.client.keycloak-url=http://localhost:18080 -camunda.operate.client.client-id=connectors -camunda.operate.client.client-secret=c0nn3ct0rsAr3Aw3s0me -camunda.operate.client.keycloak-realm=camunda-platform - -# Configuration for Operate basic auth (for use with docker-compose-core.yml, no keycloak) - -#camunda.operate.client.url=http://localhost:8081 -#camunda.operate.client.username=demo -#camunda.operate.client.password=demo +camunda.client.zeebe.grpc-address=http://localhost:26500 +camunda.client.zeebe.rest-address=http://localhost:8088 \ No newline at end of file diff --git a/src/test/resources/icon.svg b/src/test/resources/icon.svg new file mode 100644 index 0000000..736934a --- /dev/null +++ b/src/test/resources/icon.svg @@ -0,0 +1 @@ +Slack \ No newline at end of file