camel-cm component added following the steps in http://camel.apache.org/add-new-component-guide.html
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/c70e9db8 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/c70e9db8 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/c70e9db8 Branch: refs/heads/master Commit: c70e9db88e9d3c04bf5b69cde8078c7e47c70e15 Parents: fa78b86 Author: oalles <oal...@neivi.es> Authored: Sun Mar 20 14:23:21 2016 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Wed Mar 23 18:46:10 2016 +0100 ---------------------------------------------------------------------- components/camel-cm/README.md | 32 ++ components/camel-cm/pom.xml | 101 +++++ .../apache/camel/component/cm/CMComponent.java | 104 +++++ .../camel/component/cm/CMConfiguration.java | 92 +++++ .../apache/camel/component/cm/CMConstants.java | 39 ++ .../apache/camel/component/cm/CMEndpoint.java | 141 +++++++ .../apache/camel/component/cm/CMMessage.java | 153 +++++++ .../apache/camel/component/cm/CMProducer.java | 165 ++++++++ .../org/apache/camel/component/cm/CMSender.java | 30 ++ .../component/cm/CMSenderOneMessageImpl.java | 263 ++++++++++++ .../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/CMValidationException.java | 40 ++ .../cm/exceptions/HostUnavailableException.java | 40 ++ .../cm/exceptions/InvalidPayloadException.java | 44 ++ .../cm/exceptions/InvalidURLException.java | 30 ++ .../exceptions/InvalidUriEndpointException.java | 33 ++ .../cm/exceptions/MessagingException.java | 40 ++ .../cm/exceptions/ProviderException.java | 41 ++ .../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 | 407 +++++++++++++++++++ .../cm/test/CamelTestConfiguration.java | 100 +++++ .../camel/component/cm/test/SMSMessageTest.java | 183 +++++++++ .../cm/test/ValidatorConfiguration.java | 35 ++ .../cmsender/CMResponseExceptionSender.java | 31 ++ .../InsufficientBalanceExceptionSender.java | 31 ++ .../cmsender/InvalidMSISDNExceptionSender.java | 31 ++ .../InvalidProductTokenExceptionSender.java | 31 ++ ...ountFoundForProductTokenExceptionSender.java | 31 ++ .../cmsender/NoMessageExceptionSender.java | 31 ++ .../NotPhoneNumberFoundExceptionSender.java | 31 ++ .../cmsender/UnknownErrorExceptionSender.java | 31 ++ .../UnroutableMessageExceptionSender.java | 31 ++ .../src/test/resources/cm-smsgw.properties | 28 ++ components/pom.xml | 1 + parent/pom.xml | 4 + .../features/src/main/resources/features.xml | 10 + 55 files changed, 3573 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/c70e9db8/components/camel-cm/README.md ---------------------------------------------------------------------- diff --git a/components/camel-cm/README.md b/components/camel-cm/README.md new file mode 100644 index 0000000..63f9059 --- /dev/null +++ b/components/camel-cm/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/c70e9db8/components/camel-cm/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-cm/pom.xml b/components/camel-cm/pom.xml new file mode 100644 index 0000000..2659259 --- /dev/null +++ b/components/camel-cm/pom.xml @@ -0,0 +1,101 @@ +<?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.16.2</version> + </parent> + <artifactId>camel-cm</artifactId> + <packaging>bundle</packaging> + <name>Camel :: CM</name> + <description>Camel CM 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</camel.osgi.export.service> + <httpclient>${httpclient4-version}</httpclient> + <jsoup-version>1.8.3</jsoup-version> + <libphonenumber-version>7.2.7</libphonenumber-version> + <commons-validator-version>1.5.0</commons-validator-version> + </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>${httpclient}</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> + </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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMComponent.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMComponent.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMComponent.java new file mode 100644 index 0000000..ccd701f --- /dev/null +++ b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMComponent.java @@ -0,0 +1,104 @@ +/** + * 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.component.cm.exceptions.InvalidURLException; +import org.apache.camel.component.cm.exceptions.InvalidUriEndpointException; +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); + + @BeanInject + private Validator validator; + + // public CMComponent() { + // super(CMEndpoint.class); + // } + + 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.info("Creating CM Endpoint ... "); + + final String url = CMConstants.DEFAULT_SCHEME + remaining; + if (!UrlValidator.getInstance().isValid(url)) { + final String errorMessage = String.format("HOST provided: %s seem to be invalid. Remember SCHEME has to be excluded.", url); + final Exception t = new InvalidURLException(errorMessage); + LOG.error(errorMessage, t); + throw t; + } + + LOG.info("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.info("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())); + } + LOG.error(msg.toString()); + throw new InvalidUriEndpointException(msg.toString()); + } + LOG.info("CMConfiguration - OK!"); + + // Component is an Endpoint factory. So far, just one Endpoint type. + // Endpoint construction and configuration. + + LOG.info("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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMConfiguration.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMConfiguration.java new file mode 100644 index 0000000..c95c06e --- /dev/null +++ b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMConfiguration.java @@ -0,0 +1,92 @@ +/** + * 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 javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import org.apache.camel.spi.UriParam; +import org.apache.camel.spi.UriParams; + +@UriParams +public class CMConfiguration { + + @UriParam + @NotNull + private UUID productToken; + + /** + * This is the sender name. The maximum length is 11 characters. + */ + @UriParam + @NotNull + @Size(min = 1, max = 11) + private String defaultFrom; + + /** + * 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. <br> + * {@link https://dashboard.onlinesmsgateway.com/docs#send-a-message-multipart} + */ + @UriParam + @Max(8) + @Min(1) + private int defaultMaxNumberOfParts = 8; + + @UriParam + private boolean testConnectionOnStartup; + + public UUID getProductToken() { + return productToken; + } + + public void setProductToken(String productTokenAsString) { + productToken = UUID.fromString(productTokenAsString); + } + + public String getDefaultFrom() { + return defaultFrom; + } + + public void setDefaultFrom(final String defaultFrom) { + this.defaultFrom = defaultFrom; + } + + public int getDefaultMaxNumberOfParts() { + return defaultMaxNumberOfParts; + } + + public void setDefaultMaxNumberOfParts(final int defaultMaxNumberOfParts) { + this.defaultMaxNumberOfParts = defaultMaxNumberOfParts; + } + + public boolean isTestConnectionOnStartup() { + return testConnectionOnStartup; + } + + public void setTestConnectionOnStartup(final boolean testConnectionOnStartup) { + this.testConnectionOnStartup = testConnectionOnStartup; + } + + public void setProductTokenAsUUID(final UUID productToken) { + this.productToken = productToken; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMConstants.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMConstants.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMConstants.java new file mode 100644 index 0000000..ad8bfc4 --- /dev/null +++ b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMConstants.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; + +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 - checkk 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"; + + String GSM_CHARACTERS_REGEX = "^[A-Za-z0-9 \\r\\n@£$¥èéùìòÃÃøà å\u0394_\u03A6\u0393\u039B\u03A9" + + "\u03A0\u03A8\u03A3\u0398\u039EÃæÃÃ!\"#$%&'()*+,\\-./:;<=>?¡ÃÃÃç¿äöñüà ^{}\\\\\\[~\\]|\u20AC]*$"; +} http://git-wip-us.apache.org/repos/asf/camel/blob/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMEndpoint.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMEndpoint.java new file mode 100644 index 0000000..0aa34d2 --- /dev/null +++ b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMEndpoint.java @@ -0,0 +1,141 @@ +/** + * 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 org.apache.camel.Consumer; +import org.apache.camel.ExchangePattern; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.api.management.ManagedAttribute; +import org.apache.camel.api.management.ManagedOperation; +import org.apache.camel.api.management.ManagedResource; +import org.apache.camel.impl.DefaultEndpoint; +import org.apache.camel.spi.Metadata; +import org.apache.camel.spi.UriPath; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ManagedResource(description = "CM SMS Endpoint") +// @UriEndpoint(scheme = "cm", title = "CM DIRECT SMS", syntax = "cm:host", +// label = "sms provider", producerOnly = true) +public class CMEndpoint extends DefaultEndpoint { + + private static final Logger LOG = LoggerFactory.getLogger(CMEndpoint.class); + + @UriPath + @Metadata(description = "SMS Provider HOST with scheme", required = "true") + private String host; + + /** + * data needed for exchange interaction + */ + private CMConfiguration configuration; + + private CMProducer producer; + + /** + * Constructs a partially-initialized CMEndpoint instance. Useful when creating endpoints manually (e.g., as beans in Spring). + */ + // We are just going to allow fully initialized endpoint instances + // public CMEndpoint() { + // } + + /** + * Constructs a fully-initialized CMEndpoint instance. This is the preferred method of constructing an object from Java code (as opposed to Spring beans, etc.). + * + * @param endpointUri the full URI used to create this endpoint + * @param component the component that created this endpoint + */ + public CMEndpoint(final String uri, final CMComponent component) { + super(uri, component); + setExchangePattern(ExchangePattern.InOut); + LOG.info("CM Endpoint created - (IN/OUT)"); + } + + /** + * Provides a channel on which clients can send Messages to a CM Endpoint + */ + @Override + public Producer 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 + LOG.debug("Creating CM Producer"); + producer = new CMProducer(this, new CMSenderOneMessageImpl(getCMUrl(), config.getProductToken())); + LOG.debug("CM Producer: OK!"); + return producer; + } + + @Override + public Consumer createConsumer(final Processor processor) throws Exception { + + throw new RuntimeCamelException("So far, cannot consume from CM Endpoint: " + getEndpointUri()); + } + + public CMConfiguration getConfiguration() { + return configuration; + } + + public void setConfiguration(final CMConfiguration configuration) { + this.configuration = configuration; + } + + @Override + public boolean isSingleton() { + return true; + } + + // @Override + // public Exchange createExchange() { + // return super.createExchange(); + // } + + @ManagedAttribute + public String getHost() { + return host; + } + + public String getCMUrl() { + return CMConstants.DEFAULT_SCHEME + host; + } + + @ManagedOperation(description = "Dynamically modify Service HOST") + public void setHost(final String host) { + this.host = host; + } + + @Override + public CMComponent getComponent() { + return (CMComponent) super.getComponent(); + } + + public CMProducer getProducer() { + return producer; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMMessage.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMMessage.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMMessage.java new file mode 100644 index 0000000..2f98936 --- /dev/null +++ b/components/camel-cm/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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMProducer.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMProducer.java new file mode 100644 index 0000000..d175750 --- /dev/null +++ b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMProducer.java @@ -0,0 +1,165 @@ +/** + * 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.component.cm.client.SMSMessage; +import org.apache.camel.component.cm.exceptions.HostUnavailableException; +import org.apache.camel.component.cm.exceptions.InvalidPayloadException; +import org.apache.camel.impl.DefaultProducer; +import org.apache.http.client.methods.HttpHead; +import org.apache.http.impl.client.HttpClientBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * is the exchange processor. Sends a validated sms message to CM Endpoints. + */ +public class CMProducer extends DefaultProducer { + + private static final Logger LOG = LoggerFactory.getLogger(CMProducer.class); + + 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) { + + try { + + // Immutable message receive from clients. + final SMSMessage smsMessage = exchange.getIn().getBody(SMSMessage.class); + if (smsMessage == null) { + throw new NullPointerException(); + } + + // 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())); + } + throw new InvalidPayloadException(msg.toString()); + } + 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 + // throws MessagingException for abnormal situations. + sender.send(cmMessage); + + log.debug("Request accepted by CM Host: {}", cmMessage.toString()); + } catch (final NullPointerException e) { + // Body hast to be an instance of SMSMessage + final String m = "Check Message body - Has to be an SMSMessage instance"; + log.error(m, e); + exchange.setException(new InvalidPayloadException(m)); + } catch (final RuntimeException e) { + log.error("Message cannot be sent ", e); + exchange.setException(e); + } + } + + @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.info("Connection to {}: OK", getEndpoint().getCMUrl()); + } catch (final Exception e) { + log.info("Connection to {}: NOT AVAILABLE", getEndpoint().getCMUrl()); + throw new HostUnavailableException(e); + } + } + + // keep starting + super.doStart(); + + log.info("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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMSender.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMSender.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMSender.java new file mode 100644 index 0000000..d3eceeb --- /dev/null +++ b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMSender.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; + +import org.apache.camel.component.cm.exceptions.MessagingException; + +/** + * Sends a validated sms message to CM endpoints + */ +public interface CMSender { + + /** + * Sends a validated sms message to CM Endpoints. + */ + void send(CMMessage cmMessage) throws MessagingException; +} http://git-wip-us.apache.org/repos/asf/camel/blob/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMSenderOneMessageImpl.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMSenderOneMessageImpl.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMSenderOneMessageImpl.java new file mode 100644 index 0000000..fc69fc5 --- /dev/null +++ b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMSenderOneMessageImpl.java @@ -0,0 +1,263 @@ +/** + * 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.MessagingException; +import org.apache.camel.component.cm.exceptions.ProviderException; +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 previously validated SMSMessage to CM endpoint + */ + @Override + public void send(final CMMessage cmMessage) throws MessagingException { + + // See: Check https://dashboard.onlinesmsgateway.com/docs for responses + + try { + + // 1.Construct XML. Throws XMLConstructionException + final String xml = createXml(cmMessage); + + // 2. Try to send to CM SMS Provider ...Throws CMResponse + doHttpPost(url, xml); + } catch (final RuntimeException e) { + LOG.error("Failed to send SMS: {}", cmMessage, e); + throw e; // XMLConstrucion o + } + } + + 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) { + LOG.error("Cant serialize CMMessage {}: ", message, e); + throw new XMLConstructionException(e); + } catch (final ParserConfigurationException e) { + LOG.error("Cant serialize CMMessage {}: ", message, e); + throw new XMLConstructionException(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 ProviderException("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 ProviderException("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 ProviderException(io); + } catch (Throwable t) { + if (!(t instanceof MessagingException)) { + // Chain it + t = new MessagingException(t); + } + throw (MessagingException) t; + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMUtils.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMUtils.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/CMUtils.java new file mode 100644 index 0000000..932e99f --- /dev/null +++ b/components/camel-cm/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_CHARACTERS_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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/client/SMSMessage.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/client/SMSMessage.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/client/SMSMessage.java new file mode 100644 index 0000000..869c9f8 --- /dev/null +++ b/components/camel-cm/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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/client/Translator.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/client/Translator.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/client/Translator.java new file mode 100644 index 0000000..4c6e9e9 --- /dev/null +++ b/components/camel-cm/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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/CMDirectException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/CMDirectException.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/CMDirectException.java new file mode 100644 index 0000000..70912ff --- /dev/null +++ b/components/camel-cm/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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/CMValidationException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/CMValidationException.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/CMValidationException.java new file mode 100644 index 0000000..65cfaff --- /dev/null +++ b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/CMValidationException.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 CMValidationException extends CMDirectException { + + public CMValidationException() { + } + + public CMValidationException(final String message) { + super(message); + } + + public CMValidationException(final Throwable cause) { + super(cause); + } + + public CMValidationException(final String message, final Throwable cause) { + super(message, cause); + } + + public CMValidationException(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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/HostUnavailableException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/HostUnavailableException.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/HostUnavailableException.java new file mode 100644 index 0000000..4e1348c --- /dev/null +++ b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/HostUnavailableException.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 HostUnavailableException extends MessagingException { + + 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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/InvalidPayloadException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/InvalidPayloadException.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/InvalidPayloadException.java new file mode 100644 index 0000000..0cf8385 --- /dev/null +++ b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/InvalidPayloadException.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.exceptions; + +/** + * The body has to be an instance of CMMessage. + * + */ +public class InvalidPayloadException extends CMValidationException { + + public InvalidPayloadException() { + } + + public InvalidPayloadException(final String message) { + super(message); + } + + public InvalidPayloadException(final Throwable cause) { + super(cause); + } + + public InvalidPayloadException(final String message, final Throwable cause) { + super(message, cause); + } + + public InvalidPayloadException(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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/InvalidURLException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/InvalidURLException.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/InvalidURLException.java new file mode 100644 index 0000000..9f26a5b --- /dev/null +++ b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/InvalidURLException.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.exceptions; + +/** + * Invalid Resource URL - CM Hosts + */ +public class InvalidURLException extends InvalidUriEndpointException { + + public InvalidURLException() { + } + + public InvalidURLException(final String message) { + super(message); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/InvalidUriEndpointException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/InvalidUriEndpointException.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/InvalidUriEndpointException.java new file mode 100644 index 0000000..449df1b --- /dev/null +++ b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/InvalidUriEndpointException.java @@ -0,0 +1,33 @@ +/** + * 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; + +/** + * CM Camel component s configuration is based on URI. This exception is raised + * when the uri provided for configuration is wrong + * + */ +public class InvalidUriEndpointException extends CMValidationException { + + public InvalidUriEndpointException() { + super(); + } + + public InvalidUriEndpointException(final String message) { + super(message); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/MessagingException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/MessagingException.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/MessagingException.java new file mode 100644 index 0000000..ddf9c87 --- /dev/null +++ b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/MessagingException.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 MessagingException extends CMDirectException { + + public MessagingException() { + } + + public MessagingException(final String message) { + super(message); + } + + public MessagingException(final Throwable cause) { + super(cause); + } + + public MessagingException(final String message, final Throwable cause) { + super(message, cause); + } + + public MessagingException(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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/ProviderException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/ProviderException.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/ProviderException.java new file mode 100644 index 0000000..e29ca4a --- /dev/null +++ b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/ProviderException.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; + +import org.apache.camel.component.cm.exceptions.cmresponse.CMResponseException; + +public class ProviderException extends CMResponseException { + + public ProviderException() { + } + + public ProviderException(final String message) { + super(message); + } + + public ProviderException(final Throwable cause) { + super(cause); + } + + public ProviderException(final String message, final Throwable cause) { + super(message, cause); + } + + public ProviderException(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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/XMLConstructionException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/XMLConstructionException.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/XMLConstructionException.java new file mode 100644 index 0000000..a6dae02 --- /dev/null +++ b/components/camel-cm/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 MessagingException { + + 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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/CMResponseException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/CMResponseException.java b/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/CMResponseException.java new file mode 100644 index 0000000..7251c51 --- /dev/null +++ b/components/camel-cm/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.MessagingException; + +public class CMResponseException extends MessagingException { + + 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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InsufficientBalanceException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InsufficientBalanceException.java b/components/camel-cm/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/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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InvalidMSISDNException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InvalidMSISDNException.java b/components/camel-cm/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/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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InvalidProductTokenException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/InvalidProductTokenException.java b/components/camel-cm/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/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/c70e9db8/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/NoAccountFoundForProductTokenException.java ---------------------------------------------------------------------- diff --git a/components/camel-cm/src/main/java/org/apache/camel/component/cm/exceptions/cmresponse/NoAccountFoundForProductTokenException.java b/components/camel-cm/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/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() { + } +}