diff --git a/core/src/main/java/io/camunda/connector/api/inbound/InboundConnectorContext.java b/core/src/main/java/io/camunda/connector/api/inbound/InboundConnectorContext.java index 6057750beb..8d3054b075 100644 --- a/core/src/main/java/io/camunda/connector/api/inbound/InboundConnectorContext.java +++ b/core/src/main/java/io/camunda/connector/api/inbound/InboundConnectorContext.java @@ -16,6 +16,8 @@ */ package io.camunda.connector.api.inbound; +import java.util.Map; + /** * The context object provided to an inbound connector function. The context allows to fetch * information injected by the environment runtime. @@ -35,4 +37,14 @@ public interface InboundConnectorContext { * @param input - the object to validate */ void validate(Object input); + + /** + * Correlates the inbound event to the matching process definition + * + * @param correlationPoint - information about the target process + * @param variables - variables to be passed to the process + * @return + */ + InboundConnectorResult correlate( + ProcessCorrelationPoint correlationPoint, Map variables); } diff --git a/core/src/main/java/io/camunda/connector/api/inbound/InboundConnectorProperties.java b/core/src/main/java/io/camunda/connector/api/inbound/InboundConnectorProperties.java new file mode 100644 index 0000000000..b93b9b2ac6 --- /dev/null +++ b/core/src/main/java/io/camunda/connector/api/inbound/InboundConnectorProperties.java @@ -0,0 +1,115 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.camunda.connector.api.inbound; + +import java.util.Map; +import java.util.Objects; + +public class InboundConnectorProperties { + + public static String TYPE_WEBHOOK = "webhook"; + + private final String type; + private final Map properties; + + private final ProcessCorrelationPoint correlationPoint; + + private final String bpmnProcessId; + private final int version; + private final long processDefinitionKey; + + public InboundConnectorProperties( + ProcessCorrelationPoint correlationPoint, + Map properties, + String bpmnProcessId, + int version, + long processDefinitionKey) { + this.type = properties.get("inbound.type"); + this.properties = properties; + this.correlationPoint = correlationPoint; + this.bpmnProcessId = bpmnProcessId; + this.version = version; + this.processDefinitionKey = processDefinitionKey; + } + + public String getType() { + return type; + } + + public Map getProperties() { + return properties; + } + + public ProcessCorrelationPoint getCorrelationPoint() { + return correlationPoint; + } + + public String getBpmnProcessId() { + return bpmnProcessId; + } + + public int getVersion() { + return version; + } + + public long getProcessDefinitionKey() { + return processDefinitionKey; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InboundConnectorProperties that = (InboundConnectorProperties) o; + return version == that.version + && processDefinitionKey == that.processDefinitionKey + && Objects.equals(type, that.type) + && Objects.equals(properties, that.properties) + && Objects.equals(correlationPoint, that.correlationPoint) + && Objects.equals(bpmnProcessId, that.bpmnProcessId); + } + + @Override + public int hashCode() { + return Objects.hash( + type, properties, correlationPoint, bpmnProcessId, version, processDefinitionKey); + } + + @Override + public String toString() { + return "InboundConnectorProperties{" + + "type='" + + type + + '\'' + + ", properties=" + + properties + + ", correlationPoint=" + + correlationPoint + + ", bpmnProcessId='" + + bpmnProcessId + + '\'' + + ", version=" + + version + + ", processDefinitionKey=" + + processDefinitionKey + + '}'; + } +} diff --git a/core/src/main/java/io/camunda/connector/api/inbound/InboundConnectorResult.java b/core/src/main/java/io/camunda/connector/api/inbound/InboundConnectorResult.java new file mode 100644 index 0000000000..48248898e2 --- /dev/null +++ b/core/src/main/java/io/camunda/connector/api/inbound/InboundConnectorResult.java @@ -0,0 +1,87 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.camunda.connector.api.inbound; + +import java.util.Objects; + +/** + * Contains general information about the inbound correlation results. + * + *

This information is specific to the process correlation point type, e.g. subscription key & + * message name in case of an IntermediateEvent target, or process definition key in case of a + * StartEvent target. + */ +public abstract class InboundConnectorResult { + + protected String type; + protected String id; + protected Object responseData; + + protected InboundConnectorResult(String type, String id, Object responseData) { + this.type = type; + this.id = id; + this.responseData = responseData; + } + + /** Type of process correlation point, e.g. StartEvent or Message */ + public String getType() { + return type; + } + + /** ID of a process correlation point (unique within its type, see {@link #getType()} */ + public String getId() { + return id; + } + + /** Additional information related to Inbound Connector correlation result */ + public Object getResponseData() { + return this.responseData; + } + + @Override + public String toString() { + return "InboundConnectorResult{" + + "type='" + + type + + '\'' + + ", id='" + + id + + '\'' + + ", responseData=" + + responseData + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InboundConnectorResult result = (InboundConnectorResult) o; + return Objects.equals(type, result.type) + && Objects.equals(id, result.id) + && Objects.equals(responseData, result.responseData); + } + + @Override + public int hashCode() { + return Objects.hash(type, id, responseData); + } +} diff --git a/runtime-util/src/test/java/io/camunda/connector/runtime/util/inbound/InboundJobHandlerContextTest.java b/core/src/main/java/io/camunda/connector/api/inbound/ProcessCorrelationPoint.java similarity index 65% rename from runtime-util/src/test/java/io/camunda/connector/runtime/util/inbound/InboundJobHandlerContextTest.java rename to core/src/main/java/io/camunda/connector/api/inbound/ProcessCorrelationPoint.java index 948b6f25dc..0842131b3a 100644 --- a/runtime-util/src/test/java/io/camunda/connector/runtime/util/inbound/InboundJobHandlerContextTest.java +++ b/core/src/main/java/io/camunda/connector/api/inbound/ProcessCorrelationPoint.java @@ -14,18 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.camunda.connector.runtime.util.inbound; +package io.camunda.connector.api.inbound; -import static org.junit.jupiter.api.Assertions.assertThrowsExactly; - -import org.junit.jupiter.api.Test; - -class InboundJobHandlerContextTest { - - private InboundJobHandlerContext testObject; - - @Test - void shouldFailConstructor_WhenNullSecretProvider() { - assertThrowsExactly(RuntimeException.class, () -> new InboundJobHandlerContext(null)); - } -} +/** + * Base class for a unique set of properties of a single inbound Connector usage in the business + * process definition. + * + *

Comparable interface defines the priorities among inbound connector execution (suitable + * inbound candidates are executed in the natural order). + */ +public abstract class ProcessCorrelationPoint implements Comparable {} diff --git a/core/src/main/java/io/camunda/connector/impl/inbound/MessageCorrelationPoint.java b/core/src/main/java/io/camunda/connector/impl/inbound/MessageCorrelationPoint.java new file mode 100644 index 0000000000..328c32f68c --- /dev/null +++ b/core/src/main/java/io/camunda/connector/impl/inbound/MessageCorrelationPoint.java @@ -0,0 +1,70 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.camunda.connector.impl.inbound; + +import io.camunda.connector.api.inbound.ProcessCorrelationPoint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** Properties of a message published by an Inbound Connector */ +public class MessageCorrelationPoint extends ProcessCorrelationPoint { + + public static final String TYPE_NAME = "MESSAGE"; + + private static final Logger LOG = LoggerFactory.getLogger(MessageCorrelationPoint.class); + private final String messageName; + + /** FEEL expression */ + private final String correlationKeyExpression; + + public MessageCorrelationPoint(String messageName, String correlationKeyExpression) { + this.messageName = messageName; + this.correlationKeyExpression = correlationKeyExpression; + LOG.debug("Created inbound correlation point: " + this); + } + + public String getMessageName() { + return messageName; + } + + public String getCorrelationKeyExpression() { + return correlationKeyExpression; + } + + @Override + public String toString() { + return "MessageCorrelationPoint{" + + "messageName='" + + messageName + + '\'' + + ", correlationKeyMapping='" + + correlationKeyExpression + + '}'; + } + + @Override + public int compareTo(ProcessCorrelationPoint o) { + if (!this.getClass().equals(o.getClass())) { + return 1; + } + MessageCorrelationPoint other = (MessageCorrelationPoint) o; + if (!messageName.equals(other.messageName)) { + return messageName.compareTo(other.messageName); + } + return correlationKeyExpression.compareTo(other.correlationKeyExpression); + } +} diff --git a/core/src/main/java/io/camunda/connector/impl/inbound/StartEventCorrelationPoint.java b/core/src/main/java/io/camunda/connector/impl/inbound/StartEventCorrelationPoint.java new file mode 100644 index 0000000000..50984ec03d --- /dev/null +++ b/core/src/main/java/io/camunda/connector/impl/inbound/StartEventCorrelationPoint.java @@ -0,0 +1,77 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.camunda.connector.impl.inbound; + +import io.camunda.connector.api.inbound.ProcessCorrelationPoint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** Properties of a StartEvent triggered by an Inbound Connector */ +public class StartEventCorrelationPoint extends ProcessCorrelationPoint { + + public static final String TYPE_NAME = "START_EVENT"; + + private final String bpmnProcessId; + private final int version; + private final long processDefinitionKey; + + private static final Logger LOG = LoggerFactory.getLogger(StartEventCorrelationPoint.class); + + public StartEventCorrelationPoint(long processDefinitionKey, String bpmnProcessId, int version) { + this.bpmnProcessId = bpmnProcessId; + this.version = version; + this.processDefinitionKey = processDefinitionKey; + LOG.debug("Created inbound correlation point: " + this); + } + + public String getBpmnProcessId() { + return bpmnProcessId; + } + + public int getVersion() { + return version; + } + + public long getProcessDefinitionKey() { + return processDefinitionKey; + } + + @Override + public String toString() { + return "StartEventCorrelationPoint{" + + "processDefinitionKey=" + + processDefinitionKey + + ", bpmnProcessId='" + + bpmnProcessId + + '\'' + + ", version=" + + version + + '}'; + } + + @Override + public int compareTo(ProcessCorrelationPoint o) { + if (!this.getClass().equals(o.getClass())) { + return -1; + } + StartEventCorrelationPoint other = (StartEventCorrelationPoint) o; + if (!bpmnProcessId.equals(other.bpmnProcessId)) { + return bpmnProcessId.compareTo(other.bpmnProcessId); + } + return Integer.compare(version, other.version); + } +} diff --git a/core/src/main/java/io/camunda/connector/test/inbound/InboundConnectorContextBuilder.java b/core/src/main/java/io/camunda/connector/test/inbound/InboundConnectorContextBuilder.java deleted file mode 100644 index ec49fb4e98..0000000000 --- a/core/src/main/java/io/camunda/connector/test/inbound/InboundConnectorContextBuilder.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH - * under one or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information regarding copyright - * ownership. Camunda licenses this file to you under the Apache License, - * Version 2.0; you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.camunda.connector.test.inbound; - -import io.camunda.connector.api.inbound.InboundConnectorContext; -import io.camunda.connector.api.secret.SecretProvider; -import io.camunda.connector.impl.context.AbstractConnectorContext; -import java.util.HashMap; -import java.util.Map; - -public class InboundConnectorContextBuilder { - protected final Map secrets = new HashMap<>(); - protected SecretProvider secretProvider = secrets::get; - - public static InboundConnectorContextBuilder create() { - return new InboundConnectorContextBuilder(); - } - - /** - * Provides the secret's value for the given name. - * - * @param name - the secret's name, e.g. MY_SECRET when referred to as "secrets.MY_SECRET" - * @param value - the secret's value - * @return builder for fluent API - */ - public InboundConnectorContextBuilder secret(String name, String value) { - secrets.put(name, value); - return this; - } - - /** - * Provides the secret values via the defined {@link SecretProvider}. - * - * @param secretProvider - provider for secret values, given a secret name - * @return builder for fluent API - */ - public InboundConnectorContextBuilder secrets(SecretProvider secretProvider) { - this.secretProvider = secretProvider; - return this; - } - - /** - * @return the {@link io.camunda.connector.api.inbound.InboundConnectorContext} including all - * previously defined properties - */ - public InboundConnectorContextBuilder.TestInboundConnectorContext build() { - return new InboundConnectorContextBuilder.TestInboundConnectorContext(secretProvider); - } - - public class TestInboundConnectorContext extends AbstractConnectorContext - implements InboundConnectorContext { - - protected TestInboundConnectorContext(SecretProvider secretProvider) { - super(secretProvider); - } - } -} diff --git a/core/src/test/java/io/camunda/connector/impl/inbound/ProcessCorrelationPointTest.java b/core/src/test/java/io/camunda/connector/impl/inbound/ProcessCorrelationPointTest.java new file mode 100644 index 0000000000..45f3be0ed1 --- /dev/null +++ b/core/src/test/java/io/camunda/connector/impl/inbound/ProcessCorrelationPointTest.java @@ -0,0 +1,53 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.camunda.connector.impl.inbound; + +import io.camunda.connector.api.inbound.ProcessCorrelationPoint; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ProcessCorrelationPointTest { + + @Test + void shouldBeSortableByProcessVersion() { + // given + ProcessCorrelationPoint p1 = new StartEventCorrelationPoint(0, "process1", 0); + ProcessCorrelationPoint p2 = new StartEventCorrelationPoint(2, "process1", 1); + ProcessCorrelationPoint p3 = new StartEventCorrelationPoint(1, "process2", 0); + ProcessCorrelationPoint p4 = new MessageCorrelationPoint("jobCompleted", "=key"); + ProcessCorrelationPoint p5 = new MessageCorrelationPoint("jobCompleted1", "=key"); + ProcessCorrelationPoint p6 = new MessageCorrelationPoint("jobCompleted1", "=key1"); + + // when + List sortedPoints = List.of(p6, p5, p1, p2, p3, p4); + sortedPoints = sortedPoints.stream().sorted().collect(Collectors.toList()); + + // then + Iterator iter = sortedPoints.iterator(); + // points are sorted in the expected order + Assertions.assertThat(iter.next()).isSameAs(p1); + Assertions.assertThat(iter.next()).isSameAs(p2); + Assertions.assertThat(iter.next()).isSameAs(p3); + Assertions.assertThat(iter.next()).isSameAs(p4); + Assertions.assertThat(iter.next()).isSameAs(p5); + Assertions.assertThat(iter.next()).isSameAs(p6); + Assertions.assertThat(iter.hasNext()).isFalse(); + } +} diff --git a/runtime-util/src/main/java/io/camunda/connector/runtime/util/inbound/InboundJobHandlerContext.java b/runtime-util/src/main/java/io/camunda/connector/runtime/util/inbound/InboundJobHandlerContext.java deleted file mode 100644 index ccd2d9148f..0000000000 --- a/runtime-util/src/main/java/io/camunda/connector/runtime/util/inbound/InboundJobHandlerContext.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH - * under one or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information regarding copyright - * ownership. Camunda licenses this file to you under the Apache License, - * Version 2.0; you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.camunda.connector.runtime.util.inbound; - -import io.camunda.connector.api.inbound.InboundConnectorContext; -import io.camunda.connector.api.secret.SecretProvider; -import io.camunda.connector.impl.context.AbstractConnectorContext; - -/** Implementation of {@link io.camunda.connector.api.inbound.InboundConnectorContext} */ -public class InboundJobHandlerContext extends AbstractConnectorContext - implements InboundConnectorContext { - - public InboundJobHandlerContext(final SecretProvider secretProvider) { - super(secretProvider); - } -}