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.InvalidResponseException;
026 import org.jsmpp.PDUException;
027 import org.jsmpp.bean.Alphabet;
028 import org.jsmpp.bean.BindType;
029 import org.jsmpp.bean.ESMClass;
030 import org.jsmpp.bean.GeneralDataCoding;
031 import org.jsmpp.bean.MessageClass;
032 import org.jsmpp.bean.NumberingPlanIndicator;
033 import org.jsmpp.bean.RegisteredDelivery;
034 import org.jsmpp.bean.SubmitSm;
035 import org.jsmpp.bean.TypeOfNumber;
036 import org.jsmpp.extra.NegativeResponseException;
037 import org.jsmpp.extra.ResponseTimeoutException;
038 import org.jsmpp.session.BindParameter;
039 import org.jsmpp.session.SMPPSession;
040
041 /**
042 * An implementation of @{link Producer} which use the SMPP protocol
043 *
044 * @version $Revision: 888296 $
045 * @author muellerc
046 */
047 public class SmppProducer extends DefaultProducer {
048
049 private static final transient Log LOG = LogFactory.getLog(SmppProducer.class);
050
051 private SmppConfiguration configuration;
052 private SMPPSession session;
053
054 public SmppProducer(SmppEndpoint endpoint, SmppConfiguration configuration) {
055 super(endpoint);
056 this.configuration = configuration;
057 }
058
059 @Override
060 protected void doStart() throws Exception {
061 if (LOG.isDebugEnabled()) {
062 LOG.debug("Connecting to: " + getEndpoint().getConnectionString() + "...");
063 }
064
065 super.doStart();
066
067 session = createSMPPSession();
068 session.setEnquireLinkTimer(this.configuration.getEnquireLinkTimer());
069 session.setTransactionTimer(this.configuration.getTransactionTimer());
070 session.connectAndBind(
071 this.configuration.getHost(),
072 this.configuration.getPort(),
073 new BindParameter(
074 BindType.BIND_TX,
075 this.configuration.getSystemId(),
076 this.configuration.getPassword(),
077 this.configuration.getSystemType(),
078 TypeOfNumber.valueOf(configuration.getTypeOfNumber()),
079 NumberingPlanIndicator.valueOf(configuration.getNumberingPlanIndicator()),
080 ""));
081
082 LOG.info("Connected to: " + getEndpoint().getConnectionString());
083 }
084
085 /**
086 * Factory method to easily instantiate a mock SMPPSession
087 *
088 * @return the SMPPSession
089 */
090 SMPPSession createSMPPSession() {
091 return new SMPPSession();
092 }
093
094 public void process(Exchange exchange) throws Exception {
095 if (LOG.isDebugEnabled()) {
096 LOG.debug("Sending a short message for exchange id '"
097 + exchange.getExchangeId() + "'...");
098 }
099
100 SubmitSm submitSm = getEndpoint().getBinding().createSubmitSm(exchange);
101 String messageId;
102 try {
103 messageId = doProcess(submitSm);
104 } catch (Exception e) {
105 // TODO: Add some DEBUG logging that we retry one more time
106 doStop();
107 doStart();
108
109 messageId = doProcess(submitSm);
110 }
111
112 LOG.info("Sent a short message for exchange id '"
113 + exchange.getExchangeId() + "' and received message id '"
114 + messageId + "'");
115
116 if (exchange.getPattern().isOutCapable()) {
117 exchange.getOut().setHeader(SmppBinding.ID, messageId);
118 } else {
119 exchange.getIn().setHeader(SmppBinding.ID, messageId);
120 }
121 }
122
123 private String doProcess(SubmitSm submitSm) throws PDUException,
124 ResponseTimeoutException, InvalidResponseException,
125 NegativeResponseException, IOException {
126
127 String messageId = session.submitShortMessage(
128 submitSm.getServiceType(),
129 TypeOfNumber.valueOf(submitSm.getSourceAddrTon()),
130 NumberingPlanIndicator.valueOf(submitSm.getSourceAddrNpi()),
131 submitSm.getSourceAddr(),
132 TypeOfNumber.valueOf(submitSm.getDestAddrTon()),
133 NumberingPlanIndicator.valueOf(submitSm.getDestAddrNpi()),
134 submitSm.getDestAddress(),
135 new ESMClass(),
136 submitSm.getProtocolId(),
137 submitSm.getPriorityFlag(),
138 submitSm.getScheduleDeliveryTime(),
139 submitSm.getValidityPeriod(),
140 new RegisteredDelivery(submitSm.getRegisteredDelivery()),
141 submitSm.getReplaceIfPresent(),
142 new GeneralDataCoding(
143 false,
144 false,
145 MessageClass.CLASS1,
146 Alphabet.ALPHA_DEFAULT),
147 (byte) 0,
148 submitSm.getShortMessage());
149
150 return messageId;
151 }
152
153 @Override
154 protected void doStop() throws Exception {
155 if (LOG.isDebugEnabled()) {
156 LOG.debug("Disconnecting from: " + getEndpoint().getConnectionString() + "...");
157 }
158
159 super.doStop();
160
161 if (session != null) {
162 session.close();
163 session = null;
164 }
165
166 LOG.info("Disconnected from: " + getEndpoint().getConnectionString());
167 }
168
169 @Override
170 public SmppEndpoint getEndpoint() {
171 return (SmppEndpoint) super.getEndpoint();
172 }
173
174 /**
175 * Returns the smppConfiguration for this producer
176 *
177 * @return the configuration
178 */
179 public SmppConfiguration getConfiguration() {
180 return configuration;
181 }
182
183 @Override
184 public String toString() {
185 return "SmppProducer[" + getEndpoint().getConnectionString() + "]";
186 }
187
188 }