CAMEL-9430 Create camel-component for braintreepayments
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/e8b00192 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/e8b00192 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/e8b00192 Branch: refs/heads/master Commit: e8b00192394cc395bfd48ff3070ffc9fb3abf1bf Parents: dbd5c5b Author: lburgazzoli <lburgazz...@gmail.com> Authored: Thu Jan 7 10:04:29 2016 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Fri Jan 8 18:39:49 2016 +0100 ---------------------------------------------------------------------- components/camel-braintree/pom.xml | 370 ++++++++++++++++ .../component/braintree/BraintreeComponent.java | 75 ++++ .../braintree/BraintreeConfiguration.java | 166 +++++++ .../component/braintree/BraintreeConsumer.java | 30 ++ .../component/braintree/BraintreeEndpoint.java | 106 +++++ .../component/braintree/BraintreeProducer.java | 31 ++ .../braintree/internal/BraintreeConstants.java | 29 ++ .../internal/BraintreePropertiesHelper.java | 39 ++ .../org/apache/camel/component/braintree | 18 + .../braintree/AbstractBraintreeTestSupport.java | 159 +++++++ .../braintree/AddOnGatewayIntegrationTest.java | 53 +++ .../AddressGatewayIntegrationTest.java | 231 ++++++++++ .../ClientTokenGatewayIntegrationTest.java | 48 +++ ...tCardVerificationGatewayIntegrationTest.java | 69 +++ .../CustomerGatewayIntegrationTest.java | 202 +++++++++ .../DiscountGatewayIntegrationTest.java | 54 +++ .../MerchantAccountGatewayIntegrationTest.java | 111 +++++ .../PaymentMethodGatewayIntegrationTest.java | 205 +++++++++ ...aymentMethodNonceGatewayIntegrationTest.java | 67 +++ .../braintree/PlanGatewayIntegrationTest.java | 53 +++ ...ementBatchSummaryGatewayIntegrationTest.java | 75 ++++ .../SubscriptionGatewayIntegrationTest.java | 169 ++++++++ .../TransactionGatewayIntegrationTest.java | 431 +++++++++++++++++++ ...bhookNotificationGatewayIntegrationTest.java | 69 +++ .../src/test/resources/log4j.properties | 31 ++ .../src/test/resources/test-options.properties | 21 + components/pom.xml | 1 + parent/pom.xml | 7 + 28 files changed, 2920 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-braintree/pom.xml b/components/camel-braintree/pom.xml new file mode 100644 index 0000000..2b6e9c0 --- /dev/null +++ b/components/camel-braintree/pom.xml @@ -0,0 +1,370 @@ +<?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>2.17-SNAPSHOT</version> + </parent> + + <artifactId>camel-braintree</artifactId> + <packaging>bundle</packaging> + <name>Camel :: Braintree</name> + <description>Camel Braintree support</description> + + <properties> + <schemeName>braintree</schemeName> + <componentName>Braintree</componentName> + <componentPackage>org.apache.camel.component.braintree</componentPackage> + <outPackage>org.apache.camel.component.braintree.internal</outPackage> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + + <camel.osgi.export.pkg>${componentPackage}</camel.osgi.export.pkg> + <camel.osgi.private.pkg>${outPackage}</camel.osgi.private.pkg> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.braintreepayments.gateway</groupId> + <artifactId>braintree-java</artifactId> + <version>${braintree-gateway-version}</version> + </dependency> + <!-- + <dependency> + <groupId>org.apache.servicemix.bundles</groupId> + <artifactId>org.apache.servicemix.bundles.braintree-java</artifactId> + <version>${braintree-gateway-bundle-version}</version> + </dependency> + --> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + <version>${commons-lang3-version}</version> + </dependency> + <dependency> + <groupId>commons-collections</groupId> + <artifactId>commons-collections</artifactId> + <version>${commons-collections-version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>${google-guava-version}</version> + <scope>test</scope> + </dependency> + + + <!-- support camel documentation --> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>apt</artifactId> + <exclusions> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-nop</artifactId> + </exclusion> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-jdk14</artifactId> + </exclusion> + </exclusions> + </dependency> + + <!-- Camel annotations in provided scope to avoid compile errors in IDEs --> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>spi-annotations</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + + <!-- Component API javadoc in provided scope to read API signatures --> + <dependency> + <groupId>com.braintreepayments.gateway</groupId> + <artifactId>braintree-java</artifactId> + <version>${braintree-gateway-version}</version> + <classifier>javadoc</classifier> + <scope>provided</scope> + </dependency> + + <!-- logging --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>test</scope> + </dependency> + + <!-- testing --> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <defaultGoal>install</defaultGoal> + + <plugins> + <!-- generate Component source and test source --> + <plugin> + <groupId>org.apache.camel</groupId> + <artifactId>camel-api-component-maven-plugin</artifactId> + <version>${project.version}</version> + <executions> + <execution> + <id>generate-test-component-classes</id> + <goals> + <goal>fromApis</goal> + </goals> + <configuration> + <apis> + <api> + <apiName>addOn</apiName> + <proxyClass>com.braintreegateway.AddOnGateway</proxyClass> + <fromJavadoc/> + </api> + <api> + <apiName>address</apiName> + <proxyClass>com.braintreegateway.AddressGateway</proxyClass> + <fromJavadoc/> + </api> + <api> + <apiName>clientToken</apiName> + <proxyClass>com.braintreegateway.ClientTokenGateway</proxyClass> + <fromJavadoc/> + </api> + <api> + <apiName>creditCardVerification</apiName> + <proxyClass>com.braintreegateway.CreditCardVerificationGateway</proxyClass> + <fromJavadoc/> + </api> + <api> + <apiName>customer</apiName> + <proxyClass>com.braintreegateway.CustomerGateway</proxyClass> + <fromJavadoc> + <excludeMethods>.*ransparent.*</excludeMethods> + </fromJavadoc> + </api> + <api> + <apiName>discount</apiName> + <proxyClass>com.braintreegateway.DiscountGateway</proxyClass> + <fromJavadoc/> + </api> + <api> + <apiName>merchantAccount</apiName> + <proxyClass>com.braintreegateway.MerchantAccountGateway</proxyClass> + <fromJavadoc/> + </api> + <api> + <apiName>paymentMethod</apiName> + <proxyClass>com.braintreegateway.PaymentMethodGateway</proxyClass> + <fromJavadoc> + <excludeMethods>.*parse.*</excludeMethods> + </fromJavadoc> + </api> + <api> + <apiName>paymentMethodNonce</apiName> + <proxyClass>com.braintreegateway.PaymentMethodNonceGateway</proxyClass> + <fromJavadoc> + <excludeMethods>.*parse.*</excludeMethods> + </fromJavadoc> + </api> + <api> + <apiName>plan</apiName> + <proxyClass>com.braintreegateway.PlanGateway</proxyClass> + <fromJavadoc/> + </api> + <api> + <apiName>settlementBatchSummary</apiName> + <proxyClass>com.braintreegateway.SettlementBatchSummaryGateway</proxyClass> + <fromJavadoc/> + </api> + <api> + <apiName>subscription</apiName> + <proxyClass>com.braintreegateway.SubscriptionGateway</proxyClass> + <fromJavadoc/> + </api> + <api> + <apiName>transaction</apiName> + <proxyClass>com.braintreegateway.TransactionGateway</proxyClass> + <fromJavadoc> + <excludeMethods>.*TrData.*|.*ransparent.*</excludeMethods> + </fromJavadoc> + <substitutions> + <substitution> + <method>^.+$</method> + <argName>^.+$</argName> + <argType>com.braintreegateway.TransactionRequest</argType> + <replacement>request</replacement> + <replaceWithType>false</replaceWithType> + </substitution> + <substitution> + <method>^.+$</method> + <argName>^.+$</argName> + <argType>com.braintreegateway.TransactionCloneRequest</argType> + <replacement>cloneRequest</replacement> + <replaceWithType>false</replaceWithType> + </substitution> + </substitutions> + </api> + <api> + <apiName>webhookNotification</apiName> + <proxyClass>com.braintreegateway.WebhookNotificationGateway</proxyClass> + <fromJavadoc/> + </api> + </apis> + </configuration> + </execution> + </executions> + </plugin> + + <!-- generate components meta-data and validate component includes documentation etc --> + <plugin> + <groupId>org.apache.camel</groupId> + <artifactId>camel-package-maven-plugin</artifactId> + <executions> + <execution> + <id>prepare</id> + <goals> + <goal>prepare-components</goal> + </goals> + <phase>generate-resources</phase> + </execution> + <execution> + <id>validate</id> + <goals> + <goal>validate-components</goal> + </goals> + <phase>prepare-package</phase> + </execution> + </executions> + </plugin> + + <!-- add generated source and test source to build --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>add-generated-sources</id> + <goals> + <goal>add-source</goal> + </goals> + <configuration> + <sources> + <source>${project.build.directory}/generated-sources/camel-component</source> + </sources> + </configuration> + </execution> + <execution> + <id>add-generated-test-sources</id> + <goals> + <goal>add-test-source</goal> + </goals> + <configuration> + <sources> + <source>${project.build.directory}/generated-test-sources/camel-component</source> + </sources> + </configuration> + </execution> + </executions> + </plugin> + + </plugins> + + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.camel</groupId> + <artifactId>camel-api-component-maven-plugin</artifactId> + <configuration> + <scheme>${schemeName}</scheme> + <componentName>${componentName}</componentName> + <componentPackage>${componentPackage}</componentPackage> + <outPackage>${outPackage}</outPackage> + </configuration> + </plugin> + </plugins> + </pluginManagement> + + </build> + + <reporting> + <plugins> + <plugin> + <groupId>org.apache.camel</groupId> + <artifactId>camel-api-component-maven-plugin</artifactId> + <configuration> + <scheme>${schemeName}</scheme> + <componentName>${componentName}</componentName> + <componentPackage>${componentPackage}</componentPackage> + <outPackage>${outPackage}</outPackage> + </configuration> + </plugin> + </plugins> + </reporting> + + <profiles> + <profile> + <id>braintree-test</id> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <childDelegation>false</childDelegation> + <useFile>true</useFile> + <forkCount>1</forkCount> + <reuseForks>true</reuseForks> + <forkedProcessTimeoutInSeconds>300</forkedProcessTimeoutInSeconds> + <includes> + <include>**/*Test.java</include> + </includes> + <excludes> + <exclude>**/*XXXTest.java</exclude> + </excludes> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeComponent.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeComponent.java b/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeComponent.java new file mode 100644 index 0000000..15f127f --- /dev/null +++ b/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeComponent.java @@ -0,0 +1,75 @@ +/** + * 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.braintree; + +import java.util.HashMap; +import java.util.Map; + +import com.braintreegateway.BraintreeGateway; +import org.apache.camel.CamelContext; +import org.apache.camel.Endpoint; +import org.apache.camel.component.braintree.internal.BraintreeApiCollection; +import org.apache.camel.component.braintree.internal.BraintreeApiName; +import org.apache.camel.util.component.AbstractApiComponent; + + +/** + * Represents the component that manages {@link BraintreeEndpoint}. + */ +public class BraintreeComponent extends AbstractApiComponent<BraintreeApiName, BraintreeConfiguration, BraintreeApiCollection> { + private final Map<String, BraintreeGateway> gateways; + + public BraintreeComponent() { + super(BraintreeEndpoint.class, BraintreeApiName.class, BraintreeApiCollection.getCollection()); + + this.gateways = new HashMap<>(); + } + + public BraintreeComponent(CamelContext context) { + super(context, BraintreeEndpoint.class, BraintreeApiName.class, BraintreeApiCollection.getCollection()); + + this.gateways = new HashMap<>(); + } + + @Override + protected BraintreeApiName getApiName(String apiNameStr) throws IllegalArgumentException { + return BraintreeApiName.fromValue(apiNameStr); + } + + @Override + protected Endpoint createEndpoint(String uri, String methodName, BraintreeApiName apiName, BraintreeConfiguration endpointConfiguration) { + return new BraintreeEndpoint(uri, this, apiName, methodName, endpointConfiguration, getGateway(endpointConfiguration)); + } + + /** + * To use the shared configuration + */ + @Override + public void setConfiguration(BraintreeConfiguration configuration) { + super.setConfiguration(configuration); + } + + private synchronized BraintreeGateway getGateway(BraintreeConfiguration configuration) { + BraintreeGateway gateway = gateways.get(configuration.getMerchantId()); + if (gateway == null) { + //TODO: review the key used to track gateways + gateways.put(configuration.getMerchantId(), gateway = configuration.newBraintreeGateway()); + } + + return gateway; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeConfiguration.java b/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeConfiguration.java new file mode 100644 index 0000000..49c3dd3 --- /dev/null +++ b/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeConfiguration.java @@ -0,0 +1,166 @@ +/** + * 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.braintree; + +import com.braintreegateway.BraintreeGateway; +import com.braintreegateway.Environment; +import org.apache.camel.spi.Metadata; +import org.apache.camel.spi.UriParam; +import org.apache.camel.spi.UriParams; +import org.apache.camel.util.ObjectHelper; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Component configuration for Braintree component. + */ +@UriParams +public class BraintreeConfiguration { + private static final Logger LOG = LoggerFactory.getLogger(BraintreeConfiguration.class); + + private static final String ENVIRONMENT = "environment"; + private static final String MERCHANT_ID = "merchant_id"; + private static final String PUBLIC_KEY = "public_key"; + private static final String PRIVATE_KEY = "private_key"; + + @UriParam + @Metadata(required = "true") + private String environment; + + @UriParam + @Metadata(required = "true") + private String merchantId; + + @UriParam + @Metadata(required = "true") + private String publicKey; + + @UriParam + @Metadata(required = "true") + private String privateKey; + + + /** + * @return the environment + */ + public String getEnvironment() { + return ObjectHelper.notNull(environment, ENVIRONMENT); + } + + /** + * @param environment the environment Either SANDBOX or PRODUCTION + */ + public void setEnvironment(String environment) { + this.environment = environment; + } + + + /** + * @return the merchant id + */ + public String getMerchantId() { + return ObjectHelper.notNull(merchantId, MERCHANT_ID); + } + + /** + * @param merchantId the merchant id provided by Braintree. + */ + public void setMerchantId(String merchantId) { + this.merchantId = merchantId; + } + + + /** + * @return the public key + */ + public String getPublicKey() { + return ObjectHelper.notNull(publicKey, PUBLIC_KEY); + } + + /** + * @param publicKey the public key provided by Braintree. + */ + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + + /** + * @return the private key + */ + public String getPrivateKey() { + return ObjectHelper.notNull(privateKey, PRIVATE_KEY); + } + + /** + * @param privateKey the private key provided by Braintree. + */ + public void setPrivateKey(String privateKey) { + this.privateKey = privateKey; + } + + + /** + * Helper method to get and Environment object from its name + * + * @return the environment + */ + private Environment getBraintreeEnvironment() { + String name = getEnvironment(); + + if (StringUtils.equalsIgnoreCase("development", name)) { + return Environment.DEVELOPMENT; + } + + if (StringUtils.equalsIgnoreCase("sandbox", name)) { + return Environment.SANDBOX; + } + + if (StringUtils.equalsIgnoreCase("production", name)) { + return Environment.PRODUCTION; + } + + throw new IllegalArgumentException(String.format( + "Environment should be development, sandbox or production, got %s", name)); + } + + /** + * Contruct a BraintreeGateway from configuration + * + * @return a braintree gateway + */ + BraintreeGateway newBraintreeGateway() { + return new BraintreeGateway( + getBraintreeEnvironment(), + getMerchantId(), + getPublicKey(), + getPrivateKey()); + } + + /* + public void validate() { + if (ObjectHelper.isEmpty(environment) + || ObjectHelper.isEmpty(merchantId) + || ObjectHelper.isEmpty(publicKey) + || ObjectHelper.isEmpty(privateKey)) { + throw new IllegalArgumentException(String.format( + "Missing required properties %s, %s, %s, %s", ENVIRONMENT, MERCHANT_ID, PUBLIC_KEY, PRIVATE_KEY)); + } + } + */ +} http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeConsumer.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeConsumer.java b/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeConsumer.java new file mode 100644 index 0000000..cb3e61a --- /dev/null +++ b/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeConsumer.java @@ -0,0 +1,30 @@ +/** + * 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.braintree; + +import org.apache.camel.Processor; +import org.apache.camel.component.braintree.internal.BraintreeApiName; +import org.apache.camel.util.component.AbstractApiConsumer; + +/** + * The Braintree consumer. + */ +public class BraintreeConsumer extends AbstractApiConsumer<BraintreeApiName, BraintreeConfiguration> { + public BraintreeConsumer(BraintreeEndpoint endpoint, Processor processor) { + super(endpoint, processor); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeEndpoint.java b/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeEndpoint.java new file mode 100644 index 0000000..25c83c4 --- /dev/null +++ b/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeEndpoint.java @@ -0,0 +1,106 @@ +/** + * 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.braintree; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; + +import com.braintreegateway.BraintreeGateway; +import org.apache.camel.Consumer; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.component.braintree.internal.BraintreeApiCollection; +import org.apache.camel.component.braintree.internal.BraintreeApiName; +import org.apache.camel.component.braintree.internal.BraintreeConstants; +import org.apache.camel.component.braintree.internal.BraintreePropertiesHelper; +import org.apache.camel.spi.UriEndpoint; +import org.apache.camel.spi.UriPath; +import org.apache.camel.util.component.AbstractApiEndpoint; +import org.apache.camel.util.component.ApiMethod; +import org.apache.camel.util.component.ApiMethodPropertiesHelper; + +/** + * Represents a Braintree endpoint. + */ +@UriEndpoint(scheme = "braintree", title = "Braintree", syntax = "braintree:name", consumerClass = BraintreeConsumer.class, label = "Braintree") +public class BraintreeEndpoint extends AbstractApiEndpoint<BraintreeApiName, BraintreeConfiguration> { + + @UriPath(description = "the method name") + private final String name; + + private Object apiProxy; + private final BraintreeGateway gateway; + + public BraintreeEndpoint(String uri, BraintreeComponent component, + BraintreeApiName apiName, String methodName, BraintreeConfiguration endpointConfiguration, BraintreeGateway gateway) { + super(uri, component, apiName, methodName, BraintreeApiCollection.getCollection().getHelper(apiName), endpointConfiguration); + + this.gateway = gateway; + this.name = methodName; + } + + @Override + public Producer createProducer() throws Exception { + return new BraintreeProducer(this); + } + + @Override + public Consumer createConsumer(Processor processor) throws Exception { + // make sure inBody is not set for consumers + if (inBody != null) { + throw new IllegalArgumentException("Option inBody is not supported for consumer endpoint"); + } + final BraintreeConsumer consumer = new BraintreeConsumer(this, processor); + // also set consumer.* properties + configureConsumer(consumer); + return consumer; + } + + @Override + protected ApiMethodPropertiesHelper<BraintreeConfiguration> getPropertiesHelper() { + return BraintreePropertiesHelper.getHelper(); + } + + @Override + protected String getThreadProfileName() { + return BraintreeConstants.THREAD_PROFILE_NAME; + } + + @Override + protected void afterConfigureProperties() { + try { + Method method = gateway.getClass().getMethod(apiName.getName()); + if (method != null) { + apiProxy = method.invoke(gateway); + } else { + throw new IllegalArgumentException("Invalid API name " + apiName); + } + } catch (NoSuchMethodException e) { + throw new IllegalArgumentException(e); + } catch (InvocationTargetException e) { + throw new IllegalArgumentException(e); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } + } + + @Override + public Object getApiProxy(ApiMethod method, Map<String, Object> args) { + return apiProxy; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeProducer.java b/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeProducer.java new file mode 100644 index 0000000..3db8795 --- /dev/null +++ b/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/BraintreeProducer.java @@ -0,0 +1,31 @@ +/** + * 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.braintree; + + +import org.apache.camel.component.braintree.internal.BraintreeApiName; +import org.apache.camel.component.braintree.internal.BraintreePropertiesHelper; +import org.apache.camel.util.component.AbstractApiProducer; + +/** + * The Braintree producer. + */ +public class BraintreeProducer extends AbstractApiProducer<BraintreeApiName, BraintreeConfiguration> { + public BraintreeProducer(BraintreeEndpoint endpoint) { + super(endpoint, BraintreePropertiesHelper.getHelper()); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/internal/BraintreeConstants.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/internal/BraintreeConstants.java b/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/internal/BraintreeConstants.java new file mode 100644 index 0000000..00b2241 --- /dev/null +++ b/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/internal/BraintreeConstants.java @@ -0,0 +1,29 @@ +/** + * 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.braintree.internal; + +/** + * Constants for Braintree component. + */ +public interface BraintreeConstants { + + // suffix for parameters when passed as exchange header properties + String PROPERTY_PREFIX = "CamelBraintree."; + + // thread profile name for this component + String THREAD_PROFILE_NAME = "CamelBraintree"; +} http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/internal/BraintreePropertiesHelper.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/internal/BraintreePropertiesHelper.java b/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/internal/BraintreePropertiesHelper.java new file mode 100644 index 0000000..873428c --- /dev/null +++ b/components/camel-braintree/src/main/java/org/apache/camel/component/braintree/internal/BraintreePropertiesHelper.java @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.braintree.internal; + +import org.apache.camel.component.braintree.BraintreeConfiguration; +import org.apache.camel.util.component.ApiMethodPropertiesHelper; + +/** + * Singleton {@link ApiMethodPropertiesHelper} for Braintree component. + */ +public final class BraintreePropertiesHelper extends ApiMethodPropertiesHelper<BraintreeConfiguration> { + + private static BraintreePropertiesHelper helper; + + private BraintreePropertiesHelper() { + super(BraintreeConfiguration.class, BraintreeConstants.PROPERTY_PREFIX); + } + + public static synchronized BraintreePropertiesHelper getHelper() { + if (helper == null) { + helper = new BraintreePropertiesHelper(); + } + return helper; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/main/resources/META-INF/services/org/apache/camel/component/braintree ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/main/resources/META-INF/services/org/apache/camel/component/braintree b/components/camel-braintree/src/main/resources/META-INF/services/org/apache/camel/component/braintree new file mode 100644 index 0000000..cb28621 --- /dev/null +++ b/components/camel-braintree/src/main/resources/META-INF/services/org/apache/camel/component/braintree @@ -0,0 +1,18 @@ +# +# 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. +# + +class=org.apache.camel.component.braintree.BraintreeComponent http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/AbstractBraintreeTestSupport.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/AbstractBraintreeTestSupport.java b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/AbstractBraintreeTestSupport.java new file mode 100644 index 0000000..33bbc9e --- /dev/null +++ b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/AbstractBraintreeTestSupport.java @@ -0,0 +1,159 @@ +/** + * 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.braintree; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import com.braintreegateway.BraintreeGateway; +import org.apache.camel.CamelContext; +import org.apache.camel.CamelExecutionException; +import org.apache.camel.component.braintree.internal.BraintreeApiCollection; +import org.apache.camel.component.braintree.internal.BraintreeApiName; +import org.apache.camel.component.braintree.internal.BraintreeConstants; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.apache.camel.util.IntrospectionSupport; +import org.apache.camel.util.component.ApiMethod; +import org.apache.commons.lang3.StringUtils; + +/** + * Abstract base class for Braintree Integration tests generated by Camel API component maven plugin. + */ +public class AbstractBraintreeTestSupport extends CamelTestSupport { + + private static final String TEST_OPTIONS_PROPERTIES = "/test-options.properties"; + + private BraintreeGateway gateway; + + protected AbstractBraintreeTestSupport() { + this.gateway = null; + } + + @Override + protected CamelContext createCamelContext() throws Exception { + + final CamelContext context = super.createCamelContext(); + + // read Braintree component configuration from TEST_OPTIONS_PROPERTIES + final Properties properties = new Properties(); + try { + properties.load(getClass().getResourceAsStream(TEST_OPTIONS_PROPERTIES)); + } catch (Exception e) { + throw new IOException(String.format("%s could not be loaded: %s", TEST_OPTIONS_PROPERTIES, e.getMessage()), e); + } + + Map<String, Object> options = new HashMap<>(); + for (Map.Entry<Object, Object> entry : properties.entrySet()) { + options.put(entry.getKey().toString(), entry.getValue()); + } + + addOptionIfMissing(options, "environment", "CAMEL_BRAINTREE_ENVIRONMENT"); + addOptionIfMissing(options, "merchantId" , "CAMEL_BRAINTREE_MERCHANT_ID"); + addOptionIfMissing(options, "publicKey" , "CAMEL_BRAINTREE_PUBLIC_KEY"); + addOptionIfMissing(options, "privateKey" , "CAMEL_BRAINTREE_PRIVATE_KEY"); + + final BraintreeConfiguration configuration = new BraintreeConfiguration(); + IntrospectionSupport.setProperties(configuration, options); + + // add BraintreeComponent to Camel context + final BraintreeComponent component = new BraintreeComponent(context); + component.setConfiguration(configuration); + context.addComponent("braintree", component); + + return context; + } + + protected void addOptionIfMissing(Map<String, Object> options, String name, String envName) { + if (!options.containsKey(name)) { + String value = System.getenv(envName); + if (StringUtils.isNotBlank(value)) { + options.put(name, value); + } + } + } + + @Override + public boolean isCreateCamelContextPerClass() { + // only create the context once for this class + return false; + } + + @SuppressWarnings("unchecked") + protected <T> T requestBodyAndHeaders(String endpointUri, Object body, Map<String, Object> headers) + throws CamelExecutionException { + return (T) template().requestBodyAndHeaders(endpointUri, body, headers); + } + + protected <T> T requestBodyAndHeaders(String endpointUri, Object body, Map<String, Object> headers, Class<T> type) + throws CamelExecutionException { + return template().requestBodyAndHeaders(endpointUri, body, headers, type); + } + + @SuppressWarnings("unchecked") + protected <T> T requestBody(String endpoint, Object body) throws CamelExecutionException { + return (T) template().requestBody(endpoint, body); + } + + protected <T> T requestBody(String endpoint, Object body, Class<T> type) throws CamelExecutionException { + return template().requestBody(endpoint, body, type); + } + + protected static BraintreeApiName getApiName(Class<? extends ApiMethod> apiMethod) { + return BraintreeApiCollection.getCollection().getApiName(apiMethod); + } + + protected static String getApiNameAsString(Class<? extends ApiMethod> apiMethod) { + return getApiName(apiMethod).getName(); + } + + protected final BraintreeComponent getBraintreeComponent() { + return (BraintreeComponent)context().getComponent("braintree"); + } + + protected final synchronized BraintreeGateway getGateway() { + if (gateway == null) { + gateway = getBraintreeComponent().getConfiguration().newBraintreeGateway(); + } + + return gateway; + } + + protected final class BraintreeHeaderBuilder { + private final Map<String, Object> headers; + + public BraintreeHeaderBuilder() { + headers = new HashMap<>(); + } + + public BraintreeHeaderBuilder add(String key, Object value) { + if (key.startsWith(BraintreeConstants.PROPERTY_PREFIX)) { + headers.put(key, value); + } else { + headers.put(BraintreeConstants.PROPERTY_PREFIX + key, value); + } + + return this; + } + + public Map<String, Object> build() { + return Collections.unmodifiableMap(headers); + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/AddOnGatewayIntegrationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/AddOnGatewayIntegrationTest.java b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/AddOnGatewayIntegrationTest.java new file mode 100644 index 0000000..ecf9c02 --- /dev/null +++ b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/AddOnGatewayIntegrationTest.java @@ -0,0 +1,53 @@ +/** + * 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.braintree; + +import java.util.List; + +import com.braintreegateway.AddOn; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.braintree.internal.AddOnGatewayApiMethod; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AddOnGatewayIntegrationTest extends AbstractBraintreeTestSupport { + + private static final Logger LOG = LoggerFactory.getLogger(AddOnGatewayIntegrationTest.class); + private static final String PATH_PREFIX = getApiNameAsString(AddOnGatewayApiMethod.class); + + @Ignore + @Test + public void testAll() throws Exception { + final List<AddOn> result = requestBody("direct://ALL", null, List.class); + + assertNotNull("all result", result); + LOG.debug("all: " + result); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() { + // test route for all + from("direct://ALL") + .to("braintree://" + PATH_PREFIX + "/all"); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/AddressGatewayIntegrationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/AddressGatewayIntegrationTest.java b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/AddressGatewayIntegrationTest.java new file mode 100644 index 0000000..e88b3f7 --- /dev/null +++ b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/AddressGatewayIntegrationTest.java @@ -0,0 +1,231 @@ +/** + * 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.braintree; + +import java.util.List; +import java.util.UUID; + +import com.braintreegateway.Address; +import com.braintreegateway.AddressRequest; +import com.braintreegateway.BraintreeGateway; +import com.braintreegateway.Customer; +import com.braintreegateway.CustomerRequest; +import com.braintreegateway.Result; +import com.google.common.collect.Lists; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.braintree.internal.AddressGatewayApiMethod; +import org.apache.camel.component.braintree.internal.BraintreeApiCollection; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class AddressGatewayIntegrationTest extends AbstractBraintreeTestSupport { + + private static final Logger LOG = LoggerFactory.getLogger(AddressGatewayIntegrationTest.class); + private static final String PATH_PREFIX = BraintreeApiCollection.getCollection().getApiName(AddressGatewayApiMethod.class).getName(); + + + private BraintreeGateway gateway; + private Customer customer; + private final List<String> addressIds; + + // ************************************************************************* + // + // ************************************************************************* + + public AddressGatewayIntegrationTest() { + this.customer = null; + this.gateway = null; + this.addressIds = Lists.newLinkedList(); + } + + @Override + protected void doPostSetup() throws Exception { + this.gateway = getGateway(); + this.customer = gateway.customer().create( + new CustomerRequest() + .firstName("user") + .lastName(UUID.randomUUID().toString()) + ).getTarget(); + + if (customer != null) { + LOG.info("Customer created - id={}", this.customer.getId()); + } + } + + @Override + public void tearDown() throws Exception { + if (this.gateway != null && customer != null) { + for (String id : this.addressIds) { + if (this.gateway.address().delete(customer.getId(), id).isSuccess()) { + LOG.info("Address deleted - customer={}, id={}", customer.getId(), id); + } else { + LOG.warn("Unable to delete address - customer={}, id={}", customer.getId(), id); + } + } + + this.addressIds.clear(); + + if (this.gateway.customer().delete(this.customer.getId()).isSuccess()) { + LOG.info("Customer deleted - id={}", this.customer.getId()); + } else { + LOG.warn("Unable to delete customer - id={}", this.customer.getId()); + } + } + } + + private Address createAddress() { + // Create address + final Result<Address> result = gateway.address().create( + this.customer.getId(), + new AddressRequest() + .company("Apache") + .streetAddress("1901 Munsey Drive") + .locality("Forest Hill") + ); + + assertNotNull("create", result); + assertTrue(result.isSuccess()); + + LOG.info("Address created - customer={}, id={}", this.customer.getId(), result.getTarget().getId()); + + return result.getTarget(); + } + + // ************************************************************************* + // + // ************************************************************************* + + @Test + public void testCreate() throws Exception { + assertNotNull("BraintreeGateway can't be null", this.gateway); + assertNotNull("Customer can't be null", this.customer); + + final Result<Address> address = requestBodyAndHeaders( + "direct://CREATE", + null, + new BraintreeHeaderBuilder() + .add("customerId", customer.getId()) + .add("request", new AddressRequest() + .company("Apache") + .streetAddress("1901 Munsey Drive") + .locality("Forest Hill")) + .build(), + Result.class + ); + + assertNotNull("create", address); + assertTrue(address.isSuccess()); + + LOG.info("Address created - customer={}, id={}", customer.getId(), address.getTarget().getId()); + this.addressIds.add(address.getTarget().getId()); + } + + @Test + public void testDelete() throws Exception { + assertNotNull("BraintreeGateway can't be null", this.gateway); + assertNotNull("Customer can't be null", this.customer); + + final Address address = createAddress(); + final Result<Address> result = requestBodyAndHeaders( + "direct://DELETE", + null, + new BraintreeHeaderBuilder() + .add("customerId", customer.getId()) + .add("id", address.getId()) + .build(), + Result.class + ); + + assertNotNull("delete", address); + assertTrue(result.isSuccess()); + + LOG.info("Address deleted - customer={}, id={}", customer.getId(), address.getId()); + } + + @Test + public void testFind() throws Exception { + assertNotNull("BraintreeGateway can't be null", this.gateway); + assertNotNull("Customer can't be null", this.customer); + + final Address addressRef = createAddress(); + this.addressIds.add(addressRef.getId()); + + final Address address = requestBodyAndHeaders( + "direct://FIND", null, + new BraintreeHeaderBuilder() + .add("customerId", customer.getId()) + .add("id", addressRef.getId()) + .build(), + Address.class + ); + + assertNotNull("find", address); + LOG.info("Address found - customer={}, id={}", customer.getId(), address.getId()); + } + + @Test + public void testUpdate() throws Exception { + assertNotNull("BraintreeGateway can't be null", this.gateway); + assertNotNull("Customer can't be null", this.customer); + + final Address addressRef = createAddress(); + this.addressIds.add(addressRef.getId()); + + final Result<Address> result = requestBodyAndHeaders( + "direct://UPDATE", null, + new BraintreeHeaderBuilder() + .add("customerId", customer.getId()) + .add("id", addressRef.getId()) + .add("request", new AddressRequest() + .company("Apache") + .streetAddress(customer.getId()) + .locality(customer.getId())) + .build(), + Result.class); + + assertNotNull("update", result); + assertTrue(result.isSuccess()); + + LOG.info("Address updated - customer={}, id={}", customer.getId(), result.getTarget().getId()); + } + + // ************************************************************************* + // Routes + // ************************************************************************* + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() { + // test route for create + from("direct://CREATE") + .to("braintree://" + PATH_PREFIX + "/create"); + // test route for delete + from("direct://DELETE") + .to("braintree://" + PATH_PREFIX + "/delete"); + // test route for find + from("direct://FIND") + .to("braintree://" + PATH_PREFIX + "/find"); + // test route for update + from("direct://UPDATE") + .to("braintree://" + PATH_PREFIX + "/update"); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/ClientTokenGatewayIntegrationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/ClientTokenGatewayIntegrationTest.java b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/ClientTokenGatewayIntegrationTest.java new file mode 100644 index 0000000..b16075a --- /dev/null +++ b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/ClientTokenGatewayIntegrationTest.java @@ -0,0 +1,48 @@ +/** + * 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.braintree; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.braintree.internal.ClientTokenGatewayApiMethod; +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class ClientTokenGatewayIntegrationTest extends AbstractBraintreeTestSupport { + + private static final String PATH_PREFIX = getApiNameAsString(ClientTokenGatewayApiMethod.class); + private static final Logger LOG = LoggerFactory.getLogger(ClientTokenGatewayIntegrationTest.class); + + @Test + public void testClientTokenGeneration() throws Exception { + final String token = requestBody("direct://GENERATE", null, String.class); + + assertTrue(StringUtils.isNotBlank(token)); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() { + from("direct://GENERATE") + .to("braintree://" + PATH_PREFIX + "/generate"); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/CreditCardVerificationGatewayIntegrationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/CreditCardVerificationGatewayIntegrationTest.java b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/CreditCardVerificationGatewayIntegrationTest.java new file mode 100644 index 0000000..b32c135 --- /dev/null +++ b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/CreditCardVerificationGatewayIntegrationTest.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.braintree; + +import com.braintreegateway.CreditCardVerification; +import com.braintreegateway.ResourceCollection; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.braintree.internal.BraintreeApiCollection; +import org.apache.camel.component.braintree.internal.CreditCardVerificationGatewayApiMethod; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CreditCardVerificationGatewayIntegrationTest extends AbstractBraintreeTestSupport { + + private static final Logger LOG = LoggerFactory.getLogger(CreditCardVerificationGatewayIntegrationTest.class); + private static final String PATH_PREFIX = BraintreeApiCollection.getCollection().getApiName(CreditCardVerificationGatewayApiMethod.class).getName(); + + // TODO provide parameter values for find + @Ignore + @Test + public void testFind() throws Exception { + // using String message body for single parameter "id" + final CreditCardVerification result = requestBody("direct://FIND", null, CreditCardVerification.class); + + assertNotNull("find result", result); + LOG.debug("find: " + result); + } + + // TODO provide parameter values for search + @Ignore + @Test + public void testSearch() throws Exception { + // using com.braintreegateway.CreditCardVerificationSearchRequest message body for single parameter "query" + final ResourceCollection<CreditCardVerification> result = requestBody("direct://SEARCH", null, ResourceCollection.class); + + assertNotNull("search result", result); + LOG.debug("search: " + result); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() { + // test route for find + from("direct://FIND") + .to("braintree://" + PATH_PREFIX + "/find?inBody=id"); + // test route for search + from("direct://SEARCH") + .to("braintree://" + PATH_PREFIX + "/search?inBody=query"); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/CustomerGatewayIntegrationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/CustomerGatewayIntegrationTest.java b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/CustomerGatewayIntegrationTest.java new file mode 100644 index 0000000..92b2f75 --- /dev/null +++ b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/CustomerGatewayIntegrationTest.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.braintree; + +import java.util.HashMap; +import java.util.UUID; + +import com.braintreegateway.Customer; +import com.braintreegateway.CustomerRequest; +import com.braintreegateway.CustomerSearchRequest; +import com.braintreegateway.ResourceCollection; +import com.braintreegateway.Result; +import com.braintreegateway.ValidationError; +import com.braintreegateway.ValidationErrorCode; +import com.braintreegateway.ValidationErrors; +import com.braintreegateway.exceptions.NotFoundException; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import org.apache.camel.CamelExecutionException; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.braintree.internal.CustomerGatewayApiMethod; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class CustomerGatewayIntegrationTest extends AbstractBraintreeTestSupport { + + private static final String PATH_PREFIX = getApiNameAsString(CustomerGatewayApiMethod.class); + private static final Logger LOG = LoggerFactory.getLogger(CustomerGatewayIntegrationTest.class); + + /** + * Customers management workflow: + * - create a customer + * - lookup by id + * - update first name + * - delete by id + * - confirm deletion by searching again + * + * @throws Exception + */ + @Test + public void testCustomerManagementWorkflow() throws Exception { + String customerLastName = UUID.randomUUID().toString(); + String customerId = null; + + // Create customer + Result<Customer> createResult = requestBody( + "direct://CREATE_IN_BODY", + new CustomerRequest() + .firstName("user") + .lastName(customerLastName) + .company("Apache") + .email("user@braintree.camel") + .website("http://user.braintree.camel"), + Result.class + ); + + assertNotNull(createResult); + assertTrue(createResult.isSuccess()); + assertNotNull(createResult.getTarget()); + assertNotNull(createResult.getTarget().getId()); + + customerId = createResult.getTarget().getId(); + + // Find customer by ID + Customer customer1 = requestBody("direct://FIND_IN_BODY", customerId, Customer.class); + assertNotNull(customer1); + assertEquals("user", customer1.getFirstName()); + assertEquals(customerLastName, customer1.getLastName()); + assertEquals("Apache", customer1.getCompany()); + assertEquals("user@braintree.camel", customer1.getEmail()); + assertEquals("http://user.braintree.camel", customer1.getWebsite()); + + // Update customer + HashMap<String, Object> headers = new HashMap<>(); + headers.put("CamelBraintree.id", customerId); + Result<Customer> updateResult = requestBodyAndHeaders( + "direct://UPDATE_IN_BODY", + new CustomerRequest().firstName("user-mod"), + headers, + Result.class + ); + + assertNotNull(updateResult); + assertTrue(updateResult.isSuccess()); + assertNotNull(updateResult.getTarget()); + assertEquals("user-mod", updateResult.getTarget().getFirstName()); + + // Delete customer + Result<Customer> customerResult = requestBody("direct://DELETE_IN_BODY", customerId, Result.class); + assertNotNull(customerResult); + assertTrue(customerResult.isSuccess()); + assertNull(customerResult.getTarget()); + + // Check if customer has been deleted customer + ResourceCollection<Customer> customers = requestBody( + "direct://SEARCH_IN_BODY", + new CustomerSearchRequest().id().is(customerId), + ResourceCollection.class + ); + + assertNotNull(customers); + assertEquals(0, customers.getMaximumSize()); + } + + @Test + public void testUpdateUnknownCustomer() throws Exception { + try { + String id = "unknown-" + UUID.randomUUID().toString(); + + HashMap<String, Object> headers = new HashMap<>(); + headers.put("CamelBraintree.id", id); + + requestBodyAndHeaders("direct://UPDATE_IN_BODY", + new CustomerRequest().firstName(id), + headers); + + fail("Should have thrown NotFoundException"); + } catch (CamelExecutionException e) { + assertIsInstanceOf(NotFoundException.class, e.getCause().getCause()); + } + } + + @Test + public void testSearchUnknownCustomer() throws Exception { + try { + requestBody("direct://FIND_IN_BODY", "unknown-" + UUID.randomUUID().toString()); + fail("Should have thrown NotFoundException"); + } catch (CamelExecutionException e) { + assertIsInstanceOf(NotFoundException.class, e.getCause().getCause()); + } + } + + @Test + public void testWrongCustomerCreateRequest() throws Exception { + // Create customer + Result<Customer> createResult = requestBody( + "direct://CREATE_IN_BODY", + new CustomerRequest() + .firstName("user") + .lastName(UUID.randomUUID().toString()) + .company("Apache") + .email("wrongEmail") + .website("http://user.braintree.camel"), + Result.class + ); + + assertNotNull(createResult); + assertFalse(createResult.isSuccess()); + + + final ValidationErrors errors = createResult.getErrors(); + assertNotNull(errors); + assertNotNull(errors.getAllDeepValidationErrors()); + + assertNotNull(Iterables.find(errors.getAllDeepValidationErrors(), new Predicate<ValidationError>() { + @Override + public boolean apply(ValidationError o) { + return o.getCode() == ValidationErrorCode.CUSTOMER_EMAIL_FORMAT_IS_INVALID; + } + } + )); + } + + // ************************************************************************* + // Routes + // ************************************************************************* + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() { + from("direct://CREATE_IN_BODY") + .to("braintree://" + PATH_PREFIX + "/create?inBody=request"); + from("direct://DELETE_IN_BODY") + .to("braintree://" + PATH_PREFIX + "/delete?inBody=id"); + from("direct://FIND_IN_BODY") + .to("braintree://" + PATH_PREFIX + "/find?inBody=id"); + from("direct://SEARCH_IN_BODY") + .to("braintree://" + PATH_PREFIX + "/search?inBody=query"); + from("direct://UPDATE_IN_BODY") + .to("braintree://" + PATH_PREFIX + "/update?inBody=request"); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/DiscountGatewayIntegrationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/DiscountGatewayIntegrationTest.java b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/DiscountGatewayIntegrationTest.java new file mode 100644 index 0000000..a0056c3 --- /dev/null +++ b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/DiscountGatewayIntegrationTest.java @@ -0,0 +1,54 @@ +/** + * 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.braintree; + +import java.util.List; + +import com.braintreegateway.Discount; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.braintree.internal.BraintreeApiCollection; +import org.apache.camel.component.braintree.internal.DiscountGatewayApiMethod; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DiscountGatewayIntegrationTest extends AbstractBraintreeTestSupport { + + private static final Logger LOG = LoggerFactory.getLogger(DiscountGatewayIntegrationTest.class); + private static final String PATH_PREFIX = BraintreeApiCollection.getCollection().getApiName(DiscountGatewayApiMethod.class).getName(); + + @Ignore + @Test + public void testAll() throws Exception { + final List<Discount> result = requestBody("direct://ALL", null, List.class); + + assertNotNull("all result", result); + LOG.debug("all: " + result); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() { + // test route for all + from("direct://ALL") + .to("braintree://" + PATH_PREFIX + "/all"); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/e8b00192/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/MerchantAccountGatewayIntegrationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/MerchantAccountGatewayIntegrationTest.java b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/MerchantAccountGatewayIntegrationTest.java new file mode 100644 index 0000000..7d833cd --- /dev/null +++ b/components/camel-braintree/src/test/java/org/apache/camel/component/braintree/MerchantAccountGatewayIntegrationTest.java @@ -0,0 +1,111 @@ +/** + * 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.braintree; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import com.braintreegateway.MerchantAccount; +import com.braintreegateway.MerchantAccountRequest; +import com.braintreegateway.Result; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.braintree.internal.BraintreeApiCollection; +import org.apache.camel.component.braintree.internal.BraintreeConstants; +import org.apache.camel.component.braintree.internal.MerchantAccountGatewayApiMethod; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MerchantAccountGatewayIntegrationTest extends AbstractBraintreeTestSupport { + + private static final Logger LOG = LoggerFactory.getLogger(MerchantAccountGatewayIntegrationTest.class); + private static final String PATH_PREFIX = BraintreeApiCollection.getCollection().getApiName(MerchantAccountGatewayApiMethod.class).getName(); + + @Ignore + @Test + public void testCreate() throws Exception { + final String merchantId = UUID.randomUUID().toString(); + final Result<MerchantAccount> result = requestBody("direct://CREATE", + new MerchantAccountRequest() + .masterMerchantAccountId(System.getenv("CAMEL_BRAINTREE_MERCHANT_ACCOUNT_ID")) + .individual() + .firstName("merchant") + .lastName(merchantId) + .address() + .streetAddress("my street") + .done() + .done() + , Result.class + ); + + assertNotNull("create result", result); + assertTrue(result.isSuccess()); + } + + @Ignore + @Test + public void testFind() throws Exception { + final Map<String, Object> headers = new HashMap<>(); + headers.put(BraintreeConstants.PROPERTY_PREFIX + "id", System.getenv("CAMEL_BRAINTREE_MERCHANT_ACCOUNT_ID")); + final MerchantAccount result = requestBodyAndHeaders("direct://FIND", null, headers, MerchantAccount.class); + + assertNotNull("find result", result); + } + + @Ignore + @Test + public void testUpdate() throws Exception { + final Map<String, Object> headers = new HashMap<>(); + headers.put(BraintreeConstants.PROPERTY_PREFIX + "id", System.getenv("CAMEL_BRAINTREE_MERCHANT_ACCOUNT_ID")); + + final Result<MerchantAccount> result = requestBodyAndHeaders("direct://UPDATE", + new MerchantAccountRequest() + .individual() + .address() + .streetAddress("my new street address") + .done() + .done(), + headers, + Result.class); + + assertNotNull("update result", result); + assertTrue(result.isSuccess()); + } + + // ************************************************************************* + // Routes + // ************************************************************************* + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() { + // test route for create + from("direct://CREATE") + .to("braintree://" + PATH_PREFIX + "/create?inBody=request"); + // test route for find + from("direct://FIND") + .to("braintree://" + PATH_PREFIX + "/find"); + // test route for update + from("direct://UPDATE") + .to("braintree://" + PATH_PREFIX + "/update?inBody=request"); + } + }; + } +}