Polished
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/58515451 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/58515451 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/58515451 Branch: refs/heads/master Commit: 585154511947c0ddf2674e1e44fc0f85db7f9311 Parents: 1c79846 Author: Claus Ibsen <davscl...@apache.org> Authored: Wed Mar 23 19:41:18 2016 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Wed Mar 23 19:41:18 2016 +0100 ---------------------------------------------------------------------- apache-camel/pom.xml | 4 + .../src/main/descriptors/common-bin.xml | 1 + components/camel-cm-sms/README.md | 32 ++ components/camel-cm-sms/pom.xml | 106 ++++++ .../apache/camel/component/cm/CMComponent.java | 96 +++++ .../camel/component/cm/CMConfiguration.java | 89 +++++ .../apache/camel/component/cm/CMConstants.java | 44 +++ .../apache/camel/component/cm/CMEndpoint.java | 109 ++++++ .../apache/camel/component/cm/CMMessage.java | 153 ++++++++ .../apache/camel/component/cm/CMProducer.java | 149 ++++++++ .../org/apache/camel/component/cm/CMSender.java | 28 ++ .../component/cm/CMSenderOneMessageImpl.java | 254 +++++++++++++ .../org/apache/camel/component/cm/CMUtils.java | 30 ++ .../camel/component/cm/client/SMSMessage.java | 114 ++++++ .../camel/component/cm/client/Translator.java | 23 ++ .../cm/exceptions/CMDirectException.java | 40 ++ .../cm/exceptions/HostUnavailableException.java | 39 ++ .../cm/exceptions/XMLConstructionException.java | 39 ++ .../cmresponse/CMResponseException.java | 41 ++ .../InsufficientBalanceException.java | 26 ++ .../cmresponse/InvalidMSISDNException.java | 23 ++ .../InvalidProductTokenException.java | 26 ++ .../NoAccountFoundForProductTokenException.java | 28 ++ .../cmresponse/NoMessageException.java | 23 ++ .../NotPhoneNumberFoundException.java | 23 ++ .../cmresponse/UnknownErrorException.java | 26 ++ .../cmresponse/UnroutableMessageException.java | 23 ++ .../cm/validation/constraints/E164.java | 41 ++ .../validation/constraints/E164Validator.java | 66 ++++ .../services/org/apache/camel/component/cm-sms | 18 + .../src/main/resources/log4j.properties | 41 ++ .../component/cm/test/CMConfigurationTest.java | 142 +++++++ .../camel/component/cm/test/CMMessageTest.java | 323 ++++++++++++++++ .../apache/camel/component/cm/test/CMProxy.java | 26 ++ .../apache/camel/component/cm/test/CMTest.java | 375 +++++++++++++++++++ .../cm/test/CamelTestConfiguration.java | 110 ++++++ .../camel/component/cm/test/SMSMessageTest.java | 183 +++++++++ .../cm/test/ValidatorConfiguration.java | 35 ++ .../cmsender/CMResponseExceptionSender.java | 30 ++ .../InsufficientBalanceExceptionSender.java | 30 ++ .../cmsender/InvalidMSISDNExceptionSender.java | 30 ++ .../InvalidProductTokenExceptionSender.java | 30 ++ ...ountFoundForProductTokenExceptionSender.java | 30 ++ .../cmsender/NoMessageExceptionSender.java | 30 ++ .../NotPhoneNumberFoundExceptionSender.java | 30 ++ .../cmsender/UnknownErrorExceptionSender.java | 30 ++ .../UnroutableMessageExceptionSender.java | 30 ++ .../src/test/resources/cm-smsgw.properties | 28 ++ components/camel-cm/README.md | 32 -- components/camel-cm/pom.xml | 105 ------ .../apache/camel/component/cm/CMComponent.java | 99 ----- .../camel/component/cm/CMConfiguration.java | 92 ----- .../apache/camel/component/cm/CMConstants.java | 44 --- .../apache/camel/component/cm/CMEndpoint.java | 141 ------- .../apache/camel/component/cm/CMMessage.java | 153 -------- .../apache/camel/component/cm/CMProducer.java | 149 -------- .../org/apache/camel/component/cm/CMSender.java | 28 -- .../component/cm/CMSenderOneMessageImpl.java | 254 ------------- .../org/apache/camel/component/cm/CMUtils.java | 30 -- .../camel/component/cm/client/SMSMessage.java | 114 ------ .../camel/component/cm/client/Translator.java | 23 -- .../cm/exceptions/CMDirectException.java | 40 -- .../cm/exceptions/HostUnavailableException.java | 39 -- .../cm/exceptions/XMLConstructionException.java | 39 -- .../cmresponse/CMResponseException.java | 41 -- .../InsufficientBalanceException.java | 26 -- .../cmresponse/InvalidMSISDNException.java | 23 -- .../InvalidProductTokenException.java | 26 -- .../NoAccountFoundForProductTokenException.java | 28 -- .../cmresponse/NoMessageException.java | 23 -- .../NotPhoneNumberFoundException.java | 23 -- .../cmresponse/UnknownErrorException.java | 26 -- .../cmresponse/UnroutableMessageException.java | 23 -- .../cm/validation/constraints/E164.java | 41 -- .../validation/constraints/E164Validator.java | 66 ---- .../services/org/apache/camel/component/cm | 18 - .../src/main/resources/log4j.properties | 37 -- .../component/cm/test/CMConfigurationTest.java | 142 ------- .../camel/component/cm/test/CMMessageTest.java | 323 ---------------- .../apache/camel/component/cm/test/CMProxy.java | 26 -- .../apache/camel/component/cm/test/CMTest.java | 363 ------------------ .../cm/test/CamelTestConfiguration.java | 112 ------ .../camel/component/cm/test/SMSMessageTest.java | 183 --------- .../cm/test/ValidatorConfiguration.java | 35 -- .../cmsender/CMResponseExceptionSender.java | 30 -- .../InsufficientBalanceExceptionSender.java | 30 -- .../cmsender/InvalidMSISDNExceptionSender.java | 30 -- .../InvalidProductTokenExceptionSender.java | 30 -- ...ountFoundForProductTokenExceptionSender.java | 30 -- .../cmsender/NoMessageExceptionSender.java | 30 -- .../NotPhoneNumberFoundExceptionSender.java | 30 -- .../cmsender/UnknownErrorExceptionSender.java | 30 -- .../UnroutableMessageExceptionSender.java | 30 -- .../src/test/resources/cm-smsgw.properties | 28 -- components/pom.xml | 2 +- parent/pom.xml | 5 + 96 files changed, 3253 insertions(+), 3266 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/apache-camel/pom.xml ---------------------------------------------------------------------- diff --git a/apache-camel/pom.xml b/apache-camel/pom.xml index db97d20..b92593e 100644 --- a/apache-camel/pom.xml +++ b/apache-camel/pom.xml @@ -153,6 +153,10 @@ </dependency> <dependency> <groupId>org.apache.camel</groupId> + <artifactId>camel-cm-sms</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> <artifactId>camel-cmis</artifactId> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/apache-camel/src/main/descriptors/common-bin.xml ---------------------------------------------------------------------- diff --git a/apache-camel/src/main/descriptors/common-bin.xml b/apache-camel/src/main/descriptors/common-bin.xml index 3f43a8e..ae2c879 100644 --- a/apache-camel/src/main/descriptors/common-bin.xml +++ b/apache-camel/src/main/descriptors/common-bin.xml @@ -49,6 +49,7 @@ <include>org.apache.camel:camel-castor</include> <include>org.apache.camel:camel-cdi</include> <include>org.apache.camel:camel-chunk</include> + <include>org.apache.camel:camel-cm-sms</include> <include>org.apache.camel:camel-cmis</include> <include>org.apache.camel:camel-core</include> <include>org.apache.camel:camel-core-osgi</include> http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/README.md ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/README.md b/components/camel-cm-sms/README.md new file mode 100644 index 0000000..63f9059 --- /dev/null +++ b/components/camel-cm-sms/README.md @@ -0,0 +1,32 @@ +# camel-cm + +[Camel component](http://camel.apache.org/components.html) for the [CM SMS Gateway](https://www.cmtelecom.com). + +It allows to integrate [CM SMS API](https://dashboard.onlinesmsgateway.com/docs) in an application as a camel component. + +You must have a valid account. More information are available at [CM Telecom](https://www.cmtelecom.com/support). + +### URI Format + +``` +cm://sgw01.cm.nl/gateway.ashx?defaultFrom=DefaultSender&defaultMaxNumberOfParts=8&productToken=2fb82162-754c-4c1b-806d-9cb7efd677f4 +``` + + +### Endpoint Options + +CM endpoints act like a **producer** and support the following options. + +| Name | Default Value | Description | +| ------------- | ------------- | ------------- | +| productToken |*none* |**Required**. UUID as String. This is the product token that was sent to you by email. Example: 'de7c7df3-81ca-4d1e-863d-95a252120321'| +| defaultFrom | *none* |**Required**. This is the default sender name, to be included in each SMSMessage instance not providing one. The maximum length is 11 characters.| +| defaultMaxNumberOfParts | 8 | If it is a [multipart message](https://dashboard.onlinesmsgateway.com/docs#send-a-message-multipart) forces the max number of parts to be sent. <p>The gateway will first check if a message is larger than 160 characters, if so, the message will be cut into multiple 153 characters parts limited by these parameters whether the message is [GSM 0038 encodeable](https://en.wikipedia.org/wiki/GSM_03.38). <p>Otherwise, The gateway will check if a message is larger than 70 characters, if so, the message will be cut into multiple 67 characters parts to a maximum of this parameter.| +| testConnectionOnStartup | false | This ensures that Camel is not started with failed connections cause an exception is thrown on startup. | + +### Tests + +Tests provided so far show a valid [Spring Configuration](https://github.com/oalles/camel-cm/blob/master/src/test/java/org/apache/camel/component/cm/test/TestConfiguration.java). Notice that CM Component URI is built from properties in a [file](https://github.com/oalles/camel-cm/blob/master/src/test/resources/cm-smsgw.properties). + +### Sample of Usage +You can try [this project](https://github.com/oalles/camel-cm-sample) to see how camel-cm can be integrated in a camel route. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/pom.xml b/components/camel-cm-sms/pom.xml new file mode 100644 index 0000000..4200180 --- /dev/null +++ b/components/camel-cm-sms/pom.xml @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- + 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.18-SNAPSHOT</version> + </parent> + + <artifactId>camel-cm-sms</artifactId> + <packaging>bundle</packaging> + + <name>Camel :: CM SMS</name> + <description>Camel CM SMS Gateway Component</description> + + <properties> + <camel.osgi.export.pkg>org.apache.camel.component.cm.*</camel.osgi.export.pkg> + <camel.osgi.export.service>org.apache.camel.spi.ComponentResolver;component=cm-sms</camel.osgi.export.service> + </properties> + + <dependencies> + + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-core</artifactId> + </dependency> + + <dependency> + <groupId>com.googlecode.libphonenumber</groupId> + <artifactId>libphonenumber</artifactId> + <version>${libphonenumber-version}</version> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient-osgi</artifactId> + <version>${httpclient4-version}</version> + </dependency> + <dependency> + <groupId>org.jsoup</groupId> + <artifactId>jsoup</artifactId> + <version>${jsoup-version}</version> + </dependency> + + <dependency> + <groupId>javax.validation</groupId> + <artifactId>validation-api</artifactId> + <version>${validation-api-version}</version> + </dependency> + <dependency> + <groupId>javax.el</groupId> + <artifactId>javax.el-api</artifactId> + <version>${javax.el-api-version}</version> + </dependency> + <dependency> + <groupId>commons-validator</groupId> + <artifactId>commons-validator</artifactId> + <version>${commons-validator-version}</version> + </dependency> + + <!-- test dependencies --> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test-spring</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-spring-javaconfig</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-validator</artifactId> + <version>${hibernate-validator-version}</version> + <scope>test</scope> + </dependency> + </dependencies> +</project> http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMComponent.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMComponent.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMComponent.java new file mode 100644 index 0000000..73d1250 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMComponent.java @@ -0,0 +1,96 @@ +/** + * 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.cm; + +import java.util.Map; +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.Validator; + +import org.apache.camel.BeanInject; +import org.apache.camel.CamelContext; +import org.apache.camel.Endpoint; +import org.apache.camel.ResolveEndpointFailedException; +import org.apache.camel.impl.UriEndpointComponent; +import org.apache.camel.util.URISupport; +import org.apache.commons.validator.routines.UrlValidator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Represents the component that manages {@link CMEndpoint}s. + */ +public class CMComponent extends UriEndpointComponent { + + private static final Logger LOG = LoggerFactory.getLogger(CMComponent.class); + + // TODO: Must not rely on dependency injection as it should work out of the box + @BeanInject + private Validator validator; + + public CMComponent(final CamelContext context) { + super(context, CMEndpoint.class); + } + + /** + * Endpoints factory + */ + @Override + protected Endpoint createEndpoint(final String uri, final String remaining, final Map<String, Object> parameters) throws Exception { + + LOG.debug("Creating CM Endpoint ... "); + + final String url = CMConstants.DEFAULT_SCHEME + remaining; + if (!UrlValidator.getInstance().isValid(url)) { + throw new ResolveEndpointFailedException(uri, String.format("HOST provided: %s seem to be invalid. Remember SCHEME has to be excluded.", url)); + } + + LOG.debug("Uri=[{}], path=[{}], parameters=[{}]", new Object[] {URISupport.sanitizeUri(uri), URISupport.sanitizePath(remaining), parameters }); + + // Set configuration based on uri parameters + final CMConfiguration config = new CMConfiguration(); + setProperties(config, parameters); + + // Validate configuration + LOG.debug("Validating uri based configuration"); + final Set<ConstraintViolation<CMConfiguration>> constraintViolations = validator.validate(config); + if (constraintViolations.size() > 0) { + final StringBuffer msg = new StringBuffer(); + for (final ConstraintViolation<CMConfiguration> cv : constraintViolations) { + msg.append(String.format("- Invalid value for %s: %s", cv.getPropertyPath().toString(), cv.getMessage())); + } + throw new ResolveEndpointFailedException(uri, msg.toString()); + } + LOG.debug("CMConfiguration - OK!"); + + // Component is an Endpoint factory. So far, just one Endpoint type. + // Endpoint construction and configuration. + + LOG.debug("Creating CMEndpoint"); + final CMEndpoint endpoint = new CMEndpoint(uri, this); + endpoint.setConfiguration(config); + endpoint.setHost(remaining); + + return endpoint; + } + + public Validator getValidator() { + return validator; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMConfiguration.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMConfiguration.java new file mode 100644 index 0000000..74d75b0 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMConfiguration.java @@ -0,0 +1,89 @@ +/** + * 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.cm; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import org.apache.camel.spi.Metadata; +import org.apache.camel.spi.UriParam; +import org.apache.camel.spi.UriParams; + +@UriParams +public class CMConfiguration { + + @UriParam @Metadata(required = "true") + @NotNull + private String productToken; + @UriParam + @NotNull @Size(min = 1, max = 11) + private String defaultFrom; + @UriParam(defaultValue = "8") + @Min(1) @Max(8) + private int defaultMaxNumberOfParts = 8; + @UriParam + private boolean testConnectionOnStartup; + + public String getProductToken() { + return productToken; + } + + /** + * The unique token to use + */ + public void setProductToken(String productToken) { + this.productToken = productToken; + } + + public String getDefaultFrom() { + return defaultFrom; + } + + /** + * This is the sender name. The maximum length is 11 characters. + */ + public void setDefaultFrom(final String defaultFrom) { + this.defaultFrom = defaultFrom; + } + + public int getDefaultMaxNumberOfParts() { + return defaultMaxNumberOfParts; + } + + /** + * If it is a multipart message forces the max number. Message can be truncated. + * Technically the gateway will first check if a message is larger than 160 characters, + * if so, the message will be cut into multiple 153 characters parts limited by these parameters. + */ + public void setDefaultMaxNumberOfParts(final int defaultMaxNumberOfParts) { + this.defaultMaxNumberOfParts = defaultMaxNumberOfParts; + } + + public boolean isTestConnectionOnStartup() { + return testConnectionOnStartup; + } + + /** + * Whether to test the connection to the SMS Gateway on startup + */ + public void setTestConnectionOnStartup(final boolean testConnectionOnStartup) { + this.testConnectionOnStartup = testConnectionOnStartup; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMConstants.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMConstants.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMConstants.java new file mode 100644 index 0000000..afe8fde --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMConstants.java @@ -0,0 +1,44 @@ +/** + * 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.cm; + +public interface CMConstants { + + String DEFAULT_SCHEME = "https://"; + + int DEFAULT_MULTIPARTS = 8; + + int MAX_UNICODE_MESSAGE_LENGTH = 70; + int MAX_GSM_MESSAGE_LENGTH = 160; + int MAX_UNICODE_MESSAGE_LENGTH_PER_PART_IF_MULTIPART = 67; + int MAX_GSM_MESSAGE_LENGTH_PER_PART_IF_MULTIPART = 153; + + // status code 200 - Error substrings - check it contains. + String ERROR_UNKNOWN = "Unknown error"; + String ERROR_NO_ACCOUNT = "No account found"; + String ERROR_INSUFICIENT_BALANCE = "Insufficient balance"; + String ERROR_UNROUTABLE_MESSAGE = "Message is unroutable"; + String ERROR_INVALID_PRODUCT_TOKEN = "Invalid product token"; + + // TODO: Review this pattern. + // or it should be foundnd an alternative to jcharset to check if a message is GSM 03.38 encodable + // See: + // https://en.wikipedia.org/wiki/GSM_03.38 + // http://frightanic.com/software-development/regex-for-gsm-03-38-7bit-character-set/ + String GSM_0338_REGEX = "^[A-Za-z0-9 \\r\\n@£$\u0394_\u03A6\u0393\u039B\u03A9\u03A0\u03A8\u03A3\u0398\u039E!\"#$%&'()*+,\\-./:;<=>?¡¿^{}\\\\\\[~\\]|" + + "\u20AC\u00a5\u00e8\u00e9\u00f9\u00ec\u00f2\u00c7\u00d8\u00f8\u00c5\u00e5\u00c6\u00e6\u00df\u00c9\u00c4\u00d6\u00d1\u00dc\u00a7\u00e4\u00f6\u00f1\u00fc\u00e0]*$"; +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMEndpoint.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMEndpoint.java new file mode 100644 index 0000000..b290801 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMEndpoint.java @@ -0,0 +1,109 @@ +/** + * 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.cm; + +import java.util.UUID; + +import org.apache.camel.Consumer; +import org.apache.camel.ExchangePattern; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.impl.DefaultEndpoint; +import org.apache.camel.spi.Metadata; +import org.apache.camel.spi.UriEndpoint; +import org.apache.camel.spi.UriParam; +import org.apache.camel.spi.UriPath; +import org.apache.camel.util.ObjectHelper; + +@UriEndpoint(scheme = "cm-sms", title = "CM SMS Gateway", syntax = "cm-sms:host", label = "mobile", producerOnly = true) +public class CMEndpoint extends DefaultEndpoint { + + @UriPath + @Metadata(required = "true") + private String host; + @UriParam + private CMConfiguration configuration; + + public CMEndpoint(final String uri, final CMComponent component) { + super(uri, component); + setExchangePattern(ExchangePattern.InOut); + } + + /** + * Provides a channel on which clients can send Messages to a CM Endpoint + */ + @Override + public CMProducer createProducer() throws Exception { + final CMConfiguration config = getConfiguration(); + + // This is the camel exchange processor. Allows to send messages to CM + // API. + // TODO: Should i provide a CMSender factory? Dynamically choose + // CMSender implementation? Sending strategy? + // Consider: + // 1. single - Single Message strategy. + // 2. Multi - CM Api supports to 1000 messages per call. + // 3. sliding - sliding window? 1000 messages or time thresold? + // 4. mocked - in order to fake cm responses + + // CMConstants.DEFAULT_SCHEME + host is a valid URL. It was previously checked + + String token = config.getProductToken(); + ObjectHelper.notEmpty(token, "productToken"); + + UUID uuid = UUID.fromString(token); + return new CMProducer(this, new CMSenderOneMessageImpl(getCMUrl(), uuid)); + } + + @Override + public Consumer createConsumer(final Processor processor) throws Exception { + throw new UnsupportedOperationException("Consumer not supported"); + } + + public CMConfiguration getConfiguration() { + return configuration; + } + + public void setConfiguration(final CMConfiguration configuration) { + this.configuration = configuration; + } + + @Override + public boolean isSingleton() { + return true; + } + + public String getCMUrl() { + return CMConstants.DEFAULT_SCHEME + host; + } + + @Override + public CMComponent getComponent() { + return (CMComponent) super.getComponent(); + } + + public String getHost() { + return host; + } + + /** + * SMS Provider HOST with scheme + */ + public void setHost(final String host) { + this.host = host; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMMessage.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMMessage.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMMessage.java new file mode 100644 index 0000000..2f98936 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMMessage.java @@ -0,0 +1,153 @@ +/** + * 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.cm; + +/** + * Valid message to be serialized and sent to CM Endpoints. If the message only uses GSM 7-bit characters, then 160 characters will fit in 1 SMS part, and 153*n characters will fit in n SMS parts for + * n>1. If the message contains other characters, then only 70 characters will fit in 1 SMS part, and 67*n characters will fit in n SMS parts for n>1. <br> + * <br> + * {@link https://dashboard.onlinesmsgateway.com/docs} <br> + * {@link http://support.telerivet.com/customer/portal/articles/1957426-multipart-unicode-sms-messages} + */ +public class CMMessage { + + /** + * Restrictions: 1 - 32 alphanumeric characters and reference will not work for demo accounts + */ + // TODO: use a ID generator? + private String idAsString; + + private String phoneNumber; + private String message; + + private String sender; + + private boolean unicode; + private int multipart = 1; + + public CMMessage(final String phoneNumber, final String message) { + this.message = message; + this.phoneNumber = phoneNumber; + } + + public String getMessage() { + return message; + } + + public void setMessage(final String message) { + this.message = message; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(final String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getSender() { + return sender; + } + + public void setSender(final String sender) { + this.sender = sender; + } + + public String getIdAsString() { + return idAsString; + } + + public void setIdAsString(final String idAsString) { + this.idAsString = idAsString; + } + + public boolean isUnicode() { + return unicode; + } + + public void setUnicode(final boolean unicode) { + this.unicode = unicode; + } + + public boolean isMultipart() { + return multipart > 1; + } + + /** + * For a CMMessage instance + * + * @param defaultMaxNumberOfParts + */ + public void setUnicodeAndMultipart(int defaultMaxNumberOfParts) { + + // Set UNICODE and MULTIPART + final String msg = getMessage(); + if (CMUtils.isGsm0338Encodeable(msg)) { + + // Not Unicode is Multipart? + if (msg.length() > CMConstants.MAX_GSM_MESSAGE_LENGTH) { + + // Multiparts. 153 caracteres max per part + int parts = msg.length() / CMConstants.MAX_GSM_MESSAGE_LENGTH_PER_PART_IF_MULTIPART; + if (msg.length() % CMConstants.MAX_GSM_MESSAGE_LENGTH_PER_PART_IF_MULTIPART != 0) { + parts++; + } + + setMultiparts((parts > defaultMaxNumberOfParts) ? defaultMaxNumberOfParts : parts); + } else { // Otherwise multipart = 1 + setMultiparts(1); + } + } else { + // Unicode Message + setUnicode(true); + + if (msg.length() > CMConstants.MAX_UNICODE_MESSAGE_LENGTH) { + + // Multiparts. 67 caracteres max per part + int parts = msg.length() / CMConstants.MAX_UNICODE_MESSAGE_LENGTH_PER_PART_IF_MULTIPART; + if (msg.length() % CMConstants.MAX_UNICODE_MESSAGE_LENGTH_PER_PART_IF_MULTIPART != 0) { + parts++; + } + + setMultiparts((parts > defaultMaxNumberOfParts) ? defaultMaxNumberOfParts : parts); + } else { // Otherwise multipart = 1 + setMultiparts(1); + } + } + } + + public void setMultiparts(final int multipart) { + this.multipart = multipart; + } + + public int getMultiparts() { + return multipart; + } + + @Override + public String toString() { + + StringBuffer sb = new StringBuffer(" {phoneNumber: " + phoneNumber + ", message: " + message + ", sender=" + sender + ", unicode: " + unicode + ", multipart: " + multipart); + if (idAsString != null && !idAsString.isEmpty()) { + sb.append(", idAsString=" + idAsString); + } + sb.append(" }"); + return sb.toString(); + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMProducer.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMProducer.java new file mode 100644 index 0000000..e4f5722 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMProducer.java @@ -0,0 +1,149 @@ +/** + * 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.cm; + +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.Validator; + +import org.apache.camel.Exchange; +import org.apache.camel.InvalidPayloadRuntimeException; +import org.apache.camel.component.cm.client.SMSMessage; +import org.apache.camel.component.cm.exceptions.HostUnavailableException; +import org.apache.camel.impl.DefaultProducer; +import org.apache.http.client.methods.HttpHead; +import org.apache.http.impl.client.HttpClientBuilder; + +/** + * is the exchange processor. Sends a validated sms message to CM Endpoints. + */ +public class CMProducer extends DefaultProducer { + + private Validator validator; + + /** + * sends a valid message to CM endpoints. + */ + private CMSender sender; + + public CMProducer(final CMEndpoint endpoint, final CMSender sender) { + super(endpoint); + this.sender = sender; + } + + /** + * Producer is a exchange processor. This process is built in several steps. 1. Validate message receive from client 2. Send validated message to CM endpoints. 3. Process response from CM + * endpoints. + */ + @Override + public void process(final Exchange exchange) throws Exception { + + // Immutable message receive from clients. Throws camel ' s + // InvalidPayloadException + final SMSMessage smsMessage = exchange.getIn().getMandatoryBody(SMSMessage.class); + + // Validates Payload - SMSMessage + log.trace("Validating SMSMessage instance provided: {}", smsMessage.toString()); + final Set<ConstraintViolation<SMSMessage>> constraintViolations = getValidator().validate(smsMessage); + if (constraintViolations.size() > 0) { + final StringBuffer msg = new StringBuffer(); + for (final ConstraintViolation<SMSMessage> cv : constraintViolations) { + msg.append(String.format("- Invalid value for %s: %s", cv.getPropertyPath().toString(), cv.getMessage())); + } + log.debug(msg.toString()); + throw new InvalidPayloadRuntimeException(exchange, SMSMessage.class); + } + log.trace("SMSMessage instance is valid: {}", smsMessage.toString()); + + // We have a valid (immutable) SMSMessage instance, lets extend to + // CMMessage + // This is the instance we will use to build the XML document to be + // sent to CM SMS GW. + final CMMessage cmMessage = new CMMessage(smsMessage.getPhoneNumber(), smsMessage.getMessage()); + log.debug("CMMessage instance build from valid SMSMessage instance"); + + if (smsMessage.getFrom() == null || smsMessage.getFrom().isEmpty()) { + String df = getConfiguration().getDefaultFrom(); + cmMessage.setSender(df); + log.debug("Dynamic sender is set to default dynamic sender: {}", df); + } + + // Remember, this can be null. + cmMessage.setIdAsString(smsMessage.getId()); + + // Unicode and multipart + cmMessage.setUnicodeAndMultipart(getConfiguration().getDefaultMaxNumberOfParts()); + + // 2. Send a validated sms message to CM endpoints + // for abnormal situations. + sender.send(cmMessage); + + log.debug("Request accepted by CM Host: {}", cmMessage.toString()); + } + + @Override + protected void doStart() throws Exception { + + // log at debug level for singletons, for prototype scoped log at trace + // level to not spam logs + + log.debug("Starting CMProducer"); + + final CMConfiguration configuration = getConfiguration(); + + if (configuration.isTestConnectionOnStartup()) { + try { + log.debug("Checking connection - {}", getEndpoint().getCMUrl()); + HttpClientBuilder.create().build().execute(new HttpHead(getEndpoint().getCMUrl())); + log.debug("Connection to {}: OK", getEndpoint().getCMUrl()); + } catch (final Exception e) { + throw new HostUnavailableException(String.format("Connection to %s: NOT AVAILABLE", getEndpoint().getCMUrl()), e); + } + } + + // keep starting + super.doStart(); + + log.debug("CMProducer started"); + } + + @Override + public CMEndpoint getEndpoint() { + return (CMEndpoint) super.getEndpoint(); + } + + public CMConfiguration getConfiguration() { + return getEndpoint().getConfiguration(); + } + + public Validator getValidator() { + if (validator == null) { + validator = getEndpoint().getComponent().getValidator(); + } + return validator; + } + + public CMSender getSender() { + return sender; + } + + public void setSender(CMSender sender) { + this.sender = sender; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMSender.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMSender.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMSender.java new file mode 100644 index 0000000..661f4dd --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMSender.java @@ -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. + */ +package org.apache.camel.component.cm; + +/** + * Sends a validated sms message to CM endpoints + */ +public interface CMSender { + + /** + * Sends a validated sms message to CM Endpoints. + */ + void send(CMMessage cmMessage); +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMSenderOneMessageImpl.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMSenderOneMessageImpl.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMSenderOneMessageImpl.java new file mode 100644 index 0000000..07e0e14 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMSenderOneMessageImpl.java @@ -0,0 +1,254 @@ +/** + * 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.cm; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.util.UUID; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Text; + +import org.apache.camel.component.cm.exceptions.CMDirectException; +import org.apache.camel.component.cm.exceptions.XMLConstructionException; +import org.apache.camel.component.cm.exceptions.cmresponse.CMResponseException; +import org.apache.camel.component.cm.exceptions.cmresponse.InsufficientBalanceException; +import org.apache.camel.component.cm.exceptions.cmresponse.InvalidProductTokenException; +import org.apache.camel.component.cm.exceptions.cmresponse.NoAccountFoundForProductTokenException; +import org.apache.camel.component.cm.exceptions.cmresponse.UnknownErrorException; +import org.apache.camel.component.cm.exceptions.cmresponse.UnroutableMessageException; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.HttpClientBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CMSenderOneMessageImpl implements CMSender { + + private static final Logger LOG = LoggerFactory.getLogger(CMSenderOneMessageImpl.class); + + private final String url; + private final UUID productToken; + + public CMSenderOneMessageImpl(final String url, final UUID productToken) { + + this.url = url; + this.productToken = productToken; + } + + /** + * Sends a message to CM endpoints. 1. CMMessage instance is going to be marshalled to xml. 2. Post request xml string to CMEndpoint. + */ + @Override + public void send(final CMMessage cmMessage) { + + // See: Check https://dashboard.onlinesmsgateway.com/docs for responses + + // 1.Construct XML. Throws XMLConstructionException + final String xml = createXml(cmMessage); + + // 2. Try to send to CM SMS Provider ...Throws CMResponseException + doHttpPost(url, xml); + } + + private String createXml(final CMMessage message) { + + try { + + final ByteArrayOutputStream xml = new ByteArrayOutputStream(); + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + + // Get the DocumentBuilder + final DocumentBuilder docBuilder = factory.newDocumentBuilder(); + + // Create blank DOM Document + final DOMImplementation impl = docBuilder.getDOMImplementation(); + final Document doc = impl.createDocument(null, "MESSAGES", null); + + // ROOT Element es MESSAGES + final Element root = doc.getDocumentElement(); + + // AUTHENTICATION element + final Element authenticationElement = doc.createElement("AUTHENTICATION"); + final Element productTokenElement = doc.createElement("PRODUCTTOKEN"); + authenticationElement.appendChild(productTokenElement); + final Text productTokenValue = doc.createTextNode("" + productToken); + productTokenElement.appendChild(productTokenValue); + root.appendChild(authenticationElement); + + // MSG Element + final Element msgElement = doc.createElement("MSG"); + root.appendChild(msgElement); + + // <FROM>VALUE</FROM> + final Element fromElement = doc.createElement("FROM"); + fromElement.appendChild(doc.createTextNode(message.getSender())); + msgElement.appendChild(fromElement); + + // <BODY>VALUE</BODY> + final Element bodyElement = doc.createElement("BODY"); + bodyElement.appendChild(doc.createTextNode(message.getMessage())); + msgElement.appendChild(bodyElement); + + // <TO>VALUE</TO> + final Element toElement = doc.createElement("TO"); + toElement.appendChild(doc.createTextNode(message.getPhoneNumber())); + msgElement.appendChild(toElement); + + // <DCS>VALUE</DCS> - if UNICODE - messageOut.isGSM338Enc + // false + if (message.isUnicode()) { + final Element dcsElement = doc.createElement("DCS"); + dcsElement.appendChild(doc.createTextNode("8")); + msgElement.appendChild(dcsElement); + } + + // <REFERENCE>VALUE</REFERENCE> -Alfanum + final String id = message.getIdAsString(); + if (id != null && !id.isEmpty()) { + final Element refElement = doc.createElement("REFERENCE"); + refElement.appendChild(doc.createTextNode("" + message.getIdAsString())); + msgElement.appendChild(refElement); + } + + // <MINIMUMNUMBEROFMESSAGEPARTS>1</MINIMUMNUMBEROFMESSAGEPARTS> + // <MAXIMUMNUMBEROFMESSAGEPARTS>8</MAXIMUMNUMBEROFMESSAGEPARTS> + if (message.isMultipart()) { + final Element minMessagePartsElement = doc.createElement("MINIMUMNUMBEROFMESSAGEPARTS"); + minMessagePartsElement.appendChild(doc.createTextNode("1")); + msgElement.appendChild(minMessagePartsElement); + + final Element maxMessagePartsElement = doc.createElement("MAXIMUMNUMBEROFMESSAGEPARTS"); + maxMessagePartsElement.appendChild(doc.createTextNode(Integer.toString(message.getMultiparts()))); + msgElement.appendChild(maxMessagePartsElement); + } + + // Creatate XML as String + final Transformer aTransformer = TransformerFactory.newInstance().newTransformer(); + aTransformer.setOutputProperty(OutputKeys.INDENT, "yes"); + final Source src = new DOMSource(doc); + final Result dest = new StreamResult(xml); + aTransformer.transform(src, dest); + return xml.toString(); + } catch (final TransformerException e) { + throw new XMLConstructionException(String.format("Cant serialize CMMessage %s", message), e); + } catch (final ParserConfigurationException e) { + throw new XMLConstructionException(String.format("Cant serialize CMMessage %s", message), e); + } + } + + private void doHttpPost(final String urlString, final String requestString) { + + final HttpClient client = HttpClientBuilder.create().build(); + final HttpPost post = new HttpPost(urlString); + post.setEntity(new StringEntity(requestString, Charset.forName("UTF-8"))); + + try { + + final HttpResponse response = client.execute(post); + + final int statusCode = response.getStatusLine().getStatusCode(); + + LOG.debug("Response Code : {}", statusCode); + + if (statusCode == 400) { + throw new CMDirectException("CM Component and CM API show some kind of inconsistency. " + + "CM is complaining about not using a post method for the request. And this component only uses POST requests. What happens?"); + } + + if (statusCode != 200) { + throw new CMDirectException("CM Component and CM API show some kind of inconsistency. The component expects the status code to be 200 or 400. New api released? "); + } + + // So we have 200 status code... + + // The response type is 'text/plain' and contains the actual + // result of the request processing. + + // We obtaing the result text + final BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); + + final StringBuffer result = new StringBuffer(); + String line = null; + while ((line = rd.readLine()) != null) { + result.append(line); + } + + // ... and process it + + line = result.toString(); + if (!line.isEmpty()) { + + // Line is not empty = error + LOG.debug("Result of the request processing: FAILED\n{}", line); + + // The response text contains the error description. We will + // throw a custom exception for each. + + if (line.contains(CMConstants.ERROR_UNKNOWN)) { + throw new UnknownErrorException(); + } else if (line.contains(CMConstants.ERROR_NO_ACCOUNT)) { + throw new NoAccountFoundForProductTokenException(); + } else if (line.contains(CMConstants.ERROR_INSUFICIENT_BALANCE)) { + throw new InsufficientBalanceException(); + } else if (line.contains(CMConstants.ERROR_UNROUTABLE_MESSAGE)) { + throw new UnroutableMessageException(); + } else if (line.contains(CMConstants.ERROR_INVALID_PRODUCT_TOKEN)) { + throw new InvalidProductTokenException(); + } else { + + // SO FAR i would expect other kind of ERROR. + + // MSISDN correctness and message validity is client + // responsibility + throw new CMResponseException("CHECK ME. I am not expecting this. "); + } + } + + // Ok. Line is EMPTY - successfully submitted + LOG.debug("Result of the request processing: Successfully submited"); + } catch (final IOException io) { + throw new CMDirectException(io); + } catch (Throwable t) { + if (!(t instanceof CMDirectException)) { + // Chain it + t = new CMDirectException(t); + } + throw (CMDirectException) t; + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMUtils.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMUtils.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMUtils.java new file mode 100644 index 0000000..f0581da --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMUtils.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.cm; + +public final class CMUtils { + + private CMUtils() { + } + + public static boolean isGsm0338Encodeable(final String message) { + return message.matches(CMConstants.GSM_0338_REGEX); + } + + // TODO: Have a look at + // https:// github.com/apache/camel/blob/master/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppUtils.java +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/client/SMSMessage.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/client/SMSMessage.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/client/SMSMessage.java new file mode 100644 index 0000000..869c9f8 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/client/SMSMessage.java @@ -0,0 +1,114 @@ +/** + * 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.cm.client; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; + +import org.apache.camel.component.cm.validation.constraints.E164; + +/** + * Immutable. The message instance provided by the client. + */ +public class SMSMessage { + + /** + * Required MSISDN. E164 value. The destination phone number. Format with a '+' and country code. + * + * @see <a href="https://en.wikipedia.org/wiki/E.164">https://en.wikipedia.org/wiki/E.164</a> + */ + @E164 + private final String phoneNumber; + + /** + * This is the message to be sent. 2 options: + * <ul> + * <li>If the message is GSM 0038 encodeable the gateway will first check if a message is larger than 160 characters, if so, the message will be cut into multiple 153 characters parts limited by + * defaultMaxNumberOfParts set in the component uri.</li> + * <li>Otherwise, the gateway will check if a message is larger than 70 characters, if so, the message will be cut into multiple 67 characters parts to a maximum of defaultMaxNumberOfParts set in + * the component uri.</li> + * </ul> + * + * @see <a href="https://en.wikipedia.org/wiki/GSM_03.38">E.164</a> + */ + @NotNull + private final String message; + + /** + * This is an optional dynamic sender name. + * <p> + * 1 - 11 alphanumeric characters and + char. Not Empty Strings. This field has a maximum length of 11 characters. If it is not set the defaultFrom required to configure the component will be set. + */ + @Size(min = 1, max = 11) + @Pattern(regexp = "^[A-Za-z0-9]+$") + private final String from; + + /** + * Unique identifier for a message. + * <p> + * 1 - 32 alphanumeric characters. Not Empty Strings. Will not work for demo accounts. This field corresponds to REFERENCE parameter in CM Api. + */ + @Size(min = 1, max = 32) + @Pattern(regexp = "^[A-Za-z0-9]+$") + private final String id; + + public SMSMessage(final String message, final String phoneNumber) { + this(null, message, phoneNumber, null); + } + + public SMSMessage(String id, final String message, final String phoneNumber) { + this(id, message, phoneNumber, null); + } + + public SMSMessage(final String id, final String message, final String phoneNumber, final String from) { + this.id = id; + this.message = message; + this.phoneNumber = phoneNumber; + this.from = from; + } + + public String getId() { + return id; + } + + public String getMessage() { + return message; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public String getFrom() { + return from; + } + + @Override + public String toString() { + StringBuffer toS = new StringBuffer("{phoneNumber: " + phoneNumber + ", message: " + message); + if (from != null && !from.isEmpty()) { + toS.append(", from: " + from); + } + if (id != null && !id.isEmpty()) { + toS.append(", id: " + id); + } + toS.append(" }"); + return toS.toString(); + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/client/Translator.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/client/Translator.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/client/Translator.java new file mode 100644 index 0000000..4c6e9e9 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/client/Translator.java @@ -0,0 +1,23 @@ +/** + * 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.cm.client; + +public interface Translator<T> { + + SMSMessage translate(T t); + +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/CMDirectException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/CMDirectException.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/CMDirectException.java new file mode 100644 index 0000000..70912ff --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/CMDirectException.java @@ -0,0 +1,40 @@ +/** + * 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.cm.exceptions; + +public class CMDirectException extends RuntimeException { + + public CMDirectException() { + } + + public CMDirectException(final String message) { + super(message); + } + + public CMDirectException(final Throwable cause) { + super(cause); + } + + public CMDirectException(final String message, final Throwable cause) { + super(message, cause); + } + + public CMDirectException(final String message, final Throwable cause, + final boolean enableSuppression, final boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/HostUnavailableException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/HostUnavailableException.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/HostUnavailableException.java new file mode 100644 index 0000000..73bf0d0 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/HostUnavailableException.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.cm.exceptions; + +public class HostUnavailableException extends CMDirectException { + + public HostUnavailableException() { + } + + public HostUnavailableException(final String message) { + super(message); + } + + public HostUnavailableException(final Throwable cause) { + super(cause); + } + + public HostUnavailableException(final String message, final Throwable cause) { + super(message, cause); + } + + public HostUnavailableException(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/XMLConstructionException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/XMLConstructionException.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/XMLConstructionException.java new file mode 100644 index 0000000..5086e70 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/XMLConstructionException.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.cm.exceptions; + +public class XMLConstructionException extends CMDirectException { + + public XMLConstructionException() { + } + + public XMLConstructionException(final String message) { + super(message); + } + + public XMLConstructionException(final Throwable cause) { + super(cause); + } + + public XMLConstructionException(final String message, final Throwable cause) { + super(message, cause); + } + + public XMLConstructionException(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/CMResponseException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/CMResponseException.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/CMResponseException.java new file mode 100644 index 0000000..4ed4f6e --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/CMResponseException.java @@ -0,0 +1,41 @@ +/** + * 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.cm.exceptions.cmresponse; + +import org.apache.camel.component.cm.exceptions.CMDirectException; + +public class CMResponseException extends CMDirectException { + + public CMResponseException() { + } + + public CMResponseException(final String message) { + super(message); + } + + public CMResponseException(final Throwable cause) { + super(cause); + } + + public CMResponseException(final String message, final Throwable cause) { + super(message, cause); + } + + public CMResponseException(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InsufficientBalanceException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InsufficientBalanceException.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InsufficientBalanceException.java new file mode 100644 index 0000000..bb73cc5 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InsufficientBalanceException.java @@ -0,0 +1,26 @@ +/** + * 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.cm.exceptions.cmresponse; + +/** + * You are out of trial messages. Order new messages via your dashboard. + */ +public class InsufficientBalanceException extends CMResponseException { + + public InsufficientBalanceException() { + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InvalidMSISDNException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InvalidMSISDNException.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InvalidMSISDNException.java new file mode 100644 index 0000000..c80fbdd --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InvalidMSISDNException.java @@ -0,0 +1,23 @@ +/** + * 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.cm.exceptions.cmresponse; + +public class InvalidMSISDNException extends CMResponseException { + + public InvalidMSISDNException() { + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InvalidProductTokenException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InvalidProductTokenException.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InvalidProductTokenException.java new file mode 100644 index 0000000..ce81bcb --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InvalidProductTokenException.java @@ -0,0 +1,26 @@ +/** + * 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.cm.exceptions.cmresponse; + +/** + * Invalid or missing + */ +public class InvalidProductTokenException extends CMResponseException { + + public InvalidProductTokenException() { + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/NoAccountFoundForProductTokenException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/NoAccountFoundForProductTokenException.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/NoAccountFoundForProductTokenException.java new file mode 100644 index 0000000..a718ff3 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/NoAccountFoundForProductTokenException.java @@ -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. + */ +package org.apache.camel.component.cm.exceptions.cmresponse; + +/** + * No account found for the provided product token. + * + * @author Omar + */ +public class NoAccountFoundForProductTokenException extends CMResponseException { + + public NoAccountFoundForProductTokenException() { + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/NoMessageException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/NoMessageException.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/NoMessageException.java new file mode 100644 index 0000000..4398219 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/NoMessageException.java @@ -0,0 +1,23 @@ +/** + * 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.cm.exceptions.cmresponse; + +public class NoMessageException extends CMResponseException { + + public NoMessageException() { + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/NotPhoneNumberFoundException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/NotPhoneNumberFoundException.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/NotPhoneNumberFoundException.java new file mode 100644 index 0000000..877b972 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/NotPhoneNumberFoundException.java @@ -0,0 +1,23 @@ +/** + * 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.cm.exceptions.cmresponse; + +public class NotPhoneNumberFoundException extends CMResponseException { + + public NotPhoneNumberFoundException() { + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/UnknownErrorException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/UnknownErrorException.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/UnknownErrorException.java new file mode 100644 index 0000000..bb0951a --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/UnknownErrorException.java @@ -0,0 +1,26 @@ +/** + * 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.cm.exceptions.cmresponse; + +/** + * An unexpected error occurred. Check the provided values. Contact CM for support. + */ +public class UnknownErrorException extends CMResponseException { + + public UnknownErrorException() { + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/UnroutableMessageException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/UnroutableMessageException.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/UnroutableMessageException.java new file mode 100644 index 0000000..ec07c1f --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/UnroutableMessageException.java @@ -0,0 +1,23 @@ +/** + * 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.cm.exceptions.cmresponse; + +public class UnroutableMessageException extends CMResponseException { + + public UnroutableMessageException() { + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/58515451/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/validation/constraints/E164.java ---------------------------------------------------------------------- diff --git a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/validation/constraints/E164.java b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/validation/constraints/E164.java new file mode 100644 index 0000000..3d7dd95 --- /dev/null +++ b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/validation/constraints/E164.java @@ -0,0 +1,41 @@ +/** + * 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.cm.validation.constraints; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.validation.Constraint; +import javax.validation.Payload; + +@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, + ElementType.ANNOTATION_TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = E164Validator.class) +@Documented +public @interface E164 { + + // String message() default "{e164.message}"; + String message() default "E164 format expected for that phone number"; + + Class<?>[] groups() default {}; + + Class<? extends Payload>[] payload() default {}; +}