diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml index c5e11e83c5c63..8cfe8024e9098 100644 --- a/bom/camel-bom/pom.xml +++ b/bom/camel-bom/pom.xml @@ -797,6 +797,11 @@ camel-flink 4.9.0-SNAPSHOT + + org.apache.camel + camel-flowable + 4.9.0-SNAPSHOT + org.apache.camel camel-fop diff --git a/catalog/camel-allcomponents/pom.xml b/catalog/camel-allcomponents/pom.xml index fcb5049fc8b7b..1be613cbc73a4 100644 --- a/catalog/camel-allcomponents/pom.xml +++ b/catalog/camel-allcomponents/pom.xml @@ -671,6 +671,11 @@ camel-flink ${project.version} + + org.apache.camel + camel-flowable + ${project.version} + org.apache.camel camel-fop diff --git a/components/camel-flowable/pom.xml b/components/camel-flowable/pom.xml new file mode 100644 index 0000000000000..8e15ca6d806c4 --- /dev/null +++ b/components/camel-flowable/pom.xml @@ -0,0 +1,110 @@ + + + + + 4.0.0 + + + org.apache.camel + components + 4.9.0-SNAPSHOT + + + camel-flowable + jar + Camel :: Flowable + Camel Flowable support + + + UTF-8 + UTF-8 + + + + + org.apache.camel + camel-core + + + org.apache.camel + camel-spring + + + + + org.apache.camel + camel-test-spring-junit5 + test + + + + + org.flowable + flowable-engine + ${flowable-version} + + + org.flowable + flowable-spring + ${flowable-version} + + + org.flowable + flowable-event-registry-spring + ${flowable-version} + + + org.apache.logging.log4j + log4j-slf4j-impl + ${log4j2-version} + test + + + org.springframework + spring-test + provided + ${spring-version} + + + org.springframework + spring-jdbc + provided + ${spring-version} + + + com.zaxxer + HikariCP + test + ${hikari-version} + + + com.h2database + h2 + test + ${h2-version} + + + junit + junit + test + ${junit-version} + + + diff --git a/components/camel-flowable/src/generated/resources/META-INF/services/org/apache/camel/component.properties b/components/camel-flowable/src/generated/resources/META-INF/services/org/apache/camel/component.properties new file mode 100644 index 0000000000000..9b4c23e637471 --- /dev/null +++ b/components/camel-flowable/src/generated/resources/META-INF/services/org/apache/camel/component.properties @@ -0,0 +1,7 @@ +# Generated by camel build tools - do NOT edit this file! +components=flowable +groupId=org.apache.camel +artifactId=camel-flowable +version=4.9.0-SNAPSHOT +projectName=Camel :: Flowable +projectDescription=Camel Flowable support diff --git a/components/camel-flowable/src/generated/resources/META-INF/services/org/apache/camel/component/flowable b/components/camel-flowable/src/generated/resources/META-INF/services/org/apache/camel/component/flowable new file mode 100644 index 0000000000000..e7e59e963fad9 --- /dev/null +++ b/components/camel-flowable/src/generated/resources/META-INF/services/org/apache/camel/component/flowable @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.component.flowable.FlowableComponent diff --git a/components/camel-flowable/src/main/docs/flowable-component.adoc b/components/camel-flowable/src/main/docs/flowable-component.adoc new file mode 100644 index 0000000000000..c01bf35c70d75 --- /dev/null +++ b/components/camel-flowable/src/main/docs/flowable-component.adoc @@ -0,0 +1,71 @@ += Flowable Component +:doctitle: Flowable +:shortname: flowable +:artifactid: camel-flowable +:description: Communicate with the Flowable Event Registry for sending and receiving messages from the Flowable BPMN and CMMN engines. +:since: 4.9.0 +:supportlevel: Stable +:tabs-sync-option: +:component-header: Both producer and consumer are supported +//Manually maintained attributes + +*Since Camel {since}* + +*{component-header}* + +Communicate with the Flowable Event Registry for sending and receiving messages from the Flowable BPMN and CMMN engines. + +== URI format + +------------------------------ +flowable-event://[channelKey]?[options] +------------------------------ + +Where *channelKey* is the unique key value of the channel model deployed in the Flowable Event Registry. + +// component-configure options: START + +// component-configure options: END + +// component options: START +include::partial$component-configure-options.adoc[] +include::partial$component-endpoint-options.adoc[] +// component options: END + +// endpoint options: START + +// endpoint options: END + +== Usage + +=== Body content + +The body content is defined by the event model that is deployed to the Flowable Event Registry. +The event message can then be mapped to process or case variables in the process BPMN or case CMMN model. + +== Examples + +The following example sends an event to the Flowable event registry for further processing: + +[source,java] +---------------------------------------------------------------------- +from("direct:start").to("flowable:exampleChannel"); +---------------------------------------------------------------------- + +== Dependencies + +To use Flowable in your Camel routes, you need to add a dependency on +*camel-flowable*, which implements the component. + +If you use Maven, you can add the following to your pom.xml, +substituting the version number for the latest and greatest release (see +the download page for the latest versions). + +[source,xml] +------------------------------------- + + org.apache.camel + camel-flowable + x.x.x + +------------------------------------- diff --git a/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/CamelChannelModelProcessor.java b/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/CamelChannelModelProcessor.java new file mode 100644 index 0000000000000..4844d583ec2f5 --- /dev/null +++ b/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/CamelChannelModelProcessor.java @@ -0,0 +1,181 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); 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 org.apache.camel.component.flowable; + +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.commons.lang3.StringUtils; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.eventregistry.api.ChannelModelProcessor; +import org.flowable.eventregistry.api.EventRegistry; +import org.flowable.eventregistry.api.EventRepositoryService; +import org.flowable.eventregistry.api.OutboundEventChannelAdapter; +import org.flowable.eventregistry.impl.EventRegistryEngineConfiguration; +import org.flowable.eventregistry.model.CamelInboundChannelModel; +import org.flowable.eventregistry.model.CamelOutboundChannelModel; +import org.flowable.eventregistry.model.ChannelModel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.beans.factory.config.EmbeddedValueResolver; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.util.StringValueResolver; + +public class CamelChannelModelProcessor + implements BeanFactoryAware, ApplicationContextAware, ApplicationListener, + ChannelModelProcessor { + + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + protected CamelContext camelContext; + + protected BeanFactory beanFactory; + protected ApplicationContext applicationContext; + protected boolean contextRefreshed; + + protected StringValueResolver embeddedValueResolver; + + public CamelChannelModelProcessor(CamelContext camelContext) { + this.camelContext = camelContext; + } + + @Override + public boolean canProcess(ChannelModel channelModel) { + return channelModel instanceof CamelInboundChannelModel || channelModel instanceof CamelOutboundChannelModel; + } + + @Override + public boolean canProcessIfChannelModelAlreadyRegistered(ChannelModel channelModel) { + return channelModel instanceof CamelOutboundChannelModel; + } + + @Override + public void registerChannelModel( + ChannelModel channelModel, String tenantId, EventRegistry eventRegistry, + EventRepositoryService eventRepositoryService, + boolean fallbackToDefaultTenant) { + + if (channelModel instanceof CamelInboundChannelModel) { + CamelInboundChannelModel camelInboundChannelModel = (CamelInboundChannelModel) channelModel; + logger.info("Starting to register inbound channel {} in tenant {}", channelModel.getKey(), tenantId); + processInboundDefinition(camelInboundChannelModel, tenantId); + logger.info("Finished registering inbound channel {} in tenant {}", channelModel.getKey(), tenantId); + + } else if (channelModel instanceof CamelOutboundChannelModel) { + logger.info("Starting to register outbound channel {} in tenant {}", channelModel.getKey(), tenantId); + processOutboundDefinition((CamelOutboundChannelModel) channelModel, tenantId); + logger.info("Finished registering outbound channel {} in tenant {}", channelModel.getKey(), tenantId); + } + } + + protected void processInboundDefinition(CamelInboundChannelModel channelModel, String tenantId) { + try (FlowableEndpoint endpoint + = new FlowableEndpoint(channelModel, getEventRegistryEngineConfiguration(), camelContext)) { + + camelContext.addEndpoint(endpoint.getEndpointUri(), endpoint); + if (StringUtils.isNotEmpty(channelModel.getSourceUri())) { + camelContext.addRoutes(new RouteBuilder() { + + @Override + public void configure() throws Exception { + from(channelModel.getSourceUri()).routeId(channelModel.getKey()).to(endpoint.getEndpointUri()); + } + }); + } + + } catch (Exception e) { + logger.error("Error creating producer for inbound channel {} in tenant {}", channelModel.getKey(), tenantId); + throw new FlowableException( + "Error creating producer for inbound channel " + channelModel.getKey() + " in tenant " + tenantId); + } + } + + protected void processOutboundDefinition(CamelOutboundChannelModel channelModel, String tenantId) { + String destination = channelModel.getDestination(); + if (channelModel.getOutboundEventChannelAdapter() == null && StringUtils.isNotEmpty(destination)) { + channelModel.setOutboundEventChannelAdapter(createOutboundEventChannelAdapter(channelModel, tenantId)); + } + } + + protected OutboundEventChannelAdapter createOutboundEventChannelAdapter( + CamelOutboundChannelModel channelModel, String tenantId) { + + String destination = resolve(channelModel.getDestination()); + try (FlowableEndpoint endpoint + = new FlowableEndpoint(channelModel, getEventRegistryEngineConfiguration(), camelContext)) { + camelContext.addEndpoint(endpoint.getEndpointUri(), endpoint); + camelContext.addRoutes(new RouteBuilder() { + + @Override + public void configure() throws Exception { + from(endpoint).routeId(channelModel.getKey()).to(destination); + } + }); + + return new CamelOperationsOutboundEventChannelAdapter(endpoint); + + } catch (Exception e) { + logger.error("Error creating route for outbound channel {} in tenant {}", channelModel.getKey(), tenantId); + throw new FlowableException( + "Error creating route for outbound channel " + channelModel.getKey() + " in tenant " + tenantId); + } + } + + @Override + public void unregisterChannelModel( + ChannelModel channelModel, String tenantId, EventRepositoryService eventRepositoryService) { + + } + + protected String resolve(String value) { + if (embeddedValueResolver != null) { + return embeddedValueResolver.resolveStringValue(value); + } else { + return value; + } + } + + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.beanFactory = beanFactory; + if (beanFactory instanceof ConfigurableBeanFactory) { + this.embeddedValueResolver = new EmbeddedValueResolver((ConfigurableBeanFactory) beanFactory); + } + } + + protected EventRegistryEngineConfiguration getEventRegistryEngineConfiguration() { + return applicationContext.getBean(EventRegistryEngineConfiguration.class); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + if (event.getApplicationContext() == this.applicationContext) { + this.contextRefreshed = true; + } + } +} diff --git a/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/CamelOperationsOutboundEventChannelAdapter.java b/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/CamelOperationsOutboundEventChannelAdapter.java new file mode 100644 index 0000000000000..ea117625433ea --- /dev/null +++ b/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/CamelOperationsOutboundEventChannelAdapter.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); 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 org.apache.camel.component.flowable; + +import java.util.Map; + +import org.apache.camel.Exchange; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.eventregistry.api.OutboundEventChannelAdapter; + +public class CamelOperationsOutboundEventChannelAdapter implements OutboundEventChannelAdapter { + + protected FlowableEndpoint endpoint; + + public CamelOperationsOutboundEventChannelAdapter(FlowableEndpoint endpoint) { + this.endpoint = endpoint; + } + + @Override + public void sendEvent(String rawEvent, Map headerMap) { + Exchange exchange = endpoint.createExchange(); + exchange.getIn().setBody(rawEvent); + exchange.getIn().setHeaders(headerMap); + + try { + endpoint.process(exchange); + } catch (Exception e) { + throw new FlowableException("Exception while processing Camel exchange", e); + } + } +} diff --git a/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/FlowableComponent.java b/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/FlowableComponent.java new file mode 100644 index 0000000000000..01f8851a47bb8 --- /dev/null +++ b/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/FlowableComponent.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); 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 org.apache.camel.component.flowable; + +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.Endpoint; +import org.apache.camel.spi.annotations.Component; +import org.apache.camel.support.DefaultComponent; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.common.engine.impl.interceptor.EngineConfigurationConstants; +import org.flowable.engine.ProcessEngine; +import org.flowable.eventregistry.impl.EventRegistryEngineConfiguration; + +@Component("flowable") +public class FlowableComponent extends DefaultComponent { + + protected EventRegistryEngineConfiguration eventRegistryEngineConfiguration; + + public FlowableComponent() { + } + + @Override + public void setCamelContext(CamelContext context) { + super.setCamelContext(context); + ProcessEngine processEngine = getByType(context, ProcessEngine.class); + this.eventRegistryEngineConfiguration = (EventRegistryEngineConfiguration) processEngine.getProcessEngineConfiguration() + .getEngineConfigurations().get(EngineConfigurationConstants.KEY_EVENT_REGISTRY_CONFIG); + } + + private T getByType(CamelContext ctx, Class kls) { + Map looked = ctx.getRegistry().findByTypeWithName(kls); + if (looked.isEmpty()) { + return null; + } + return looked.values().iterator().next(); + + } + + @Override + protected Endpoint createEndpoint(String uri, String remaining, Map parameters) throws Exception { + throw new FlowableException("not supported"); + } +} diff --git a/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/FlowableConsumer.java b/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/FlowableConsumer.java new file mode 100644 index 0000000000000..6260f9a3fc674 --- /dev/null +++ b/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/FlowableConsumer.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); 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 org.apache.camel.component.flowable; + +import org.apache.camel.Processor; +import org.apache.camel.support.DefaultConsumer; + +public class FlowableConsumer extends DefaultConsumer { + + public FlowableConsumer(FlowableEndpoint endpoint, Processor processor) { + super(endpoint, processor); + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + ((FlowableEndpoint) getEndpoint()).addConsumer(this); + } + + @Override + protected void doStop() throws Exception { + super.doStop(); + ((FlowableEndpoint) getEndpoint()).removeConsumer(); + } +} diff --git a/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/FlowableEndpoint.java b/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/FlowableEndpoint.java new file mode 100644 index 0000000000000..9fa411213e0cf --- /dev/null +++ b/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/FlowableEndpoint.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); 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 org.apache.camel.component.flowable; + +import org.apache.camel.CamelContext; +import org.apache.camel.Consumer; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.support.DefaultEndpoint; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.eventregistry.impl.EventRegistryEngineConfiguration; +import org.flowable.eventregistry.model.CamelInboundChannelModel; +import org.flowable.eventregistry.model.CamelOutboundChannelModel; + +public class FlowableEndpoint extends DefaultEndpoint { + + protected EventRegistryEngineConfiguration eventRegistryEngineConfiguration; + + protected FlowableConsumer flowableConsumer; + protected CamelInboundChannelModel camelInboundChannel; + protected CamelOutboundChannelModel camelOutboundChannel; + + public FlowableEndpoint(CamelInboundChannelModel camelInboundChannel, + EventRegistryEngineConfiguration eventRegistryEngineConfiguration, CamelContext camelContext) { + + super(); + setCamelContext(camelContext); + this.camelInboundChannel = camelInboundChannel; + this.eventRegistryEngineConfiguration = eventRegistryEngineConfiguration; + setEndpointUri("flowable:" + camelInboundChannel.getKey()); + } + + public FlowableEndpoint(CamelOutboundChannelModel camelOutboundChannel, + EventRegistryEngineConfiguration eventRegistryEngineConfiguration, CamelContext camelContext) { + + super(); + setCamelContext(camelContext); + this.camelOutboundChannel = camelOutboundChannel; + this.eventRegistryEngineConfiguration = eventRegistryEngineConfiguration; + setEndpointUri("flowable-event:" + camelOutboundChannel.getKey()); + } + + public void process(Exchange ex) throws Exception { + if (flowableConsumer == null) { + throw new FlowableException("Consumer not defined for " + getEndpointUri()); + } + flowableConsumer.getProcessor().process(ex); + } + + @Override + public Producer createProducer() throws Exception { + FlowableProducer producer = new FlowableProducer(camelInboundChannel, this, eventRegistryEngineConfiguration); + return producer; + } + + @Override + public Consumer createConsumer(Processor processor) throws Exception { + return new FlowableConsumer(this, processor); + } + + protected void addConsumer(FlowableConsumer consumer) { + if (flowableConsumer != null) { + throw new FlowableException("Consumer already defined for " + getEndpointUri() + "!"); + } + flowableConsumer = consumer; + } + + protected void removeConsumer() { + flowableConsumer = null; + } + + @Override + public boolean isSingleton() { + return true; + } + + public void setCamelInboundChannel(CamelInboundChannelModel camelInboundChannel) { + this.camelInboundChannel = camelInboundChannel; + } + + public void setCamelOutboundChannel(CamelOutboundChannelModel camelOutboundChannel) { + this.camelOutboundChannel = camelOutboundChannel; + } + + public void setEventRegistryEngineConfiguration(EventRegistryEngineConfiguration eventRegistryEngineConfiguration) { + this.eventRegistryEngineConfiguration = eventRegistryEngineConfiguration; + } +} diff --git a/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/FlowableProducer.java b/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/FlowableProducer.java new file mode 100644 index 0000000000000..d58eff3e8ec91 --- /dev/null +++ b/components/camel-flowable/src/main/java/org/apache/camel/component/flowable/FlowableProducer.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); 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 org.apache.camel.component.flowable; + +import org.apache.camel.Endpoint; +import org.apache.camel.Exchange; +import org.apache.camel.Message; +import org.apache.camel.support.DefaultProducer; +import org.flowable.eventregistry.impl.DefaultInboundEvent; +import org.flowable.eventregistry.impl.EventRegistryEngineConfiguration; +import org.flowable.eventregistry.model.CamelInboundChannelModel; + +public class FlowableProducer extends DefaultProducer { + + protected CamelInboundChannelModel camelInboundChannel; + protected EventRegistryEngineConfiguration eventRegistryEngineConfiguration; + + public FlowableProducer(CamelInboundChannelModel camelInboundChannel, Endpoint endpoint, + EventRegistryEngineConfiguration eventRegistryEngineConfiguration) { + + super(endpoint); + this.camelInboundChannel = camelInboundChannel; + this.eventRegistryEngineConfiguration = eventRegistryEngineConfiguration; + } + + @Override + public void process(Exchange exchange) throws Exception { + Message message = exchange.getMessage(); + DefaultInboundEvent inboundEvent = new DefaultInboundEvent(message.getBody(), message.getHeaders()); + eventRegistryEngineConfiguration.getEventRegistry().eventReceived(camelInboundChannel, inboundEvent); + } +} diff --git a/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/CamelFlowableTestCase.java b/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/CamelFlowableTestCase.java new file mode 100644 index 0000000000000..5d0ef23657e89 --- /dev/null +++ b/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/CamelFlowableTestCase.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); 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 org.apache.camel.component.flowable; + +import java.util.List; + +import org.apache.camel.CamelContext; +import org.apache.camel.Route; +import org.flowable.eventregistry.api.EventDeployment; +import org.flowable.eventregistry.impl.EventRegistryEngineConfiguration; +import org.flowable.spring.impl.test.SpringFlowableTestCase; +import org.junit.jupiter.api.AfterEach; +import org.springframework.beans.factory.annotation.Autowired; + +public abstract class CamelFlowableTestCase extends SpringFlowableTestCase { + + @Autowired + protected EventRegistryEngineConfiguration eventRegistryEngineConfiguration; + + @Autowired + protected CamelContext camelContext; + + @AfterEach + public void tearDown() throws Exception { + List routes = camelContext.getRoutes(); + for (Route r : routes) { + camelContext.getRouteController().stopRoute(r.getId()); + camelContext.removeRoute(r.getId()); + } + + List eventDeployments + = eventRegistryEngineConfiguration.getEventRepositoryService().createDeploymentQuery().list(); + for (EventDeployment eventDeployment : eventDeployments) { + eventRegistryEngineConfiguration.getEventRepositoryService().deleteDeployment(eventDeployment.getId()); + } + } +} diff --git a/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableInboundChannelHeaderTest.java b/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableInboundChannelHeaderTest.java new file mode 100644 index 0000000000000..0e1ba0ec457cb --- /dev/null +++ b/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableInboundChannelHeaderTest.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); 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 org.apache.camel.component.flowable; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.apache.camel.Exchange; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.engine.test.Deployment; +import org.flowable.task.api.Task; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.test.context.ContextConfiguration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@ContextConfiguration("classpath:generic-camel-context.xml") +public class FlowableInboundChannelHeaderTest extends CamelFlowableTestCase { + + @BeforeEach + public void setUp() throws Exception { + eventRegistryEngineConfiguration.getEventRepositoryService().createDeployment() + .addClasspathResource("channel/userHeaderChannel.channel") + .addClasspathResource("event/userWithHeaderEvent.event") + .deploy(); + + camelContext.addRoutes(new RouteBuilder() { + + @Override + public void configure() throws Exception { + from("direct:start").to("flowable:userHeaderChannel"); + } + }); + } + + @Test + @Deployment(resources = { "process/startWithHeader.bpmn20.xml" }) + public void testStartProcessWithHeaderEvent() throws Exception { + ProducerTemplate tpl = camelContext.createProducerTemplate(); + ObjectNode bodyNode = new ObjectMapper().createObjectNode(); + bodyNode.put("name", "John Doe"); + bodyNode.put("age", 23); + Exchange exchange = camelContext.getEndpoint("direct:start").createExchange(); + exchange.getIn().setBody(bodyNode); + exchange.getIn().setHeader("headerProperty1", "headerTestValue"); + exchange.getIn().setHeader("headerProperty2", 99); + tpl.send("direct:start", exchange); + + ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() + .processDefinitionKey("camelProcess") + .singleResult(); + assertNotNull(processInstance); + + assertEquals("John Doe", runtimeService.getVariable(processInstance.getId(), "name")); + assertEquals(23, runtimeService.getVariable(processInstance.getId(), "age")); + assertEquals("headerTestValue", runtimeService.getVariable(processInstance.getId(), "header1")); + assertEquals(99, runtimeService.getVariable(processInstance.getId(), "header2")); + + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + assertNotNull(task); + } +} diff --git a/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableInboundChannelTest.java b/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableInboundChannelTest.java new file mode 100644 index 0000000000000..cdfcb30cde630 --- /dev/null +++ b/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableInboundChannelTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); 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 org.apache.camel.component.flowable; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.apache.camel.Exchange; +import org.apache.camel.ProducerTemplate; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.engine.test.Deployment; +import org.flowable.task.api.Task; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.test.context.ContextConfiguration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@ContextConfiguration("classpath:generic-camel-context.xml") +public class FlowableInboundChannelTest extends CamelFlowableTestCase { + + @BeforeEach + public void setUp() throws Exception { + eventRegistryEngineConfiguration.getEventRepositoryService().createDeployment() + .addClasspathResource("channel/userChannel.channel") + .addClasspathResource("event/userEvent.event") + .deploy(); + } + + @Test + @Deployment(resources = { "process/start.bpmn20.xml" }) + public void testStartProcessWithBasicEvent() throws Exception { + ProducerTemplate tpl = camelContext.createProducerTemplate(); + ObjectNode bodyNode = new ObjectMapper().createObjectNode(); + bodyNode.put("name", "John Doe"); + bodyNode.put("age", 23); + Exchange exchange = camelContext.getEndpoint("direct:start").createExchange(); + exchange.getIn().setBody(bodyNode); + tpl.send("direct:start", exchange); + + ProcessInstance processInstance + = runtimeService.createProcessInstanceQuery().processDefinitionKey("camelProcess").singleResult(); + assertNotNull(processInstance); + + assertEquals("John Doe", runtimeService.getVariable(processInstance.getId(), "name")); + assertEquals(23, runtimeService.getVariable(processInstance.getId(), "age")); + + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + assertNotNull(task); + } +} diff --git a/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableOutboundChannelTest.java b/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableOutboundChannelTest.java new file mode 100644 index 0000000000000..e469c9f9f00f7 --- /dev/null +++ b/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableOutboundChannelTest.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); 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 org.apache.camel.component.flowable; + +import com.fasterxml.jackson.databind.JsonNode; +import org.apache.camel.component.mock.MockEndpoint; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.engine.test.Deployment; +import org.flowable.task.api.Task; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.test.context.ContextConfiguration; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ContextConfiguration("classpath:generic-camel-context.xml") +public class FlowableOutboundChannelTest extends CamelFlowableTestCase { + + @BeforeEach + public void setUp() throws Exception { + eventRegistryEngineConfiguration.getEventRepositoryService().createDeployment() + .addClasspathResource("channel/userOutboundChannel.channel") + .addClasspathResource("event/userEvent.event") + .deploy(); + } + + @Test + @Deployment(resources = { "process/sendEvent.bpmn20.xml" }) + public void testSendBasicEvent() throws Exception { + ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder().processDefinitionKey("camelProcess") + .variable("name", "John Doe") + .variable("age", 23) + .start(); + + assertEquals("John Doe", runtimeService.getVariable(processInstance.getId(), "name")); + assertEquals(23, runtimeService.getVariable(processInstance.getId(), "age")); + + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + taskService.complete(task.getId()); + + MockEndpoint mockEndpoint = (MockEndpoint) camelContext.getEndpoint("mock:testQueue"); + assertEquals(1, mockEndpoint.getExchanges().size()); + String bodyString = mockEndpoint.getExchanges().get(0).getIn().getBody(String.class); + JsonNode bodyNode = processEngineConfiguration.getObjectMapper().readTree(bodyString); + assertEquals("John Doe", bodyNode.get("name").asText()); + assertEquals(23, bodyNode.get("age").asInt()); + } +} diff --git a/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableRedeployChannelTest.java b/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableRedeployChannelTest.java new file mode 100644 index 0000000000000..ad1c2dd64c9d8 --- /dev/null +++ b/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableRedeployChannelTest.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); 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 org.apache.camel.component.flowable; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.apache.camel.Exchange; +import org.apache.camel.ProducerTemplate; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.engine.test.Deployment; +import org.junit.jupiter.api.Test; +import org.springframework.test.context.ContextConfiguration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@ContextConfiguration("classpath:generic-camel-context.xml") +public class FlowableRedeployChannelTest extends CamelFlowableTestCase { + + @Test + @Deployment(resources = { "process/start.bpmn20.xml" }) + public void testUnregisterChannelModel() throws Exception { + eventRegistryEngineConfiguration.getEventRepositoryService().createDeployment() + .addClasspathResource("channel/userChannel.channel") + .addClasspathResource("event/userEvent.event") + .deploy(); + + ProducerTemplate tpl = camelContext.createProducerTemplate(); + ObjectNode bodyNode = new ObjectMapper().createObjectNode(); + bodyNode.put("name", "John Doe"); + bodyNode.put("age", 23); + Exchange exchange = camelContext.getEndpoint("direct:start").createExchange(); + exchange.getIn().setBody(bodyNode); + tpl.send("direct:start", exchange); + + ProcessInstance processInstance + = runtimeService.createProcessInstanceQuery().processDefinitionKey("camelProcess").singleResult(); + assertNotNull(processInstance); + + assertEquals("John Doe", runtimeService.getVariable(processInstance.getId(), "name")); + assertEquals(23, runtimeService.getVariable(processInstance.getId(), "age")); + + eventRegistryEngineConfiguration.getEventRepositoryService().createDeployment() + .addClasspathResource("channel/userChannelUpdated.channel") + .addClasspathResource("event/userEventUpdated.event") + .deploy(); + + bodyNode = new ObjectMapper().createObjectNode(); + bodyNode.put("name", "Jane Doe"); + bodyNode.put("age", 28); + bodyNode.put("address", "Main street 1"); + assertEquals(null, camelContext.hasEndpoint("direct:start")); + + assertEquals(1, runtimeService.createProcessInstanceQuery().processDefinitionKey("camelProcess").count()); + + exchange = camelContext.getEndpoint("direct:startUpdated").createExchange(); + exchange.getIn().setBody(bodyNode); + tpl.send("direct:startUpdated", exchange); + + assertEquals(2, runtimeService.createProcessInstanceQuery().processDefinitionKey("camelProcess").count()); + } +} diff --git a/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableSendAndReceiveChannelTest.java b/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableSendAndReceiveChannelTest.java new file mode 100644 index 0000000000000..d61a0e17f7103 --- /dev/null +++ b/components/camel-flowable/src/test/java/org/apache/camel/component/flowable/FlowableSendAndReceiveChannelTest.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); 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 org.apache.camel.component.flowable; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.apache.camel.Exchange; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.engine.test.Deployment; +import org.flowable.task.api.Task; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.test.context.ContextConfiguration; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ContextConfiguration("classpath:generic-camel-context.xml") +public class FlowableSendAndReceiveChannelTest extends CamelFlowableTestCase { + + @BeforeEach + public void setUp() throws Exception { + eventRegistryEngineConfiguration.getEventRepositoryService().createDeployment() + .addClasspathResource("channel/userOutboundChannel.channel") + .addClasspathResource("event/userEvent.event") + .addClasspathResource("channel/userInboundChannel.channel") + .addClasspathResource("event/userInboundEvent.event") + .deploy(); + + camelContext.addRoutes(new RouteBuilder() { + + @Override + public void configure() throws Exception { + from("direct:start").to("flowable:userInboundChannel"); + } + }); + } + + @Test + @Deployment(resources = { "process/sendAndReceiveEvent.bpmn20.xml" }) + public void testSendAndReceiveBasicEvent() throws Exception { + ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder().processDefinitionKey("camelProcess") + .variable("name", "John Doe") + .variable("age", 23) + .start(); + + assertEquals("John Doe", runtimeService.getVariable(processInstance.getId(), "name")); + assertEquals(23, runtimeService.getVariable(processInstance.getId(), "age")); + + Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + taskService.complete(task.getId()); + + MockEndpoint mockEndpoint = (MockEndpoint) camelContext.getEndpoint("mock:testQueue"); + assertEquals(1, mockEndpoint.getExchanges().size()); + String bodyString = mockEndpoint.getExchanges().get(0).getIn().getBody(String.class); + JsonNode bodyNode = processEngineConfiguration.getObjectMapper().readTree(bodyString); + assertEquals("John Doe", bodyNode.get("name").asText()); + assertEquals(23, bodyNode.get("age").asInt()); + + ProducerTemplate tpl = camelContext.createProducerTemplate(); + ObjectNode sendBodyNode = new ObjectMapper().createObjectNode(); + sendBodyNode.put("name", "John Doe"); + sendBodyNode.put("city", "Amsterdam"); + Exchange exchange = camelContext.getEndpoint("direct:start").createExchange(); + exchange.getIn().setBody(sendBodyNode); + tpl.send("direct:start", exchange); + + assertEquals("John Doe", runtimeService.getVariable(processInstance.getId(), "correlationName")); + assertEquals("Amsterdam", runtimeService.getVariable(processInstance.getId(), "city")); + + task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); + assertEquals("userTask2", task.getTaskDefinitionKey()); + taskService.complete(task.getId()); + + assertEquals(0, runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId()).count()); + } +} diff --git a/components/camel-flowable/src/test/resources/channel/userChannel.channel b/components/camel-flowable/src/test/resources/channel/userChannel.channel new file mode 100644 index 0000000000000..793c6e499f6a4 --- /dev/null +++ b/components/camel-flowable/src/test/resources/channel/userChannel.channel @@ -0,0 +1,11 @@ +{ + "name": "Camel user channel", + "key": "userChannel", + "channelType": "inbound", + "type": "camel", + "sourceUri": "direct:start", + "deserializerType": "json", + "channelEventKeyDetection": { + "fixedValue": "userEvent" + } +} \ No newline at end of file diff --git a/components/camel-flowable/src/test/resources/channel/userChannelUpdated.channel b/components/camel-flowable/src/test/resources/channel/userChannelUpdated.channel new file mode 100644 index 0000000000000..10cccf947b46c --- /dev/null +++ b/components/camel-flowable/src/test/resources/channel/userChannelUpdated.channel @@ -0,0 +1,11 @@ +{ + "name": "Camel user channel", + "key": "userChannel", + "channelType": "inbound", + "type": "camel", + "sourceUri": "direct:startUpdated", + "deserializerType": "json", + "channelEventKeyDetection": { + "fixedValue": "userEvent" + } +} \ No newline at end of file diff --git a/components/camel-flowable/src/test/resources/channel/userHeaderChannel.channel b/components/camel-flowable/src/test/resources/channel/userHeaderChannel.channel new file mode 100644 index 0000000000000..b04e71c1d6849 --- /dev/null +++ b/components/camel-flowable/src/test/resources/channel/userHeaderChannel.channel @@ -0,0 +1,10 @@ +{ + "name": "Camel user channel", + "key": "userHeaderChannel", + "channelType": "inbound", + "type": "camel", + "deserializerType": "json", + "channelEventKeyDetection": { + "fixedValue": "userHeaderEvent" + } +} \ No newline at end of file diff --git a/components/camel-flowable/src/test/resources/channel/userInboundChannel.channel b/components/camel-flowable/src/test/resources/channel/userInboundChannel.channel new file mode 100644 index 0000000000000..958a4ba932620 --- /dev/null +++ b/components/camel-flowable/src/test/resources/channel/userInboundChannel.channel @@ -0,0 +1,10 @@ +{ + "name": "Camel user inbound channel", + "key": "userInboundChannel", + "channelType": "inbound", + "type": "camel", + "deserializerType": "json", + "channelEventKeyDetection": { + "fixedValue": "userInboundEvent" + } +} \ No newline at end of file diff --git a/components/camel-flowable/src/test/resources/channel/userOutboundChannel.channel b/components/camel-flowable/src/test/resources/channel/userOutboundChannel.channel new file mode 100644 index 0000000000000..514c9a51f95a3 --- /dev/null +++ b/components/camel-flowable/src/test/resources/channel/userOutboundChannel.channel @@ -0,0 +1,8 @@ +{ + "name": "Camel outbound user channel", + "key": "userOutboundChannel", + "channelType": "outbound", + "type": "camel", + "destination": "mock:testQueue", + "serializerType": "json" +} \ No newline at end of file diff --git a/components/camel-flowable/src/test/resources/event/userEvent.event b/components/camel-flowable/src/test/resources/event/userEvent.event new file mode 100644 index 0000000000000..685b69f3844bc --- /dev/null +++ b/components/camel-flowable/src/test/resources/event/userEvent.event @@ -0,0 +1,14 @@ +{ + "key": "userEvent", + "name": "User Event", + "payload": [ + { + "name": "name", + "type": "string" + }, + { + "name": "age", + "type": "integer" + } + ] +} \ No newline at end of file diff --git a/components/camel-flowable/src/test/resources/event/userEventUpdated.event b/components/camel-flowable/src/test/resources/event/userEventUpdated.event new file mode 100644 index 0000000000000..8e546d5119148 --- /dev/null +++ b/components/camel-flowable/src/test/resources/event/userEventUpdated.event @@ -0,0 +1,18 @@ +{ + "key": "userEvent", + "name": "User Event", + "payload": [ + { + "name": "name", + "type": "string" + }, + { + "name": "age", + "type": "integer" + }, + { + "name": "address", + "type": "string" + } + ] +} \ No newline at end of file diff --git a/components/camel-flowable/src/test/resources/event/userInboundEvent.event b/components/camel-flowable/src/test/resources/event/userInboundEvent.event new file mode 100644 index 0000000000000..b6b54bfefd307 --- /dev/null +++ b/components/camel-flowable/src/test/resources/event/userInboundEvent.event @@ -0,0 +1,15 @@ +{ + "key": "userInboundEvent", + "name": "User Inbound Event", + "payload": [ + { + "name": "name", + "correlationParameter":true, + "type": "string" + }, + { + "name": "city", + "type": "string" + } + ] +} \ No newline at end of file diff --git a/components/camel-flowable/src/test/resources/event/userWithHeaderEvent.event b/components/camel-flowable/src/test/resources/event/userWithHeaderEvent.event new file mode 100644 index 0000000000000..14620f806b8d6 --- /dev/null +++ b/components/camel-flowable/src/test/resources/event/userWithHeaderEvent.event @@ -0,0 +1,24 @@ +{ + "key": "userHeaderEvent", + "name": "User Header Event", + "payload": [ + { + "name": "headerProperty1", + "type": "string", + "header": true + }, + { + "name": "headerProperty2", + "type": "integer", + "header": true + }, + { + "name": "name", + "type": "string" + }, + { + "name": "age", + "type": "integer" + } + ] +} \ No newline at end of file diff --git a/components/camel-flowable/src/test/resources/generic-camel-context.xml b/components/camel-flowable/src/test/resources/generic-camel-context.xml new file mode 100644 index 0000000000000..8accdeccd06d6 --- /dev/null +++ b/components/camel-flowable/src/test/resources/generic-camel-context.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/components/camel-flowable/src/test/resources/log4j2.properties b/components/camel-flowable/src/test/resources/log4j2.properties new file mode 100644 index 0000000000000..f9f75591e5724 --- /dev/null +++ b/components/camel-flowable/src/test/resources/log4j2.properties @@ -0,0 +1,28 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); 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. +## --------------------------------------------------------------------------- + +appender.console.type = Console +appender.console.name = console +appender.console.layout.type = PatternLayout +appender.console.layout.pattern = %d %-5p %c{1} - %m %n +appender.file.type = File +appender.file.name = file +appender.file.fileName = target/camel-flowable-test.log +appender.file.layout.type = PatternLayout +appender.file.layout.pattern = %d %-5p %c{1} - %m %n +rootLogger.level = info +rootLogger.appenderRef.file.ref = console diff --git a/components/camel-flowable/src/test/resources/process/sendAndReceiveEvent.bpmn20.xml b/components/camel-flowable/src/test/resources/process/sendAndReceiveEvent.bpmn20.xml new file mode 100644 index 0000000000000..4391bd89fc13f --- /dev/null +++ b/components/camel-flowable/src/test/resources/process/sendAndReceiveEvent.bpmn20.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/components/camel-flowable/src/test/resources/process/sendEvent.bpmn20.xml b/components/camel-flowable/src/test/resources/process/sendEvent.bpmn20.xml new file mode 100644 index 0000000000000..bf4e153ac5673 --- /dev/null +++ b/components/camel-flowable/src/test/resources/process/sendEvent.bpmn20.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/components/camel-flowable/src/test/resources/process/start.bpmn20.xml b/components/camel-flowable/src/test/resources/process/start.bpmn20.xml new file mode 100644 index 0000000000000..58f11b963c9ae --- /dev/null +++ b/components/camel-flowable/src/test/resources/process/start.bpmn20.xml @@ -0,0 +1,44 @@ + + + + + + + + + userEvent + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/components/camel-flowable/src/test/resources/process/startWithHeader.bpmn20.xml b/components/camel-flowable/src/test/resources/process/startWithHeader.bpmn20.xml new file mode 100644 index 0000000000000..87a00f1792632 --- /dev/null +++ b/components/camel-flowable/src/test/resources/process/startWithHeader.bpmn20.xml @@ -0,0 +1,46 @@ + + + + + + + + + userHeaderEvent + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/components/pom.xml b/components/pom.xml index 823dd239e60e4..e865a52f2a49d 100644 --- a/components/pom.xml +++ b/components/pom.xml @@ -134,6 +134,7 @@ camel-file-watch camel-flatpack camel-flink + camel-flowable camel-fop camel-freemarker camel-ftp diff --git a/docs/components/modules/ROOT/nav.adoc b/docs/components/modules/ROOT/nav.adoc index d95c26c9b494e..248066e2c8bf0 100644 --- a/docs/components/modules/ROOT/nav.adoc +++ b/docs/components/modules/ROOT/nav.adoc @@ -116,6 +116,7 @@ ** xref:file-watch-component.adoc[File Watch] ** xref:flatpack-component.adoc[Flatpack] ** xref:flink-component.adoc[Flink] +** xref:flowable-component.adoc[Flowable] ** xref:fop-component.adoc[FOP] ** xref:freemarker-component.adoc[Freemarker] ** xref:ftp-component.adoc[FTP] diff --git a/docs/components/modules/ROOT/pages/flowable-component.adoc b/docs/components/modules/ROOT/pages/flowable-component.adoc new file mode 120000 index 0000000000000..b164c17ef43eb --- /dev/null +++ b/docs/components/modules/ROOT/pages/flowable-component.adoc @@ -0,0 +1 @@ +../../../../../components/camel-flowable/src/main/docs/flowable-component.adoc \ No newline at end of file diff --git a/parent/pom.xml b/parent/pom.xml index d0218ad7905d6..605c618db87ff 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -76,7 +76,7 @@ 1.12.0 1.12.0 4.2.2 - 2.28.18 + 2.28.19 2.18.2 1.2.28 12.0.0-beta.25 @@ -153,6 +153,7 @@ 2.2.0 4.0.18 1.20.0 + 7.1.0 2.10 2.24.1 1.2.0 @@ -203,6 +204,7 @@ 2.11.0 33.3.1-jre 3.0 + 2.2.224 3.4.0 3.0 2.5.1 @@ -212,6 +214,7 @@ 2.2.2 8.0.1.Final 6.3.2.Final + 5.0.1 2.6.1 2.7.3 1.7 @@ -304,6 +307,7 @@ 1.18.1 20.0.7 3.1.13 + 4.13.2 2.4 5.11.2 2.3.0 @@ -1300,6 +1304,11 @@ camel-flink ${project.version} + + org.apache.camel + camel-flowable + ${project.version} + org.apache.camel camel-fop diff --git a/pom.xml b/pom.xml index 1a7e58fc581c1..a7e6697b242fe 100644 --- a/pom.xml +++ b/pom.xml @@ -253,8 +253,10 @@ **/*.bin **/*.cat **/*.cer + **/*.channel **/*.chtml **/*.csv + **/*.event **/*.gif **/*.gpg **/*.graphql*