This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit 1994ab4ae94f7864582b0cc27fbfbfc452a08c53 Author: Andrea Cosentino <[email protected]> AuthorDate: Fri Jan 31 16:32:15 2020 +0100 CAMEL-14463 - Create an AWS-MQ component based on SDK v2 --- components/camel-aws2-mq/pom.xml | 86 +++++ .../src/main/docs/aws-mq-component.adoc | 212 ++++++++++++ .../camel/component/aws2/mq/MQ2Component.java | 120 +++++++ .../aws2/mq/MQ2ComponentVerifierExtension.java | 86 +++++ .../camel/component/aws2/mq/MQ2Configuration.java | 151 +++++++++ .../camel/component/aws2/mq/MQ2Constants.java | 34 ++ .../camel/component/aws2/mq/MQ2Endpoint.java | 120 +++++++ .../camel/component/aws2/mq/MQ2Operations.java | 27 ++ .../camel/component/aws2/mq/MQ2Producer.java | 283 ++++++++++++++++ .../component/aws2/mq/AmazonMQClientMock.java | 107 +++++++ .../aws2/mq/MQComponentClientRegistryTest.java | 43 +++ .../aws2/mq/MQComponentConfigurationTest.java | 69 ++++ .../aws2/mq/MQComponentVerifierExtensionTest.java | 74 +++++ .../component/aws2/mq/MQProducerSpringTest.java | 176 ++++++++++ .../camel/component/aws2/mq/MQProducerTest.java | 202 ++++++++++++ .../src/test/resources/log4j2.properties | 28 ++ .../aws2/mq/MQComponentSpringTest-context.xml | 60 ++++ .../builder/endpoint/EndpointBuilderFactory.java | 1 + .../camel/builder/endpoint/EndpointBuilders.java | 1 + .../endpoint/dsl/MQ2EndpointBuilderFactory.java | 355 +++++++++++++++++++++ 20 files changed, 2235 insertions(+) diff --git a/components/camel-aws2-mq/pom.xml b/components/camel-aws2-mq/pom.xml new file mode 100644 index 0000000..ae34a11 --- /dev/null +++ b/components/camel-aws2-mq/pom.xml @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.camel</groupId> + <artifactId>components</artifactId> + <version>3.1.0-SNAPSHOT</version> + </parent> + + <artifactId>camel-aws2-mq</artifactId> + <packaging>jar</packaging> + + <name>Camel :: AWS2 MQ</name> + <description>A Camel Amazon MQ Web Service Component Version 2</description> + + <properties> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-support</artifactId> + </dependency> + <dependency> + <groupId>software.amazon.awssdk</groupId> + <artifactId>mq</artifactId> + <version>${aws-java-sdk2-version}</version> + </dependency> + <dependency> + <groupId>software.amazon.awssdk</groupId> + <artifactId>apache-client</artifactId> + <version>${aws-java-sdk2-version}</version> + </dependency> + + <!-- for testing --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test-spring</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j-impl</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project> diff --git a/components/camel-aws2-mq/src/main/docs/aws-mq-component.adoc b/components/camel-aws2-mq/src/main/docs/aws-mq-component.adoc new file mode 100644 index 0000000..ee7eb8c --- /dev/null +++ b/components/camel-aws2-mq/src/main/docs/aws-mq-component.adoc @@ -0,0 +1,212 @@ +[[aws-mq-component]] += AWS MQ Component + +*Since Camel 2.21* + +// HEADER START +*Only producer is supported* +// HEADER END + +The MQ component supports create, run, start, stop and terminate +https://aws.amazon.com/amazon-mq/[AWS MQ] instances. + +Prerequisites + +You must have a valid Amazon Web Services developer account, and be +signed up to use Amazon MQ. More information is available at +https://aws.amazon.com/amazon-mq/[Amazon MQ]. + +== URI Format + +[source,java] +------------------------- +aws-mq://label[?options] +------------------------- + +You can append query options to the URI in the following format, +?options=value&option2=value&... + +== URI Options + + +// component options: START +The AWS MQ component supports 6 options, which are listed below. + + + +[width="100%",cols="2,5,^1,2",options="header"] +|=== +| Name | Description | Default | Type +| *configuration* (advanced) | The AWS MQ default configuration | | MQConfiguration +| *accessKey* (producer) | Amazon AWS Access Key | | String +| *secretKey* (producer) | Amazon AWS Secret Key | | String +| *region* (producer) | The region in which MQ client needs to work | | String +| *basicPropertyBinding* (advanced) | Whether the component should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities | false | boolean +| *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...] +|=== +// component options: END + + + + +// endpoint options: START +The AWS MQ endpoint is configured using URI syntax: + +---- +aws-mq:label +---- + +with the following path and query parameters: + +=== Path Parameters (1 parameters): + + +[width="100%",cols="2,5,^1,2",options="header"] +|=== +| Name | Description | Default | Type +| *label* | *Required* Logical name | | String +|=== + + +=== Query Parameters (11 parameters): + + +[width="100%",cols="2,5,^1,2",options="header"] +|=== +| Name | Description | Default | Type +| *accessKey* (producer) | Amazon AWS Access Key | | String +| *amazonMqClient* (producer) | To use a existing configured AmazonMQClient as client | | AmazonMQ +| *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...] +| *operation* (producer) | *Required* The operation to perform. It can be listBrokers,createBroker,deleteBroker | | MQOperations +| *proxyHost* (producer) | To define a proxy host when instantiating the MQ client | | String +| *proxyPort* (producer) | To define a proxy port when instantiating the MQ client | | Integer +| *proxyProtocol* (producer) | To define a proxy protocol when instantiating the MQ client | HTTPS | Protocol +| *region* (producer) | The region in which MQ client needs to work. When using this parameter, the configuration will expect the capitalized name of the region (for example AP_EAST_1) You'll need to use the name Regions.EU_WEST_1.name() | | String +| *secretKey* (producer) | Amazon AWS Secret Key | | String +| *basicPropertyBinding* (advanced) | Whether the endpoint should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities | false | boolean +| *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean +|=== +// endpoint options: END +// spring-boot-auto-configure options: START +== Spring Boot Auto-Configuration + +When using Spring Boot make sure to use the following Maven dependency to have support for auto configuration: + +[source,xml] +---- +<dependency> + <groupId>org.apache.camel.springboot</groupId> + <artifactId>camel-aws-mq-starter</artifactId> + <version>x.x.x</version> + <!-- use the same version as your Camel core version --> +</dependency> +---- + + +The component supports 15 options, which are listed below. + + + +[width="100%",cols="2,5,^1,2",options="header"] +|=== +| Name | Description | Default | Type +| *camel.component.aws-mq.access-key* | Amazon AWS Access Key | | String +| *camel.component.aws-mq.basic-property-binding* | Whether the component should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities | false | Boolean +| *camel.component.aws-mq.bridge-error-handler* | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | Boolean +| *camel.component.aws-mq.configuration.access-key* | Amazon AWS Access Key | | String +| *camel.component.aws-mq.configuration.amazon-mq-client* | To use a existing configured AmazonMQClient as client | | AmazonMQ +| *camel.component.aws-mq.configuration.operation* | The operation to perform. It can be listBrokers,createBroker,deleteBroker | | MQOperations +| *camel.component.aws-mq.configuration.proxy-host* | To define a proxy host when instantiating the MQ client | | String +| *camel.component.aws-mq.configuration.proxy-port* | To define a proxy port when instantiating the MQ client | | Integer +| *camel.component.aws-mq.configuration.proxy-protocol* | To define a proxy protocol when instantiating the MQ client | | Protocol +| *camel.component.aws-mq.configuration.region* | The region in which MQ client needs to work. When using this parameter, the configuration will expect the capitalized name of the region (for example AP_EAST_1) You'll need to use the name Regions.EU_WEST_1.name() | | String +| *camel.component.aws-mq.configuration.secret-key* | Amazon AWS Secret Key | | String +| *camel.component.aws-mq.enabled* | Whether to enable auto configuration of the aws-mq component. This is enabled by default. | | Boolean +| *camel.component.aws-mq.lazy-start-producer* | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed the [...] +| *camel.component.aws-mq.region* | The region in which MQ client needs to work | | String +| *camel.component.aws-mq.secret-key* | Amazon AWS Secret Key | | String +|=== +// spring-boot-auto-configure options: END + + + + +Required MQ component options + +You have to provide the amazonMqClient in the +Registry or your accessKey and secretKey to access +the https://aws.amazon.com/amazon-mq/[Amazon MQ] service. + +== Usage + +=== Message headers evaluated by the MQ producer + +[width="100%",cols="10%,10%,80%",options="header",] +|======================================================================= +|Header |Type |Description + +|`CamelAwsMQMaxResults` |`String` |The number of results that must be retrieved from listBrokers operation + +|`CamelAwsMQBrokerName` |`String` |The broker name + +|`CamelAwsMQOperation` |`String` |The operation we want to perform + +|`CamelAwsMQBrokerId` |`String` |The broker id + +|`CamelAwsMQBrokerDeploymentMode` |`String` |The deployment mode for the broker in the createBroker operation + +|`CamelAwsMQBrokerInstanceType` |`String` |The instance type for the MQ machine in the createBroker operation + +|`CamelAwsMQBrokerEngine` |`String` |The Broker Engine for MQ. Default is ACTIVEMQ + +|`CamelAwsMQBrokerEngineVersion` |`String` |The Broker Engine Version for MQ. Currently you can choose between 5.15.6 and 5.15.0 of ACTIVEMQ + +|`CamelAwsMQBrokerUsers` |`List<User>` |The list of users for MQ + +|`CamelAwsMQBrokerPubliclyAccessible` |`Boolean` |If the MQ instance must be publicly available or not. Default is false. +|======================================================================= + +=== MQ Producer operations + +Camel-AWS MQ component provides the following operation on the producer side: + +- listBrokers +- createBroker +- deleteBroker +- rebootBroker +- updateBroker +- describeBroker + +== Producer Examples + +- listBrokers: this operation will list the available MQ Brokers in AWS + +[source,java] +-------------------------------------------------------------------------------- +from("direct:listBrokers") + .to("aws-mq://test?amazonMqClient=#amazonMqClient&operation=listBrokers") +-------------------------------------------------------------------------------- + +== Automatic detection of AmazonMQ client in registry + +The component is capable of detecting the presence of an AmazonMQ bean into the registry. +If it's the only instance of that type it will be used as client and you won't have to define it as uri parameter. +This may be really useful for smarter configuration of the endpoint. + +Dependencies + +Maven users will need to add the following dependency to their pom.xml. + +*pom.xml* + +[source,xml] +--------------------------------------- +<dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-aws-mq</artifactId> + <version>${camel-version}</version> +</dependency> +--------------------------------------- + +where `$\{camel-version\}` must be replaced by the actual version of Camel. + diff --git a/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Component.java b/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Component.java new file mode 100644 index 0000000..5567aa9 --- /dev/null +++ b/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Component.java @@ -0,0 +1,120 @@ +/* + * 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.aws2.mq; + +import java.util.Map; +import java.util.Set; + +import org.apache.camel.CamelContext; +import org.apache.camel.Endpoint; +import org.apache.camel.spi.Metadata; +import org.apache.camel.spi.annotations.Component; +import org.apache.camel.support.DefaultComponent; +import software.amazon.awssdk.services.mq.MqClient; + +/** + * For working with Amazon MQ version 2. + */ +@Component("aws2-mq") +public class MQ2Component extends DefaultComponent { + + @Metadata + private String accessKey; + @Metadata + private String secretKey; + @Metadata + private String region; + @Metadata(label = "advanced") + private MQ2Configuration configuration; + + public MQ2Component() { + this(null); + } + + public MQ2Component(CamelContext context) { + super(context); + + registerExtension(new MQ2ComponentVerifierExtension()); + } + + @Override + protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { + MQ2Configuration configuration = this.configuration != null ? this.configuration.copy() : new MQ2Configuration(); + MQ2Endpoint endpoint = new MQ2Endpoint(uri, this, configuration); + endpoint.getConfiguration().setAccessKey(accessKey); + endpoint.getConfiguration().setSecretKey(secretKey); + endpoint.getConfiguration().setRegion(region); + setProperties(endpoint, parameters); + checkAndSetRegistryClient(configuration); + if (configuration.getAmazonMqClient() == null && (configuration.getAccessKey() == null || configuration.getSecretKey() == null)) { + throw new IllegalArgumentException("amazonMQClient or accessKey and secretKey must be specified"); + } + + return endpoint; + } + + public MQ2Configuration getConfiguration() { + return configuration; + } + + /** + * The AWS MQ default configuration + */ + public void setConfiguration(MQ2Configuration configuration) { + this.configuration = configuration; + } + + public String getAccessKey() { + return accessKey; + } + + /** + * Amazon AWS Access Key + */ + public void setAccessKey(String accessKey) { + this.accessKey = accessKey; + } + + public String getSecretKey() { + return secretKey; + } + + /** + * Amazon AWS Secret Key + */ + public void setSecretKey(String secretKey) { + this.secretKey = secretKey; + } + + public String getRegion() { + return region; + } + + /** + * The region in which MQ client needs to work + */ + public void setRegion(String region) { + this.region = region; + } + + private void checkAndSetRegistryClient(MQ2Configuration configuration) { + Set<MqClient> clients = getCamelContext().getRegistry().findByType(MqClient.class); + if (clients.size() == 1) { + configuration.setAmazonMqClient(clients.stream().findFirst().get()); + } + } +} diff --git a/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2ComponentVerifierExtension.java b/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2ComponentVerifierExtension.java new file mode 100644 index 0000000..340edb7 --- /dev/null +++ b/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2ComponentVerifierExtension.java @@ -0,0 +1,86 @@ +/* + * 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.aws2.mq; + +import java.util.Map; + +import org.apache.camel.component.extension.verifier.DefaultComponentVerifierExtension; +import org.apache.camel.component.extension.verifier.ResultBuilder; +import org.apache.camel.component.extension.verifier.ResultErrorBuilder; +import org.apache.camel.component.extension.verifier.ResultErrorHelper; + +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.core.exception.SdkClientException; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.mq.MqClient; +import software.amazon.awssdk.services.mq.MqClientBuilder; +import software.amazon.awssdk.services.mq.model.ListBrokersRequest; + +public class MQ2ComponentVerifierExtension extends DefaultComponentVerifierExtension { + + public MQ2ComponentVerifierExtension() { + this("aws2-mq"); + } + + public MQ2ComponentVerifierExtension(String scheme) { + super(scheme); + } + + // ********************************* + // Parameters validation + // ********************************* + + @Override + protected Result verifyParameters(Map<String, Object> parameters) { + + ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.PARAMETERS).error(ResultErrorHelper.requiresOption("accessKey", parameters)) + .error(ResultErrorHelper.requiresOption("secretKey", parameters)).error(ResultErrorHelper.requiresOption("region", parameters)); + + // Validate using the catalog + + super.verifyParametersAgainstCatalog(builder, parameters); + + return builder.build(); + } + + // ********************************* + // Connectivity validation + // ********************************* + + @Override + protected Result verifyConnectivity(Map<String, Object> parameters) { + ResultBuilder builder = ResultBuilder.withStatusAndScope(Result.Status.OK, Scope.CONNECTIVITY); + + try { + MQ2Configuration configuration = setProperties(new MQ2Configuration(), parameters); + AwsBasicCredentials cred = AwsBasicCredentials.create(configuration.getAccessKey(), configuration.getSecretKey()); + MqClientBuilder clientBuilder = MqClient.builder(); + MqClient client = clientBuilder.credentialsProvider(StaticCredentialsProvider.create(cred)).region(Region.of(configuration.getRegion())).build(); + client.listBrokers(ListBrokersRequest.builder().build()); + } catch (SdkClientException e) { + ResultErrorBuilder errorBuilder = ResultErrorBuilder.withCodeAndDescription(VerificationError.StandardCode.AUTHENTICATION, e.getMessage()) + .detail("aws_mq_exception_message", e.getMessage()).detail(VerificationError.ExceptionAttribute.EXCEPTION_CLASS, e.getClass().getName()) + .detail(VerificationError.ExceptionAttribute.EXCEPTION_INSTANCE, e); + + builder.error(errorBuilder.build()); + } catch (Exception e) { + builder.error(ResultErrorBuilder.withException(e).build()); + } + return builder.build(); + } +} diff --git a/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Configuration.java b/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Configuration.java new file mode 100644 index 0000000..42cf19d --- /dev/null +++ b/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Configuration.java @@ -0,0 +1,151 @@ +/* + * 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.aws2.mq; + +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.spi.Metadata; +import org.apache.camel.spi.UriParam; +import org.apache.camel.spi.UriParams; +import org.apache.camel.spi.UriPath; +import software.amazon.awssdk.core.Protocol; +import software.amazon.awssdk.services.mq.MqClient; + +@UriParams +public class MQ2Configuration implements Cloneable { + + @UriPath(description = "Logical name") + @Metadata(required = true) + private String label; + @UriParam(label = "producer") + private MqClient amazonMqClient; + @UriParam(label = "producer", secret = true) + private String accessKey; + @UriParam(label = "producer", secret = true) + private String secretKey; + @UriParam(label = "producer") + @Metadata(required = true) + private MQ2Operations operation; + @UriParam(enums = "HTTP,HTTPS", defaultValue = "HTTPS") + private Protocol proxyProtocol = Protocol.HTTPS; + @UriParam(label = "producer") + private String proxyHost; + @UriParam(label = "producer") + private Integer proxyPort; + @UriParam + private String region; + + public MqClient getAmazonMqClient() { + return amazonMqClient; + } + + /** + * To use a existing configured AmazonMQClient as client + */ + public void setAmazonMqClient(MqClient amazonMqClient) { + this.amazonMqClient = amazonMqClient; + } + + public String getAccessKey() { + return accessKey; + } + + /** + * Amazon AWS Access Key + */ + public void setAccessKey(String accessKey) { + this.accessKey = accessKey; + } + + public String getSecretKey() { + return secretKey; + } + + /** + * Amazon AWS Secret Key + */ + public void setSecretKey(String secretKey) { + this.secretKey = secretKey; + } + + public MQ2Operations getOperation() { + return operation; + } + + /** + * The operation to perform. It can be listBrokers,createBroker,deleteBroker + */ + public void setOperation(MQ2Operations operation) { + this.operation = operation; + } + + public Protocol getProxyProtocol() { + return proxyProtocol; + } + + /** + * To define a proxy protocol when instantiating the MQ client + */ + public void setProxyProtocol(Protocol proxyProtocol) { + this.proxyProtocol = proxyProtocol; + } + + public String getProxyHost() { + return proxyHost; + } + + /** + * To define a proxy host when instantiating the MQ client + */ + public void setProxyHost(String proxyHost) { + this.proxyHost = proxyHost; + } + + public Integer getProxyPort() { + return proxyPort; + } + + /** + * To define a proxy port when instantiating the MQ client + */ + public void setProxyPort(Integer proxyPort) { + this.proxyPort = proxyPort; + } + + public String getRegion() { + return region; + } + + /** + * The region in which MQ client needs to work. When using this parameter, the configuration will expect the capitalized name of the region (for example AP_EAST_1) + * You'll need to use the name Regions.EU_WEST_1.name() + */ + public void setRegion(String region) { + this.region = region; + } + + // ************************************************* + // + // ************************************************* + + public MQ2Configuration copy() { + try { + return (MQ2Configuration)super.clone(); + } catch (CloneNotSupportedException e) { + throw new RuntimeCamelException(e); + } + } +} diff --git a/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Constants.java b/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Constants.java new file mode 100644 index 0000000..be8f46e --- /dev/null +++ b/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Constants.java @@ -0,0 +1,34 @@ +/* + * 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.aws2.mq; + +/** + * Constants used in Camel AWS MQ module + */ +public interface MQ2Constants { + String OPERATION = "CamelAwsMQOperation"; + String MAX_RESULTS = "CamelAwsMQMaxResults"; + String BROKER_NAME = "CamelAwsMQBrokerName"; + String BROKER_ENGINE = "CamelAwsMQBrokerEngine"; + String BROKER_ENGINE_VERSION = "CamelAwsMQBrokerEngineVersion"; + String BROKER_ID = "CamelAwsMQBrokerID"; + String CONFIGURATION_ID = "CamelAwsMQConfigurationID"; + String BROKER_DEPLOYMENT_MODE = "CamelAwsMQBrokerDeploymentMode"; + String BROKER_INSTANCE_TYPE = "CamelAwsMQBrokerInstanceType"; + String BROKER_USERS = "CamelAwsMQBrokerUsers"; + String BROKER_PUBLICLY_ACCESSIBLE = "CamelAwsMQBrokerPubliclyAccessible"; +} diff --git a/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Endpoint.java b/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Endpoint.java new file mode 100644 index 0000000..a145644 --- /dev/null +++ b/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Endpoint.java @@ -0,0 +1,120 @@ +/* + * 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.aws2.mq; + +import java.net.URI; + +import org.apache.camel.Component; +import org.apache.camel.Consumer; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.spi.UriEndpoint; +import org.apache.camel.spi.UriParam; +import org.apache.camel.support.ScheduledPollEndpoint; +import org.apache.camel.util.ObjectHelper; + +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.http.apache.ApacheHttpClient; +import software.amazon.awssdk.http.apache.ProxyConfiguration; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.mq.MqClient; +import software.amazon.awssdk.services.mq.MqClientBuilder; + +/** + * The aws-mq is used for managing Amazon MQ instances. + */ +@UriEndpoint(firstVersion = "3.1.0", scheme = "aws2-mq", title = "AWS 2 MQ", syntax = "aws2-mq:label", producerOnly = true, label = "cloud,management") +public class MQ2Endpoint extends ScheduledPollEndpoint { + + private MqClient mqClient; + + @UriParam + private MQ2Configuration configuration; + + public MQ2Endpoint(String uri, Component component, MQ2Configuration configuration) { + super(uri, component); + this.configuration = configuration; + } + + @Override + public Consumer createConsumer(Processor processor) throws Exception { + throw new UnsupportedOperationException("You cannot receive messages from this endpoint"); + } + + @Override + public Producer createProducer() throws Exception { + return new MQ2Producer(this); + } + + @Override + public void doStart() throws Exception { + super.doStart(); + + mqClient = configuration.getAmazonMqClient() != null ? configuration.getAmazonMqClient() : (MqClient)createMQClient(); + } + + @Override + public void doStop() throws Exception { + if (ObjectHelper.isEmpty(configuration.getAmazonMqClient())) { + if (mqClient != null) { + mqClient.close(); + } + } + super.doStop(); + } + + public MQ2Configuration getConfiguration() { + return configuration; + } + + public MqClient getAmazonMqClient() { + return mqClient; + } + + MqClient createMQClient() { + MqClient client = null; + MqClientBuilder clientBuilder = MqClient.builder(); + ProxyConfiguration.Builder proxyConfig = null; + ApacheHttpClient.Builder httpClientBuilder = null; + boolean isClientConfigFound = false; + if (ObjectHelper.isNotEmpty(configuration.getProxyHost()) && ObjectHelper.isNotEmpty(configuration.getProxyPort())) { + proxyConfig = ProxyConfiguration.builder(); + URI proxyEndpoint = URI.create(configuration.getProxyProtocol() + configuration.getProxyHost() + configuration.getProxyPort()); + proxyConfig.endpoint(proxyEndpoint); + httpClientBuilder = ApacheHttpClient.builder().proxyConfiguration(proxyConfig.build()); + isClientConfigFound = true; + } + if (configuration.getAccessKey() != null && configuration.getSecretKey() != null) { + AwsBasicCredentials cred = AwsBasicCredentials.create(configuration.getAccessKey(), configuration.getSecretKey()); + if (isClientConfigFound) { + clientBuilder = clientBuilder.httpClientBuilder(httpClientBuilder).credentialsProvider(StaticCredentialsProvider.create(cred)); + } else { + clientBuilder = clientBuilder.credentialsProvider(StaticCredentialsProvider.create(cred)); + } + } else { + if (!isClientConfigFound) { + clientBuilder = clientBuilder.httpClientBuilder(httpClientBuilder); + } + } + if (ObjectHelper.isNotEmpty(configuration.getRegion())) { + clientBuilder = clientBuilder.region(Region.of(configuration.getRegion())); + } + client = clientBuilder.build(); + return client; + } +} diff --git a/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Operations.java b/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Operations.java new file mode 100644 index 0000000..cb42a2d --- /dev/null +++ b/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Operations.java @@ -0,0 +1,27 @@ +/* + * 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.aws2.mq; + +public enum MQ2Operations { + + listBrokers, + createBroker, + deleteBroker, + rebootBroker, + updateBroker, + describeBroker +} diff --git a/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Producer.java b/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Producer.java new file mode 100644 index 0000000..1b539f0 --- /dev/null +++ b/components/camel-aws2-mq/src/main/java/org/apache/camel/component/aws2/mq/MQ2Producer.java @@ -0,0 +1,283 @@ +/* + * 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.aws2.mq; + +import java.util.List; + +import org.apache.camel.Endpoint; +import org.apache.camel.Exchange; +import org.apache.camel.Message; +import org.apache.camel.support.DefaultProducer; +import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.URISupport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import software.amazon.awssdk.awscore.exception.AwsServiceException; +import software.amazon.awssdk.services.mq.MqClient; +import software.amazon.awssdk.services.mq.model.ConfigurationId; +import software.amazon.awssdk.services.mq.model.CreateBrokerRequest; +import software.amazon.awssdk.services.mq.model.CreateBrokerResponse; +import software.amazon.awssdk.services.mq.model.DeleteBrokerRequest; +import software.amazon.awssdk.services.mq.model.DeleteBrokerResponse; +import software.amazon.awssdk.services.mq.model.DeploymentMode; +import software.amazon.awssdk.services.mq.model.DescribeBrokerRequest; +import software.amazon.awssdk.services.mq.model.DescribeBrokerResponse; +import software.amazon.awssdk.services.mq.model.EngineType; +import software.amazon.awssdk.services.mq.model.ListBrokersRequest; +import software.amazon.awssdk.services.mq.model.ListBrokersResponse; +import software.amazon.awssdk.services.mq.model.RebootBrokerRequest; +import software.amazon.awssdk.services.mq.model.RebootBrokerResponse; +import software.amazon.awssdk.services.mq.model.UpdateBrokerRequest; +import software.amazon.awssdk.services.mq.model.UpdateBrokerResponse; +import software.amazon.awssdk.services.mq.model.User; + +/** + * A Producer which sends messages to the Amazon MQ Service + * <a href="http://aws.amazon.com/mq/">AWS MQ</a> + */ +public class MQ2Producer extends DefaultProducer { + + private static final Logger LOG = LoggerFactory.getLogger(MQ2Producer.class); + + private transient String mqProducerToString; + + public MQ2Producer(Endpoint endpoint) { + super(endpoint); + } + + @Override + public void process(Exchange exchange) throws Exception { + switch (determineOperation(exchange)) { + case listBrokers: + listBrokers(getEndpoint().getAmazonMqClient(), exchange); + break; + case createBroker: + createBroker(getEndpoint().getAmazonMqClient(), exchange); + break; + case deleteBroker: + deleteBroker(getEndpoint().getAmazonMqClient(), exchange); + break; + case rebootBroker: + rebootBroker(getEndpoint().getAmazonMqClient(), exchange); + break; + case updateBroker: + updateBroker(getEndpoint().getAmazonMqClient(), exchange); + break; + case describeBroker: + describeBroker(getEndpoint().getAmazonMqClient(), exchange); + break; + default: + throw new IllegalArgumentException("Unsupported operation"); + } + } + + private MQ2Operations determineOperation(Exchange exchange) { + MQ2Operations operation = exchange.getIn().getHeader(MQ2Constants.OPERATION, MQ2Operations.class); + if (operation == null) { + operation = getConfiguration().getOperation(); + } + return operation; + } + + protected MQ2Configuration getConfiguration() { + return getEndpoint().getConfiguration(); + } + + @Override + public String toString() { + if (mqProducerToString == null) { + mqProducerToString = "MQProducer[" + URISupport.sanitizeUri(getEndpoint().getEndpointUri()) + "]"; + } + return mqProducerToString; + } + + @Override + public MQ2Endpoint getEndpoint() { + return (MQ2Endpoint)super.getEndpoint(); + } + + private void listBrokers(MqClient mqClient, Exchange exchange) { + ListBrokersRequest.Builder builder = ListBrokersRequest.builder(); + if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(MQ2Constants.MAX_RESULTS))) { + int maxResults = exchange.getIn().getHeader(MQ2Constants.MAX_RESULTS, Integer.class); + builder.maxResults(maxResults); + } + ListBrokersResponse result; + try { + result = mqClient.listBrokers(builder.build()); + } catch (AwsServiceException ase) { + LOG.trace("List Brokers command returned the error code {}", ase.getMessage()); + throw ase; + } + Message message = getMessageForResponse(exchange); + message.setBody(result); + } + + private void createBroker(MqClient mqClient, Exchange exchange) { + String brokerName; + String brokerEngine; + String brokerEngineVersion; + String deploymentMode; + String instanceType; + Boolean publiclyAccessible; + List<User> users; + CreateBrokerRequest.Builder builder = CreateBrokerRequest.builder(); + if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(MQ2Constants.BROKER_NAME))) { + brokerName = exchange.getIn().getHeader(MQ2Constants.BROKER_NAME, String.class); + builder.brokerName(brokerName); + } else { + throw new IllegalArgumentException("Broker Name must be specified"); + } + if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(MQ2Constants.BROKER_ENGINE))) { + brokerEngine = exchange.getIn().getHeader(MQ2Constants.BROKER_ENGINE, String.class); + builder.engineType(EngineType.fromValue(brokerEngine)); + } else { + builder.engineType(EngineType.ACTIVEMQ.name()); + } + if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(MQ2Constants.BROKER_ENGINE_VERSION))) { + brokerEngineVersion = exchange.getIn().getHeader(MQ2Constants.BROKER_ENGINE_VERSION, String.class); + builder.engineVersion(brokerEngineVersion); + } else { + throw new IllegalArgumentException("Broker Engine Version must be specified"); + } + if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(MQ2Constants.BROKER_DEPLOYMENT_MODE))) { + deploymentMode = exchange.getIn().getHeader(MQ2Constants.BROKER_DEPLOYMENT_MODE, String.class); + builder.deploymentMode(DeploymentMode.fromValue(deploymentMode)); + } else { + throw new IllegalArgumentException("Deployment Mode must be specified"); + } + if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(MQ2Constants.BROKER_INSTANCE_TYPE))) { + instanceType = exchange.getIn().getHeader(MQ2Constants.BROKER_INSTANCE_TYPE, String.class); + builder.hostInstanceType(instanceType); + } else { + throw new IllegalArgumentException("Instance Type must be specified"); + } + if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(MQ2Constants.BROKER_USERS))) { + users = exchange.getIn().getHeader(MQ2Constants.BROKER_USERS, List.class); + builder.users(users); + } else { + throw new IllegalArgumentException("A Users list must be specified"); + } + if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(MQ2Constants.BROKER_PUBLICLY_ACCESSIBLE))) { + publiclyAccessible = exchange.getIn().getHeader(MQ2Constants.BROKER_PUBLICLY_ACCESSIBLE, Boolean.class); + builder.publiclyAccessible(publiclyAccessible); + } else { + builder.publiclyAccessible(false); + } + CreateBrokerResponse result; + try { + result = mqClient.createBroker(builder.build()); + } catch (AwsServiceException ase) { + LOG.trace("Create Broker command returned the error code {}", ase.getMessage()); + throw ase; + } + Message message = getMessageForResponse(exchange); + message.setBody(result); + } + + private void deleteBroker(MqClient mqClient, Exchange exchange) { + String brokerId; + DeleteBrokerRequest.Builder builder = DeleteBrokerRequest.builder(); + if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(MQ2Constants.BROKER_ID))) { + brokerId = exchange.getIn().getHeader(MQ2Constants.BROKER_ID, String.class); + builder.brokerId(brokerId); + } else { + throw new IllegalArgumentException("Broker Name must be specified"); + } + DeleteBrokerResponse result; + try { + result = mqClient.deleteBroker(builder.build()); + } catch (AwsServiceException ase) { + LOG.trace("Delete Broker command returned the error code {}", ase.getMessage()); + throw ase; + } + Message message = getMessageForResponse(exchange); + message.setBody(result); + } + + private void rebootBroker(MqClient mqClient, Exchange exchange) { + String brokerId; + RebootBrokerRequest.Builder builder = RebootBrokerRequest.builder(); + if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(MQ2Constants.BROKER_ID))) { + brokerId = exchange.getIn().getHeader(MQ2Constants.BROKER_ID, String.class); + builder.brokerId(brokerId); + } else { + throw new IllegalArgumentException("Broker Name must be specified"); + } + RebootBrokerResponse result; + try { + result = mqClient.rebootBroker(builder.build()); + } catch (AwsServiceException ase) { + LOG.trace("Reboot Broker command returned the error code {}", ase.getMessage()); + throw ase; + } + Message message = getMessageForResponse(exchange); + message.setBody(result); + } + + private void updateBroker(MqClient mqClient, Exchange exchange) { + String brokerId; + ConfigurationId configurationId; + UpdateBrokerRequest.Builder builder = UpdateBrokerRequest.builder(); + if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(MQ2Constants.BROKER_ID))) { + brokerId = exchange.getIn().getHeader(MQ2Constants.BROKER_ID, String.class); + builder.brokerId(brokerId); + } else { + throw new IllegalArgumentException("Broker Name must be specified"); + } + if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(MQ2Constants.CONFIGURATION_ID))) { + configurationId = exchange.getIn().getHeader(MQ2Constants.CONFIGURATION_ID, ConfigurationId.class); + builder.configuration(configurationId); + } else { + throw new IllegalArgumentException("Broker Name must be specified"); + } + UpdateBrokerResponse result; + try { + result = mqClient.updateBroker(builder.build()); + } catch (AwsServiceException ase) { + LOG.trace("Update Broker command returned the error code {}", ase.getMessage()); + throw ase; + } + Message message = getMessageForResponse(exchange); + message.setBody(result); + } + + private void describeBroker(MqClient mqClient, Exchange exchange) { + String brokerId; + DescribeBrokerRequest.Builder builder = DescribeBrokerRequest.builder(); + if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(MQ2Constants.BROKER_ID))) { + brokerId = exchange.getIn().getHeader(MQ2Constants.BROKER_ID, String.class); + builder.brokerId(brokerId); + } else { + throw new IllegalArgumentException("Broker Name must be specified"); + } + DescribeBrokerResponse result; + try { + result = mqClient.describeBroker(builder.build()); + } catch (AwsServiceException ase) { + LOG.trace("Reboot Broker command returned the error code {}", ase.getMessage()); + throw ase; + } + Message message = getMessageForResponse(exchange); + message.setBody(result); + } + + public static Message getMessageForResponse(final Exchange exchange) { + return exchange.getMessage(); + } +} diff --git a/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/AmazonMQClientMock.java b/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/AmazonMQClientMock.java new file mode 100644 index 0000000..2e461c0 --- /dev/null +++ b/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/AmazonMQClientMock.java @@ -0,0 +1,107 @@ +/* + * 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.aws2.mq; + +import java.util.ArrayList; +import java.util.List; + +import software.amazon.awssdk.services.mq.MqClient; +import software.amazon.awssdk.services.mq.model.BrokerState; +import software.amazon.awssdk.services.mq.model.BrokerSummary; +import software.amazon.awssdk.services.mq.model.ConfigurationId; +import software.amazon.awssdk.services.mq.model.CreateBrokerRequest; +import software.amazon.awssdk.services.mq.model.CreateBrokerResponse; +import software.amazon.awssdk.services.mq.model.DeleteBrokerRequest; +import software.amazon.awssdk.services.mq.model.DeleteBrokerResponse; +import software.amazon.awssdk.services.mq.model.DescribeBrokerRequest; +import software.amazon.awssdk.services.mq.model.DescribeBrokerResponse; +import software.amazon.awssdk.services.mq.model.ListBrokersRequest; +import software.amazon.awssdk.services.mq.model.ListBrokersResponse; +import software.amazon.awssdk.services.mq.model.RebootBrokerRequest; +import software.amazon.awssdk.services.mq.model.RebootBrokerResponse; +import software.amazon.awssdk.services.mq.model.UpdateBrokerRequest; +import software.amazon.awssdk.services.mq.model.UpdateBrokerResponse; + +public class AmazonMQClientMock implements MqClient { + + public AmazonMQClientMock() { + } + + @Override + public CreateBrokerResponse createBroker(CreateBrokerRequest createBrokerRequest) { + CreateBrokerResponse.Builder builder = CreateBrokerResponse.builder(); + builder.brokerArn("test").brokerId("1"); + return builder.build(); + } + + @Override + public DeleteBrokerResponse deleteBroker(DeleteBrokerRequest deleteBrokerRequest) { + DeleteBrokerResponse.Builder builder = DeleteBrokerResponse.builder(); + builder.brokerId("1"); + return builder.build(); + } + + @Override + public DescribeBrokerResponse describeBroker(DescribeBrokerRequest describeBrokerRequest) { + DescribeBrokerResponse.Builder builder = DescribeBrokerResponse.builder(); + builder.brokerId("1").brokerName("Test").brokerState(BrokerState.RUNNING.toString()); + return builder.build(); + } + + @Override + public ListBrokersResponse listBrokers(ListBrokersRequest listBrokersRequest) { + ListBrokersResponse.Builder builder = ListBrokersResponse.builder(); + BrokerSummary.Builder bs = BrokerSummary.builder(); + bs.brokerArn("aws:test"); + bs.brokerId("1"); + bs.brokerName("mybroker"); + bs.brokerState(BrokerState.RUNNING.toString()); + List<BrokerSummary> list = new ArrayList<>(); + list.add(bs.build()); + builder.brokerSummaries(list); + return builder.build(); + } + + @Override + public RebootBrokerResponse rebootBroker(RebootBrokerRequest rebootBrokerRequest) { + RebootBrokerResponse.Builder builder = RebootBrokerResponse.builder(); + return builder.build(); + } + + @Override + public UpdateBrokerResponse updateBroker(UpdateBrokerRequest updateBrokerRequest) { + UpdateBrokerResponse.Builder builder = UpdateBrokerResponse.builder(); + ConfigurationId.Builder cId = ConfigurationId.builder(); + cId.id("1"); + cId.revision(12); + builder.brokerId("1").configuration(cId.build()); + return builder.build(); + } + + @Override + public String serviceName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void close() { + // TODO Auto-generated method stub + + } + +} diff --git a/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQComponentClientRegistryTest.java b/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQComponentClientRegistryTest.java new file mode 100644 index 0000000..39bdf97 --- /dev/null +++ b/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQComponentClientRegistryTest.java @@ -0,0 +1,43 @@ +/* + * 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.aws2.mq; + +import org.apache.camel.component.aws2.mq.MQ2Component; +import org.apache.camel.component.aws2.mq.MQ2Endpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +public class MQComponentClientRegistryTest extends CamelTestSupport { + + @Test + public void createEndpointWithMinimalMQClientConfiguration() throws Exception { + + AmazonMQClientMock awsMQClient = new AmazonMQClientMock(); + context.getRegistry().bind("awsMQClient", awsMQClient); + MQ2Component component = context.getComponent("aws2-mq", MQ2Component.class); + MQ2Endpoint endpoint = (MQ2Endpoint) component.createEndpoint("aws2-mq://MyQueue"); + + assertNotNull(endpoint.getConfiguration().getAmazonMqClient()); + } + + @Test(expected = IllegalArgumentException.class) + public void createEndpointWithMinimalMQClientMisconfiguration() throws Exception { + + MQ2Component component = context.getComponent("aws2-mq", MQ2Component.class); + MQ2Endpoint endpoint = (MQ2Endpoint) component.createEndpoint("aws2-mq://MyQueue"); + } +} diff --git a/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQComponentConfigurationTest.java b/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQComponentConfigurationTest.java new file mode 100644 index 0000000..0dcaf4a --- /dev/null +++ b/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQComponentConfigurationTest.java @@ -0,0 +1,69 @@ +/* + * 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.aws2.mq; + +import org.apache.camel.component.aws2.mq.MQ2Component; +import org.apache.camel.component.aws2.mq.MQ2Endpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +import software.amazon.awssdk.core.Protocol; +import software.amazon.awssdk.regions.Region; + +public class MQComponentConfigurationTest extends CamelTestSupport { + + + @Test + public void createEndpointWithComponentElements() throws Exception { + MQ2Component component = context.getComponent("aws2-mq", MQ2Component.class); + component.setAccessKey("XXX"); + component.setSecretKey("YYY"); + MQ2Endpoint endpoint = (MQ2Endpoint)component.createEndpoint("aws2-mq://MyQueue"); + + assertEquals("XXX", endpoint.getConfiguration().getAccessKey()); + assertEquals("YYY", endpoint.getConfiguration().getSecretKey()); + } + + @Test + public void createEndpointWithComponentAndEndpointElements() throws Exception { + MQ2Component component = context.getComponent("aws2-mq", MQ2Component.class); + component.setAccessKey("XXX"); + component.setSecretKey("YYY"); + component.setRegion(Region.US_WEST_1.toString()); + MQ2Endpoint endpoint = (MQ2Endpoint)component.createEndpoint("aws2-mq://MyQueue?accessKey=xxxxxx&secretKey=yyyyy®ion=US_EAST_1"); + + assertEquals("xxxxxx", endpoint.getConfiguration().getAccessKey()); + assertEquals("yyyyy", endpoint.getConfiguration().getSecretKey()); + assertEquals("US_EAST_1", endpoint.getConfiguration().getRegion()); + } + + @Test + public void createEndpointWithComponentEndpointElementsAndProxy() throws Exception { + MQ2Component component = context.getComponent("aws2-mq", MQ2Component.class); + component.setAccessKey("XXX"); + component.setSecretKey("YYY"); + component.setRegion(Region.US_WEST_1.toString()); + MQ2Endpoint endpoint = (MQ2Endpoint)component.createEndpoint("aws2-mq://label?accessKey=xxxxxx&secretKey=yyyyy®ion=US_EAST_1&proxyHost=localhost&proxyPort=9000&proxyProtocol=HTTP"); + + assertEquals("xxxxxx", endpoint.getConfiguration().getAccessKey()); + assertEquals("yyyyy", endpoint.getConfiguration().getSecretKey()); + assertEquals("US_EAST_1", endpoint.getConfiguration().getRegion()); + assertEquals(Protocol.HTTP, endpoint.getConfiguration().getProxyProtocol()); + assertEquals("localhost", endpoint.getConfiguration().getProxyHost()); + assertEquals(Integer.valueOf(9000), endpoint.getConfiguration().getProxyPort()); + } +} diff --git a/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQComponentVerifierExtensionTest.java b/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQComponentVerifierExtensionTest.java new file mode 100644 index 0000000..aa9817f --- /dev/null +++ b/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQComponentVerifierExtensionTest.java @@ -0,0 +1,74 @@ +/* + * 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.aws2.mq; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.camel.Component; +import org.apache.camel.component.aws2.mq.MQ2Operations; +import org.apache.camel.component.extension.ComponentVerifierExtension; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Assert; +import org.junit.Test; + +public class MQComponentVerifierExtensionTest extends CamelTestSupport { + + // ************************************************* + // Tests (parameters) + // ************************************************* + @Override + public boolean isUseRouteBuilder() { + return false; + } + + @Test + public void testParameters() throws Exception { + Component component = context().getComponent("aws2-mq"); + + ComponentVerifierExtension verifier = component.getExtension(ComponentVerifierExtension.class).orElseThrow(IllegalStateException::new); + + Map<String, Object> parameters = new HashMap<>(); + parameters.put("secretKey", "l"); + parameters.put("accessKey", "k"); + parameters.put("region", "l"); + parameters.put("label", "test"); + parameters.put("operation", MQ2Operations.listBrokers); + + ComponentVerifierExtension.Result result = verifier.verify(ComponentVerifierExtension.Scope.PARAMETERS, parameters); + + Assert.assertEquals(ComponentVerifierExtension.Result.Status.OK, result.getStatus()); + } + + @Test + public void testConnectivity() throws Exception { + Component component = context().getComponent("aws2-mq"); + ComponentVerifierExtension verifier = component.getExtension(ComponentVerifierExtension.class).orElseThrow(IllegalStateException::new); + + Map<String, Object> parameters = new HashMap<>(); + parameters.put("secretKey", "l"); + parameters.put("accessKey", "k"); + parameters.put("region", "US_EAST_1"); + parameters.put("label", "test"); + parameters.put("operation", MQ2Operations.listBrokers); + + ComponentVerifierExtension.Result result = verifier.verify(ComponentVerifierExtension.Scope.CONNECTIVITY, parameters); + + Assert.assertEquals(ComponentVerifierExtension.Result.Status.ERROR, result.getStatus()); + } + +} diff --git a/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQProducerSpringTest.java b/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQProducerSpringTest.java new file mode 100644 index 0000000..8337fec --- /dev/null +++ b/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQProducerSpringTest.java @@ -0,0 +1,176 @@ +/* + * 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.aws2.mq; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.component.aws2.mq.MQ2Constants; +import org.apache.camel.component.aws2.mq.MQ2Operations; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.spring.CamelSpringTestSupport; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import software.amazon.awssdk.services.mq.model.BrokerState; +import software.amazon.awssdk.services.mq.model.ConfigurationId; +import software.amazon.awssdk.services.mq.model.CreateBrokerResponse; +import software.amazon.awssdk.services.mq.model.DeleteBrokerResponse; +import software.amazon.awssdk.services.mq.model.DeploymentMode; +import software.amazon.awssdk.services.mq.model.DescribeBrokerResponse; +import software.amazon.awssdk.services.mq.model.EngineType; +import software.amazon.awssdk.services.mq.model.ListBrokersResponse; +import software.amazon.awssdk.services.mq.model.UpdateBrokerResponse; +import software.amazon.awssdk.services.mq.model.User; + +public class MQProducerSpringTest extends CamelSpringTestSupport { + + @EndpointInject("mock:result") + private MockEndpoint mock; + + @Test + public void mqListBrokersTest() throws Exception { + + mock.expectedMessageCount(1); + Exchange exchange = template.request("direct:listBrokers", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(MQ2Constants.OPERATION, MQ2Operations.listBrokers); + } + }); + + assertMockEndpointsSatisfied(); + + ListBrokersResponse resultGet = (ListBrokersResponse) exchange.getIn().getBody(); + assertEquals(1, resultGet.brokerSummaries().size()); + assertEquals("mybroker", resultGet.brokerSummaries().get(0).brokerName()); + assertEquals(BrokerState.RUNNING.toString(), resultGet.brokerSummaries().get(0).brokerState().toString()); + } + + @Test + public void mqCreateBrokerTest() throws Exception { + + mock.expectedMessageCount(1); + Exchange exchange = template.request("direct:createBroker", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(MQ2Constants.OPERATION, MQ2Operations.createBroker); + exchange.getIn().setHeader(MQ2Constants.BROKER_NAME, "test"); + exchange.getIn().setHeader(MQ2Constants.BROKER_DEPLOYMENT_MODE, DeploymentMode.SINGLE_INSTANCE); + exchange.getIn().setHeader(MQ2Constants.BROKER_INSTANCE_TYPE, "mq.t2.micro"); + exchange.getIn().setHeader(MQ2Constants.BROKER_ENGINE, EngineType.ACTIVEMQ.name()); + exchange.getIn().setHeader(MQ2Constants.BROKER_ENGINE_VERSION, "5.15.6"); + exchange.getIn().setHeader(MQ2Constants.BROKER_PUBLICLY_ACCESSIBLE, false); + List<User> users = new ArrayList<>(); + User.Builder user = User.builder(); + user.username("camel"); + user.password("camelcamel12"); + users.add(user.build()); + exchange.getIn().setHeader(MQ2Constants.BROKER_USERS, users); + } + }); + + assertMockEndpointsSatisfied(); + + CreateBrokerResponse resultGet = (CreateBrokerResponse) exchange.getIn().getBody(); + assertEquals(resultGet.brokerId(), "1"); + assertEquals(resultGet.brokerArn(), "test"); + } + + @Test + public void mqDeleteBrokerTest() throws Exception { + + mock.expectedMessageCount(1); + Exchange exchange = template.request("direct:createBroker", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(MQ2Constants.OPERATION, MQ2Operations.deleteBroker); + exchange.getIn().setHeader(MQ2Constants.BROKER_ID, "1"); + } + }); + + assertMockEndpointsSatisfied(); + + DeleteBrokerResponse resultGet = (DeleteBrokerResponse) exchange.getIn().getBody(); + assertEquals(resultGet.brokerId(), "1"); + } + + @Test + public void mqRebootBrokerTest() throws Exception { + + mock.expectedMessageCount(1); + template.request("direct:rebootBroker", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(MQ2Constants.OPERATION, MQ2Operations.rebootBroker); + exchange.getIn().setHeader(MQ2Constants.BROKER_ID, "1"); + } + }); + + assertMockEndpointsSatisfied(); + } + + @Test + public void mqUpdateBrokerTest() throws Exception { + + mock.expectedMessageCount(1); + Exchange exchange = template.request("direct:updateBroker", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(MQ2Constants.OPERATION, MQ2Operations.updateBroker); + exchange.getIn().setHeader(MQ2Constants.BROKER_ID, "1"); + ConfigurationId.Builder cId = ConfigurationId.builder(); + cId.id("1"); + cId.revision(12); + exchange.getIn().setHeader(MQ2Constants.CONFIGURATION_ID, cId.build()); + } + }); + + assertMockEndpointsSatisfied(); + UpdateBrokerResponse resultGet = (UpdateBrokerResponse) exchange.getIn().getBody(); + assertEquals(resultGet.brokerId(), "1"); + } + + @Test + public void mqDescribeBrokerTest() throws Exception { + + mock.expectedMessageCount(1); + Exchange exchange = template.request("direct:describeBroker", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(MQ2Constants.OPERATION, MQ2Operations.describeBroker); + exchange.getIn().setHeader(MQ2Constants.BROKER_ID, "1"); + ConfigurationId.Builder cId = ConfigurationId.builder(); + cId.id("1"); + cId.revision(12); + exchange.getIn().setHeader(MQ2Constants.CONFIGURATION_ID, cId.build()); + } + }); + + assertMockEndpointsSatisfied(); + DescribeBrokerResponse resultGet = (DescribeBrokerResponse) exchange.getIn().getBody(); + assertEquals(resultGet.brokerId(), "1"); + } + + @Override + protected ClassPathXmlApplicationContext createApplicationContext() { + return new ClassPathXmlApplicationContext("org/apache/camel/component/aws2/mq/MQComponentSpringTest-context.xml"); + } +} diff --git a/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQProducerTest.java b/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQProducerTest.java new file mode 100644 index 0000000..7332b3a --- /dev/null +++ b/components/camel-aws2-mq/src/test/java/org/apache/camel/component/aws2/mq/MQProducerTest.java @@ -0,0 +1,202 @@ +/* + * 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.aws2.mq; + +import java.util.ArrayList; +import java.util.List; + +import software.amazon.awssdk.services.mq.model.BrokerState; +import software.amazon.awssdk.services.mq.model.ConfigurationId; +import software.amazon.awssdk.services.mq.model.CreateBrokerResponse; +import software.amazon.awssdk.services.mq.model.DeleteBrokerResponse; +import software.amazon.awssdk.services.mq.model.DeploymentMode; +import software.amazon.awssdk.services.mq.model.DescribeBrokerResponse; +import software.amazon.awssdk.services.mq.model.EngineType; +import software.amazon.awssdk.services.mq.model.ListBrokersResponse; +import software.amazon.awssdk.services.mq.model.UpdateBrokerResponse; +import software.amazon.awssdk.services.mq.model.User; + +import org.apache.camel.BindToRegistry; +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.aws2.mq.MQ2Constants; +import org.apache.camel.component.aws2.mq.MQ2Operations; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +public class MQProducerTest extends CamelTestSupport { + + @BindToRegistry("amazonMqClient") + AmazonMQClientMock clientMock = new AmazonMQClientMock(); + + @EndpointInject("mock:result") + private MockEndpoint mock; + + @Test + public void mqListBrokersTest() throws Exception { + + mock.expectedMessageCount(1); + Exchange exchange = template.request("direct:listBrokers", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(MQ2Constants.OPERATION, MQ2Operations.listBrokers); + } + }); + + assertMockEndpointsSatisfied(); + + ListBrokersResponse resultGet = (ListBrokersResponse) exchange.getIn().getBody(); + assertEquals(1, resultGet.brokerSummaries().size()); + assertEquals("mybroker", resultGet.brokerSummaries().get(0).brokerName()); + assertEquals(BrokerState.RUNNING.toString(), resultGet.brokerSummaries().get(0).brokerState().toString()); + } + + @Test + public void mqCreateBrokerTest() throws Exception { + + mock.expectedMessageCount(1); + Exchange exchange = template.request("direct:createBroker", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(MQ2Constants.OPERATION, MQ2Operations.createBroker); + exchange.getIn().setHeader(MQ2Constants.BROKER_NAME, "test"); + exchange.getIn().setHeader(MQ2Constants.BROKER_DEPLOYMENT_MODE, DeploymentMode.SINGLE_INSTANCE); + exchange.getIn().setHeader(MQ2Constants.BROKER_INSTANCE_TYPE, "mq.t2.micro"); + exchange.getIn().setHeader(MQ2Constants.BROKER_ENGINE, EngineType.ACTIVEMQ.name()); + exchange.getIn().setHeader(MQ2Constants.BROKER_ENGINE_VERSION, "5.15.6"); + exchange.getIn().setHeader(MQ2Constants.BROKER_PUBLICLY_ACCESSIBLE, false); + List<User> users = new ArrayList<>(); + User.Builder user = User.builder(); + user.username("camel"); + user.password("camelcamel12"); + users.add(user.build()); + exchange.getIn().setHeader(MQ2Constants.BROKER_USERS, users); + } + }); + + assertMockEndpointsSatisfied(); + + CreateBrokerResponse resultGet = (CreateBrokerResponse) exchange.getIn().getBody(); + assertEquals(resultGet.brokerId(), "1"); + assertEquals(resultGet.brokerArn(), "test"); + } + + @Test + public void mqDeleteBrokerTest() throws Exception { + + mock.expectedMessageCount(1); + Exchange exchange = template.request("direct:createBroker", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(MQ2Constants.OPERATION, MQ2Operations.deleteBroker); + exchange.getIn().setHeader(MQ2Constants.BROKER_ID, "1"); + } + }); + + assertMockEndpointsSatisfied(); + + DeleteBrokerResponse resultGet = (DeleteBrokerResponse) exchange.getIn().getBody(); + assertEquals(resultGet.brokerId(), "1"); + } + + @Test + public void mqRebootBrokerTest() throws Exception { + + mock.expectedMessageCount(1); + template.request("direct:rebootBroker", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(MQ2Constants.OPERATION, MQ2Operations.rebootBroker); + exchange.getIn().setHeader(MQ2Constants.BROKER_ID, "1"); + } + }); + + assertMockEndpointsSatisfied(); + } + + @Test + public void mqUpdateBrokerTest() throws Exception { + + mock.expectedMessageCount(1); + Exchange exchange = template.request("direct:updateBroker", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(MQ2Constants.OPERATION, MQ2Operations.updateBroker); + exchange.getIn().setHeader(MQ2Constants.BROKER_ID, "1"); + ConfigurationId.Builder cId = ConfigurationId.builder(); + cId.id("1"); + cId.revision(12); + exchange.getIn().setHeader(MQ2Constants.CONFIGURATION_ID, cId.build()); + } + }); + + assertMockEndpointsSatisfied(); + UpdateBrokerResponse resultGet = (UpdateBrokerResponse) exchange.getIn().getBody(); + assertEquals(resultGet.brokerId(), "1"); + } + + @Test + public void mqDescribeBrokerTest() throws Exception { + + mock.expectedMessageCount(1); + Exchange exchange = template.request("direct:describeBroker", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(MQ2Constants.OPERATION, MQ2Operations.describeBroker); + exchange.getIn().setHeader(MQ2Constants.BROKER_ID, "1"); + ConfigurationId.Builder cId = ConfigurationId.builder(); + cId.id("1"); + cId.revision(12); + exchange.getIn().setHeader(MQ2Constants.CONFIGURATION_ID, cId.build()); + } + }); + + assertMockEndpointsSatisfied(); + DescribeBrokerResponse resultGet = (DescribeBrokerResponse) exchange.getIn().getBody(); + assertEquals(resultGet.brokerId(), "1"); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:listBrokers") + .to("aws2-mq://test?amazonMqClient=#amazonMqClient&operation=listBrokers") + .to("mock:result"); + from("direct:createBroker") + .to("aws2-mq://test?amazonMqClient=#amazonMqClient&operation=createBroker") + .to("mock:result"); + from("direct:deleteBroker") + .to("aws2-mq://test?amazonMqClient=#amazonMqClient&operation=deleteBroker") + .to("mock:result"); + from("direct:rebootBroker") + .to("aws2-mq://test?amazonMqClient=#amazonMqClient&operation=rebootBroker") + .to("mock:result"); + from("direct:updateBroker") + .to("aws2-mq://test?amazonMqClient=#amazonMqClient&operation=updateBroker") + .to("mock:result"); + from("direct:describeBroker") + .to("aws2-mq://test?amazonMqClient=#amazonMqClient&operation=describeBroker") + .to("mock:result"); + } + }; + } +} diff --git a/components/camel-aws2-mq/src/test/resources/log4j2.properties b/components/camel-aws2-mq/src/test/resources/log4j2.properties new file mode 100644 index 0000000..dc9aea9 --- /dev/null +++ b/components/camel-aws2-mq/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.file.type = File +appender.file.name = file +appender.file.fileName = target/camel-aws-mq-test.log +appender.file.layout.type = PatternLayout +appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n +appender.out.type = Console +appender.out.name = out +appender.out.layout.type = PatternLayout +appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n +rootLogger.level = INFO +rootLogger.appenderRef.file.ref = file diff --git a/components/camel-aws2-mq/src/test/resources/org/apache/camel/component/aws2/mq/MQComponentSpringTest-context.xml b/components/camel-aws2-mq/src/test/resources/org/apache/camel/component/aws2/mq/MQComponentSpringTest-context.xml new file mode 100644 index 0000000..ba9981d --- /dev/null +++ b/components/camel-aws2-mq/src/test/resources/org/apache/camel/component/aws2/mq/MQComponentSpringTest-context.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> + + <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> + <route> + <from uri="direct:listBrokers"/> + <to uri="aws2-mq://Test?amazonMqClient=#amazonMqClient&operation=listBrokers"/> + <to uri="mock:result"/> + </route> + <route> + <from uri="direct:createBroker"/> + <to uri="aws2-mq://Test?amazonMqClient=#amazonMqClient&operation=createBroker"/> + <to uri="mock:result"/> + </route> + <route> + <from uri="direct:deleteBroker"/> + <to uri="aws2-mq://Test?amazonMqClient=#amazonMqClient&operation=deleteBroker"/> + <to uri="mock:result"/> + </route> + <route> + <from uri="direct:rebootBroker"/> + <to uri="aws2-mq://Test?amazonMqClient=#amazonMqClient&operation=rebootBroker"/> + <to uri="mock:result"/> + </route> + <route> + <from uri="direct:updateBroker"/> + <to uri="aws2-mq://Test?amazonMqClient=#amazonMqClient&operation=updateBroker"/> + <to uri="mock:result"/> + </route> + <route> + <from uri="direct:describeBroker"/> + <to uri="aws2-mq://Test?amazonMqClient=#amazonMqClient&operation=describeBroker"/> + <to uri="mock:result"/> + </route> + </camelContext> + + <bean id="amazonMqClient" class="org.apache.camel.component.aws2.mq.AmazonMQClientMock"/> +</beans> \ No newline at end of file diff --git a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java index 9ec9e60..9e40575 100644 --- a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java +++ b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java @@ -213,6 +213,7 @@ public interface EndpointBuilderFactory org.apache.camel.builder.endpoint.dsl.LogEndpointBuilderFactory.LogBuilders, org.apache.camel.builder.endpoint.dsl.LuceneEndpointBuilderFactory.LuceneBuilders, org.apache.camel.builder.endpoint.dsl.LumberjackEndpointBuilderFactory.LumberjackBuilders, + org.apache.camel.builder.endpoint.dsl.MQ2EndpointBuilderFactory.MQ2Builders, org.apache.camel.builder.endpoint.dsl.MQEndpointBuilderFactory.MQBuilders, org.apache.camel.builder.endpoint.dsl.MSKEndpointBuilderFactory.MSKBuilders, org.apache.camel.builder.endpoint.dsl.MailEndpointBuilderFactory.MailBuilders, diff --git a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilders.java b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilders.java index 8afe518..f705c67 100644 --- a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilders.java +++ b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/EndpointBuilders.java @@ -210,6 +210,7 @@ public interface EndpointBuilders org.apache.camel.builder.endpoint.dsl.LogEndpointBuilderFactory, org.apache.camel.builder.endpoint.dsl.LuceneEndpointBuilderFactory, org.apache.camel.builder.endpoint.dsl.LumberjackEndpointBuilderFactory, + org.apache.camel.builder.endpoint.dsl.MQ2EndpointBuilderFactory, org.apache.camel.builder.endpoint.dsl.MQEndpointBuilderFactory, org.apache.camel.builder.endpoint.dsl.MSKEndpointBuilderFactory, org.apache.camel.builder.endpoint.dsl.MailEndpointBuilderFactory, diff --git a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/MQ2EndpointBuilderFactory.java b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/MQ2EndpointBuilderFactory.java new file mode 100644 index 0000000..d7b3da2 --- /dev/null +++ b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/MQ2EndpointBuilderFactory.java @@ -0,0 +1,355 @@ +/* + * 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.builder.endpoint.dsl; + +import javax.annotation.Generated; +import org.apache.camel.builder.EndpointConsumerBuilder; +import org.apache.camel.builder.EndpointProducerBuilder; +import org.apache.camel.builder.endpoint.AbstractEndpointBuilder; + +/** + * The aws-mq is used for managing Amazon MQ instances. + * + * Generated by camel-package-maven-plugin - do not edit this file! + */ +@Generated("org.apache.camel.maven.packaging.EndpointDslMojo") +public interface MQ2EndpointBuilderFactory { + + + /** + * Builder for endpoint for the AWS 2 MQ component. + */ + public interface MQ2EndpointBuilder extends EndpointProducerBuilder { + default AdvancedMQ2EndpointBuilder advanced() { + return (AdvancedMQ2EndpointBuilder) this; + } + /** + * Amazon AWS Access Key. + * + * The option is a: <code>java.lang.String</code> type. + * + * Group: producer + */ + default MQ2EndpointBuilder accessKey(String accessKey) { + doSetProperty("accessKey", accessKey); + return this; + } + /** + * To use a existing configured AmazonMQClient as client. + * + * The option is a: + * <code>software.amazon.awssdk.services.mq.MqClient</code> type. + * + * Group: producer + */ + default MQ2EndpointBuilder amazonMqClient(Object amazonMqClient) { + doSetProperty("amazonMqClient", amazonMqClient); + return this; + } + /** + * To use a existing configured AmazonMQClient as client. + * + * The option will be converted to a + * <code>software.amazon.awssdk.services.mq.MqClient</code> type. + * + * Group: producer + */ + default MQ2EndpointBuilder amazonMqClient(String amazonMqClient) { + doSetProperty("amazonMqClient", amazonMqClient); + return this; + } + /** + * Whether the producer should be started lazy (on the first message). + * By starting lazy you can use this to allow CamelContext and routes to + * startup in situations where a producer may otherwise fail during + * starting and cause the route to fail being started. By deferring this + * startup to be lazy then the startup failure can be handled during + * routing messages via Camel's routing error handlers. Beware that when + * the first message is processed then creating and starting the + * producer may take a little time and prolong the total processing time + * of the processing. + * + * The option is a: <code>boolean</code> type. + * + * Default: false + * Group: producer + */ + default MQ2EndpointBuilder lazyStartProducer(boolean lazyStartProducer) { + doSetProperty("lazyStartProducer", lazyStartProducer); + return this; + } + /** + * Whether the producer should be started lazy (on the first message). + * By starting lazy you can use this to allow CamelContext and routes to + * startup in situations where a producer may otherwise fail during + * starting and cause the route to fail being started. By deferring this + * startup to be lazy then the startup failure can be handled during + * routing messages via Camel's routing error handlers. Beware that when + * the first message is processed then creating and starting the + * producer may take a little time and prolong the total processing time + * of the processing. + * + * The option will be converted to a <code>boolean</code> type. + * + * Default: false + * Group: producer + */ + default MQ2EndpointBuilder lazyStartProducer(String lazyStartProducer) { + doSetProperty("lazyStartProducer", lazyStartProducer); + return this; + } + /** + * The operation to perform. It can be + * listBrokers,createBroker,deleteBroker. + * + * The option is a: + * <code>org.apache.camel.component.aws2.mq.MQ2Operations</code> type. + * + * Required: true + * Group: producer + */ + default MQ2EndpointBuilder operation(MQ2Operations operation) { + doSetProperty("operation", operation); + return this; + } + /** + * The operation to perform. It can be + * listBrokers,createBroker,deleteBroker. + * + * The option will be converted to a + * <code>org.apache.camel.component.aws2.mq.MQ2Operations</code> type. + * + * Required: true + * Group: producer + */ + default MQ2EndpointBuilder operation(String operation) { + doSetProperty("operation", operation); + return this; + } + /** + * To define a proxy host when instantiating the MQ client. + * + * The option is a: <code>java.lang.String</code> type. + * + * Group: producer + */ + default MQ2EndpointBuilder proxyHost(String proxyHost) { + doSetProperty("proxyHost", proxyHost); + return this; + } + /** + * To define a proxy port when instantiating the MQ client. + * + * The option is a: <code>java.lang.Integer</code> type. + * + * Group: producer + */ + default MQ2EndpointBuilder proxyPort(Integer proxyPort) { + doSetProperty("proxyPort", proxyPort); + return this; + } + /** + * To define a proxy port when instantiating the MQ client. + * + * The option will be converted to a <code>java.lang.Integer</code> + * type. + * + * Group: producer + */ + default MQ2EndpointBuilder proxyPort(String proxyPort) { + doSetProperty("proxyPort", proxyPort); + return this; + } + /** + * To define a proxy protocol when instantiating the MQ client. + * + * The option is a: <code>software.amazon.awssdk.core.Protocol</code> + * type. + * + * Default: HTTPS + * Group: producer + */ + default MQ2EndpointBuilder proxyProtocol(Protocol proxyProtocol) { + doSetProperty("proxyProtocol", proxyProtocol); + return this; + } + /** + * To define a proxy protocol when instantiating the MQ client. + * + * The option will be converted to a + * <code>software.amazon.awssdk.core.Protocol</code> type. + * + * Default: HTTPS + * Group: producer + */ + default MQ2EndpointBuilder proxyProtocol(String proxyProtocol) { + doSetProperty("proxyProtocol", proxyProtocol); + return this; + } + /** + * The region in which MQ client needs to work. When using this + * parameter, the configuration will expect the capitalized name of the + * region (for example AP_EAST_1) You'll need to use the name + * Regions.EU_WEST_1.name(). + * + * The option is a: <code>java.lang.String</code> type. + * + * Group: producer + */ + default MQ2EndpointBuilder region(String region) { + doSetProperty("region", region); + return this; + } + /** + * Amazon AWS Secret Key. + * + * The option is a: <code>java.lang.String</code> type. + * + * Group: producer + */ + default MQ2EndpointBuilder secretKey(String secretKey) { + doSetProperty("secretKey", secretKey); + return this; + } + } + + /** + * Advanced builder for endpoint for the AWS 2 MQ component. + */ + public interface AdvancedMQ2EndpointBuilder + extends + EndpointProducerBuilder { + default MQ2EndpointBuilder basic() { + return (MQ2EndpointBuilder) this; + } + /** + * Whether the endpoint should use basic property binding (Camel 2.x) or + * the newer property binding with additional capabilities. + * + * The option is a: <code>boolean</code> type. + * + * Default: false + * Group: advanced + */ + default AdvancedMQ2EndpointBuilder basicPropertyBinding( + boolean basicPropertyBinding) { + doSetProperty("basicPropertyBinding", basicPropertyBinding); + return this; + } + /** + * Whether the endpoint should use basic property binding (Camel 2.x) or + * the newer property binding with additional capabilities. + * + * The option will be converted to a <code>boolean</code> type. + * + * Default: false + * Group: advanced + */ + default AdvancedMQ2EndpointBuilder basicPropertyBinding( + String basicPropertyBinding) { + doSetProperty("basicPropertyBinding", basicPropertyBinding); + return this; + } + /** + * Sets whether synchronous processing should be strictly used, or Camel + * is allowed to use asynchronous processing (if supported). + * + * The option is a: <code>boolean</code> type. + * + * Default: false + * Group: advanced + */ + default AdvancedMQ2EndpointBuilder synchronous(boolean synchronous) { + doSetProperty("synchronous", synchronous); + return this; + } + /** + * Sets whether synchronous processing should be strictly used, or Camel + * is allowed to use asynchronous processing (if supported). + * + * The option will be converted to a <code>boolean</code> type. + * + * Default: false + * Group: advanced + */ + default AdvancedMQ2EndpointBuilder synchronous(String synchronous) { + doSetProperty("synchronous", synchronous); + return this; + } + } + + /** + * Proxy enum for + * <code>org.apache.camel.component.aws2.mq.MQ2Operations</code> enum. + */ + enum MQ2Operations { + listBrokers, + createBroker, + deleteBroker, + rebootBroker, + updateBroker, + describeBroker; + } + + /** + * Proxy enum for <code>software.amazon.awssdk.core.Protocol</code> enum. + */ + enum Protocol { + http, + https; + } + + public interface MQ2Builders { + /** + * AWS 2 MQ (camel-aws2-mq) + * The aws-mq is used for managing Amazon MQ instances. + * + * Category: cloud,management + * Since: 3.1 + * Maven coordinates: org.apache.camel:camel-aws2-mq + * + * Syntax: <code>aws2-mq:label</code> + * + * Path parameter: label (required) + * Logical name + */ + default MQ2EndpointBuilder aws2Mq(String path) { + return MQ2EndpointBuilderFactory.aws2Mq(path); + } + } + /** + * AWS 2 MQ (camel-aws2-mq) + * The aws-mq is used for managing Amazon MQ instances. + * + * Category: cloud,management + * Since: 3.1 + * Maven coordinates: org.apache.camel:camel-aws2-mq + * + * Syntax: <code>aws2-mq:label</code> + * + * Path parameter: label (required) + * Logical name + */ + static MQ2EndpointBuilder aws2Mq(String path) { + class MQ2EndpointBuilderImpl extends AbstractEndpointBuilder implements MQ2EndpointBuilder, AdvancedMQ2EndpointBuilder { + public MQ2EndpointBuilderImpl(String path) { + super("aws2-mq", path); + } + } + return new MQ2EndpointBuilderImpl(path); + } +} \ No newline at end of file
