001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.component.smpp;
018
019 import java.io.IOException;
020
021 import org.apache.camel.Exchange;
022 import org.apache.camel.impl.DefaultProducer;
023 import org.apache.commons.logging.Log;
024 import org.apache.commons.logging.LogFactory;
025 import org.jsmpp.DefaultPDUReader;
026 import org.jsmpp.DefaultPDUSender;
027 import org.jsmpp.InvalidResponseException;
028 import org.jsmpp.PDUException;
029 import org.jsmpp.SynchronizedPDUSender;
030 import org.jsmpp.bean.Alphabet;
031 import org.jsmpp.bean.BindType;
032 import org.jsmpp.bean.ESMClass;
033 import org.jsmpp.bean.GeneralDataCoding;
034 import org.jsmpp.bean.MessageClass;
035 import org.jsmpp.bean.NumberingPlanIndicator;
036 import org.jsmpp.bean.RegisteredDelivery;
037 import org.jsmpp.bean.SubmitSm;
038 import org.jsmpp.bean.TypeOfNumber;
039 import org.jsmpp.extra.NegativeResponseException;
040 import org.jsmpp.extra.ResponseTimeoutException;
041 import org.jsmpp.session.BindParameter;
042 import org.jsmpp.session.SMPPSession;
043 import org.jsmpp.util.DefaultComposer;
044
045 /**
046 * An implementation of @{link Producer} which use the SMPP protocol
047 *
048 * @version $Revision: 945986 $
049 * @author muellerc
050 */
051 public class SmppProducer extends DefaultProducer {
052
053 private static final transient Log LOG = LogFactory.getLog(SmppProducer.class);
054
055 private SmppConfiguration configuration;
056 private SMPPSession session;
057
058 public SmppProducer(SmppEndpoint endpoint, SmppConfiguration configuration) {
059 super(endpoint);
060 this.configuration = configuration;
061 }
062
063 @Override
064 protected void doStart() throws Exception {
065 if (LOG.isDebugEnabled()) {
066 LOG.debug("Connecting to: " + getEndpoint().getConnectionString() + "...");
067 }
068
069 super.doStart();
070
071 session = createSMPPSession();
072 session.setEnquireLinkTimer(this.configuration.getEnquireLinkTimer());
073 session.setTransactionTimer(this.configuration.getTransactionTimer());
074 session.connectAndBind(
075 this.configuration.getHost(),
076 this.configuration.getPort(),
077 new BindParameter(
078 BindType.BIND_TX,
079 this.configuration.getSystemId(),
080 this.configuration.getPassword(),
081 this.configuration.getSystemType(),
082 TypeOfNumber.valueOf(configuration.getTypeOfNumber()),
083 NumberingPlanIndicator.valueOf(configuration.getNumberingPlanIndicator()),
084 ""));
085
086 LOG.info("Connected to: " + getEndpoint().getConnectionString());
087 }
088
089 /**
090 * Factory method to easily instantiate a mock SMPPSession
091 *
092 * @return the SMPPSession
093 */
094 SMPPSession createSMPPSession() {
095 if (configuration.getUsingSSL()) {
096 return new SMPPSession(new SynchronizedPDUSender(new DefaultPDUSender(new DefaultComposer())),
097 new DefaultPDUReader(), SmppSSLConnectionFactory.getInstance());
098 } else {
099 return new SMPPSession();
100 }
101 }
102
103 public void process(Exchange exchange) throws Exception {
104 if (LOG.isDebugEnabled()) {
105 LOG.debug("Sending a short message for exchange id '"
106 + exchange.getExchangeId() + "'...");
107 }
108
109 SubmitSm submitSm = getEndpoint().getBinding().createSubmitSm(exchange);
110 String messageId;
111 try {
112 messageId = doProcess(submitSm);
113 } catch (Exception e) {
114 if (LOG.isDebugEnabled()) {
115 LOG.debug("Caught exception while trying to send short message for exchange id '"
116 + exchange.getExchangeId() + "', retrying...", e);
117 }
118 doStop();
119 doStart();
120
121 messageId = doProcess(submitSm);
122 }
123
124 if (LOG.isDebugEnabled()) {
125 LOG.debug("Sent a short message for exchange id '"
126 + exchange.getExchangeId() + "' and received message id '"
127 + messageId + "'");
128 }
129
130 if (exchange.getPattern().isOutCapable()) {
131 if (LOG.isDebugEnabled()) {
132 LOG.debug("Exchange is out capable, setting headers on out exchange...");
133 }
134 exchange.getOut().setHeader(SmppBinding.ID, messageId);
135 } else {
136 if (LOG.isDebugEnabled()) {
137 LOG.debug("Exchange is not out capable, setting headers on in exchange...");
138 }
139 exchange.getIn().setHeader(SmppBinding.ID, messageId);
140 }
141 }
142
143 private String doProcess(SubmitSm submitSm) throws PDUException,
144 ResponseTimeoutException, InvalidResponseException,
145 NegativeResponseException, IOException {
146
147 String messageId = session.submitShortMessage(
148 submitSm.getServiceType(),
149 TypeOfNumber.valueOf(submitSm.getSourceAddrTon()),
150 NumberingPlanIndicator.valueOf(submitSm.getSourceAddrNpi()),
151 submitSm.getSourceAddr(),
152 TypeOfNumber.valueOf(submitSm.getDestAddrTon()),
153 NumberingPlanIndicator.valueOf(submitSm.getDestAddrNpi()),
154 submitSm.getDestAddress(),
155 new ESMClass(),
156 submitSm.getProtocolId(),
157 submitSm.getPriorityFlag(),
158 submitSm.getScheduleDeliveryTime(),
159 submitSm.getValidityPeriod(),
160 new RegisteredDelivery(submitSm.getRegisteredDelivery()),
161 submitSm.getReplaceIfPresent(),
162 new GeneralDataCoding(
163 false,
164 false,
165 MessageClass.CLASS1,
166 Alphabet.ALPHA_DEFAULT),
167 (byte) 0,
168 submitSm.getShortMessage());
169
170 return messageId;
171 }
172
173 @Override
174 protected void doStop() throws Exception {
175 if (LOG.isDebugEnabled()) {
176 LOG.debug("Disconnecting from: " + getEndpoint().getConnectionString() + "...");
177 }
178
179 super.doStop();
180
181 if (session != null) {
182 session.close();
183 session = null;
184 }
185
186 LOG.info("Disconnected from: " + getEndpoint().getConnectionString());
187 }
188
189 @Override
190 public SmppEndpoint getEndpoint() {
191 return (SmppEndpoint) super.getEndpoint();
192 }
193
194 /**
195 * Returns the smppConfiguration for this producer
196 *
197 * @return the configuration
198 */
199 public SmppConfiguration getConfiguration() {
200 return configuration;
201 }
202
203 @Override
204 public String toString() {
205 return "SmppProducer[" + getEndpoint().getConnectionString() + "]";
206 }
207
208 }