JSMPPServerSimulator.java

1
package fr.sii.ogham.testing.sms.simulator.jsmpp;
2
3
import static fr.sii.ogham.testing.sms.simulator.decode.MessageDecoder.decode;
4
import static java.util.Collections.unmodifiableList;
5
import static ogham.testing.org.jsmpp.bean.SMSCDeliveryReceipt.SUCCESS_FAILURE;
6
7
import java.io.IOException;
8
import java.util.ArrayList;
9
import java.util.List;
10
import java.util.concurrent.ExecutorService;
11
import java.util.concurrent.Executors;
12
13
import ogham.testing.org.jsmpp.bean.BroadcastSm;
14
import ogham.testing.org.jsmpp.bean.CancelBroadcastSm;
15
import ogham.testing.org.jsmpp.bean.CancelSm;
16
import ogham.testing.org.jsmpp.bean.DataSm;
17
import ogham.testing.org.jsmpp.bean.OptionalParameter;
18
import ogham.testing.org.jsmpp.bean.QueryBroadcastSm;
19
import ogham.testing.org.jsmpp.bean.QuerySm;
20
import ogham.testing.org.jsmpp.bean.ReplaceSm;
21
import ogham.testing.org.jsmpp.bean.SubmitMulti;
22
import ogham.testing.org.jsmpp.bean.SubmitSm;
23
import ogham.testing.org.jsmpp.bean.UnsuccessDelivery;
24
import ogham.testing.org.jsmpp.extra.ProcessRequestException;
25
import ogham.testing.org.jsmpp.session.BroadcastSmResult;
26
import ogham.testing.org.jsmpp.session.DataSmResult;
27
import ogham.testing.org.jsmpp.session.QueryBroadcastSmResult;
28
import ogham.testing.org.jsmpp.session.QuerySmResult;
29
import ogham.testing.org.jsmpp.session.SMPPServerSession;
30
import ogham.testing.org.jsmpp.session.SMPPServerSessionListener;
31
import ogham.testing.org.jsmpp.session.ServerMessageReceiverListener;
32
import ogham.testing.org.jsmpp.session.ServerResponseDeliveryAdapter;
33
import ogham.testing.org.jsmpp.session.Session;
34
import ogham.testing.org.jsmpp.session.SubmitMultiResult;
35
import ogham.testing.org.jsmpp.session.SubmitSmResult;
36
import ogham.testing.org.jsmpp.util.MessageIDGenerator;
37
import ogham.testing.org.jsmpp.util.MessageId;
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40
41
import fr.sii.ogham.testing.sms.simulator.config.SimulatorConfiguration;
42
43
/**
44
 * @author uudashr
45
 * @author Aurélien Baudet
46
 *
47
 */
48
public class JSMPPServerSimulator extends ServerResponseDeliveryAdapter implements Runnable, ServerMessageReceiverListener {
49
	private static final int BIND_THREAD_POOL_SIZE = 5;
50
	private static final int RECEIPT_THREAD_POOL_SIZE = 100;
51
52
	private static final Logger LOG = LoggerFactory.getLogger(JSMPPServerSimulator.class);
53
54
	private ExecutorService execService;
55
	private final ExecutorService execServiceDelReceipt = Executors.newFixedThreadPool(RECEIPT_THREAD_POOL_SIZE);
56
	private final MessageIDGenerator messageIDGenerator = new UnsecureRandomMessageIDGenerator();
57
	private int port;
58
	private boolean stopped;
59
	private List<SubmitSm> receivedMessages = new ArrayList<>();
60
	private SMPPServerSessionListener sessionListener;
61
	private SMPPServerSession serverSession;
62
	private final Object startupMonitor = new Object();
63
	private volatile boolean running = false;
64
	private final SimulatorConfiguration config;
65
	private ServerStartupException startupFailure;
66
67
	public JSMPPServerSimulator(int port, SimulatorConfiguration config) {
68
		this.port = port;
69
		this.config = config;
70
	}
71
72
	public void run() {
73
		try {
74 1 1. run : negated conditional → RUN_ERROR
			if (!stopped) {
75
				sessionListener = createServerSessionListener();
76
				execService = Executors.newFixedThreadPool(BIND_THREAD_POOL_SIZE);
77
				running = true;
78
				LOG.info("Listening on port {}", port);
79
				synchronized (startupMonitor) {
80 1 1. run : removed call to java/lang/Object::notifyAll → RUN_ERROR
					startupMonitor.notifyAll();
81
				}
82
			}
83 1 1. run : negated conditional → RUN_ERROR
			while (!stopped) {
84
				serverSession = sessionListener.accept();
85
				LOG.info("Accepting connection for session {}", serverSession.getSessionId());
86 1 1. run : removed call to ogham/testing/org/jsmpp/session/SMPPServerSession::setMessageReceiverListener → NO_COVERAGE
				serverSession.setMessageReceiverListener(this);
87 1 1. run : removed call to ogham/testing/org/jsmpp/session/SMPPServerSession::setResponseDeliveryListener → NO_COVERAGE
				serverSession.setResponseDeliveryListener(this);
88 1 1. run : removed call to java/util/concurrent/ExecutorService::execute → NO_COVERAGE
				execService.execute(new WaitBindTask(serverSession, config.getCredentials()));
89
			}
90
		} catch (IOException e) {
91 1 1. run : negated conditional → RUN_ERROR
			if (!stopped) { // NOSONAR
92
				LOG.trace("Failed to initialize SMPP server simulator", e);
93
				startupFailure = new ServerStartupException("Server failed to start on port "+port, e);
94 1 1. run : removed call to fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::close → NO_COVERAGE
				close();
95
			}
96
		} finally {
97
			// Notify everybody that we're ready to accept connections or failed
98
			// to start.
99
			// Otherwise will run into startup timeout, see
100
			// #waitTillRunning(long).
101
			synchronized (startupMonitor) {
102 1 1. run : removed call to java/lang/Object::notifyAll → RUN_ERROR
				startupMonitor.notifyAll();
103
			}
104
		}
105
	}
106
107
	private SMPPServerSessionListener createServerSessionListener() throws IOException {
108 1 1. createServerSessionListener : replaced return value with null for fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::createServerSessionListener → RUN_ERROR
		return new ConfigurableSMPPServerSessionListener(port, config.getServerDelays());
109
	}
110
111
	public synchronized void reset() {
112
		stopped = false;
113 1 1. reset : negated conditional → RUN_ERROR
		if (!config.isKeepMessages()) {
114 1 1. reset : removed call to java/util/List::clear → RUN_ERROR
			receivedMessages.clear();
115
		}
116
	}
117
118
	public synchronized void stop() {
119
		LOG.info("Stopping SMPP simulator");
120
		running = false;
121
		stopped = true;
122 1 1. stop : negated conditional → RUN_ERROR
		if (execService != null) {
123
			LOG.trace("Stopping executor service");
124
			execService.shutdownNow();
125
			execService = null;
126
		}
127 1 1. stop : removed call to fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::close → RUN_ERROR
		close();
128
		LOG.info("SMPP simulator stopped");
129
	}
130
131
	private void close() {
132 1 1. close : negated conditional → RUN_ERROR
		if (serverSession != null) {
133
			LOG.trace("Closing server session");
134 1 1. close : removed call to ogham/testing/org/jsmpp/session/SMPPServerSession::close → NO_COVERAGE
			serverSession.close();
135
			LOG.trace("Server session closed");
136
			serverSession = null;
137
		}
138 1 1. close : negated conditional → RUN_ERROR
		if (sessionListener != null) {
139
			try {
140
				LOG.trace("Closing session listener");
141 1 1. close : removed call to ogham/testing/org/jsmpp/session/SMPPServerSessionListener::close → RUN_ERROR
				sessionListener.close();
142
				LOG.trace("Session listener closed");
143
				sessionListener = null;
144
			} catch (IOException e) {
145
				// nothing to do
146
				LOG.trace("Failed to close session listener", e);
147
			}
148
		}
149
	}
150
151
	public void waitTillRunning(long timeoutInMs) throws ServerStartupException {
152
		try {
153
			long t = System.currentTimeMillis();
154
			synchronized (startupMonitor) {
155
				// Loop to avoid spurious wake ups, see
156
				// https://www.securecoding.cert.org/confluence/display/java/THI03-J.+Always+invoke+wait%28%29+and+await%28%29+methods+inside+a+loop
157 5 1. waitTillRunning : changed conditional boundary → RUN_ERROR
2. waitTillRunning : negated conditional → RUN_ERROR
3. waitTillRunning : negated conditional → RUN_ERROR
4. waitTillRunning : Replaced long subtraction with addition → RUN_ERROR
5. waitTillRunning : negated conditional → RUN_ERROR
				while (!running && startupFailure == null && System.currentTimeMillis() - t < timeoutInMs) {
158 1 1. waitTillRunning : removed call to java/lang/Object::wait → RUN_ERROR
					startupMonitor.wait(timeoutInMs);
159
				}
160
			}
161
		} catch (InterruptedException e) {
162 1 1. waitTillRunning : removed call to java/lang/Thread::interrupt → NO_COVERAGE
			Thread.currentThread().interrupt();
163
			throw new ServerStartupException("Server failed to start (interrupted)", e);
164
		}
165
		
166 1 1. waitTillRunning : negated conditional → RUN_ERROR
		if (startupFailure != null) {
167
			throw startupFailure;
168
		}
169
170 1 1. waitTillRunning : negated conditional → RUN_ERROR
		if (!running) {
171 1 1. waitTillRunning : removed call to fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::close → NO_COVERAGE
			close();
172
			throw new ServerStartupException("Server shouldn't be started after "+timeoutInMs+"ms");
173
		}
174
	}
175
176
	@Override
177
	public QuerySmResult onAcceptQuerySm(QuerySm querySm, SMPPServerSession source) throws ProcessRequestException {
178
		LOG.info("Accepting query sm, but not implemented");
179
		return null;
180
	}
181
182
	@Override
183
	public SubmitSmResult onAcceptSubmitSm(SubmitSm submitSm, SMPPServerSession source) throws ProcessRequestException {
184
		MessageId messageId = messageIDGenerator.newMessageId();
185
		if (LOG.isDebugEnabled()) {
186
			LOG.debug("Receiving submit_sm '{}', and return message id {}", decode(new SubmitSmAdapter(submitSm)), messageId);
187
		}
188
		receivedMessages.add(submitSm);
189 1 1. onAcceptSubmitSm : negated conditional → NO_COVERAGE
		if (SUCCESS_FAILURE.containedIn(submitSm.getRegisteredDelivery())) {
190 1 1. onAcceptSubmitSm : removed call to java/util/concurrent/ExecutorService::execute → NO_COVERAGE
			execServiceDelReceipt.execute(new DeliveryReceiptTask(source, submitSm, messageId));
191
		}
192 1 1. onAcceptSubmitSm : replaced return value with null for fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::onAcceptSubmitSm → NO_COVERAGE
		return new SubmitSmResult(messageId, new OptionalParameter[0]);
193
	}
194
195
	@Override
196
	public SubmitMultiResult onAcceptSubmitMulti(SubmitMulti submitMulti, SMPPServerSession source) throws ProcessRequestException {
197
		MessageId messageId = messageIDGenerator.newMessageId();
198
		if (LOG.isDebugEnabled()) {
199
			LOG.debug("Receiving submit_multi_sm '{}', and return message id {}", submitMulti, messageId);
200
		}
201 1 1. onAcceptSubmitMulti : negated conditional → NO_COVERAGE
		if (SUCCESS_FAILURE.containedIn(submitMulti.getRegisteredDelivery())) {
202 1 1. onAcceptSubmitMulti : removed call to java/util/concurrent/ExecutorService::execute → NO_COVERAGE
			execServiceDelReceipt.execute(new DeliveryReceiptTask(source, submitMulti, messageId));
203
		}
204
205 1 1. onAcceptSubmitMulti : replaced return value with null for fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::onAcceptSubmitMulti → NO_COVERAGE
		return new SubmitMultiResult(messageId.getValue(), new UnsuccessDelivery[0], new OptionalParameter[0]);
206
	}
207
208
	@Override
209
	public DataSmResult onAcceptDataSm(DataSm dataSm, Session source) throws ProcessRequestException {
210
		LOG.debug("onAcceptDataSm '{}'", dataSm);
211
		return null;
212
	}
213
214
	@Override
215
	public void onAcceptCancelSm(CancelSm cancelSm, SMPPServerSession source) throws ProcessRequestException {
216
		// nothing to do
217
	}
218
219
	@Override
220
	public void onAcceptReplaceSm(ReplaceSm replaceSm, SMPPServerSession source) throws ProcessRequestException {
221
		// nothing to do
222
	}
223
224
	@Override
225
	public BroadcastSmResult onAcceptBroadcastSm(BroadcastSm broadcastSm, SMPPServerSession source) throws ProcessRequestException {
226
		// nothing to do
227
		return null;
228
	}
229
230
	@Override
231
	public void onAcceptCancelBroadcastSm(CancelBroadcastSm cancelBroadcastSm, SMPPServerSession source) throws ProcessRequestException {
232
		// nothing to do
233
	}
234
235
	@Override
236
	public QueryBroadcastSmResult onAcceptQueryBroadcastSm(QueryBroadcastSm queryBroadcastSm, SMPPServerSession source) throws ProcessRequestException {
237
		// nothing to do
238
		return null;
239
	}
240
241
	public List<SubmitSm> getReceivedMessages() {
242 1 1. getReceivedMessages : replaced return value with Collections.emptyList for fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::getReceivedMessages → NO_COVERAGE
		return unmodifiableList(new ArrayList<>(receivedMessages));
243
	}
244
245
	public int getPort() {
246 1 1. getPort : replaced int return with 0 for fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::getPort → RUN_ERROR
		return port;
247
	}
248
}

Mutations

74

1.1
Location : run
Killed by :
negated conditional → RUN_ERROR

80

1.1
Location : run
Killed by :
removed call to java/lang/Object::notifyAll → RUN_ERROR

83

1.1
Location : run
Killed by :
negated conditional → RUN_ERROR

86

1.1
Location : run
Killed by :
removed call to ogham/testing/org/jsmpp/session/SMPPServerSession::setMessageReceiverListener → NO_COVERAGE

87

1.1
Location : run
Killed by :
removed call to ogham/testing/org/jsmpp/session/SMPPServerSession::setResponseDeliveryListener → NO_COVERAGE

88

1.1
Location : run
Killed by :
removed call to java/util/concurrent/ExecutorService::execute → NO_COVERAGE

91

1.1
Location : run
Killed by :
negated conditional → RUN_ERROR

94

1.1
Location : run
Killed by :
removed call to fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::close → NO_COVERAGE

102

1.1
Location : run
Killed by :
removed call to java/lang/Object::notifyAll → RUN_ERROR

108

1.1
Location : createServerSessionListener
Killed by :
replaced return value with null for fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::createServerSessionListener → RUN_ERROR

113

1.1
Location : reset
Killed by :
negated conditional → RUN_ERROR

114

1.1
Location : reset
Killed by :
removed call to java/util/List::clear → RUN_ERROR

122

1.1
Location : stop
Killed by :
negated conditional → RUN_ERROR

127

1.1
Location : stop
Killed by :
removed call to fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::close → RUN_ERROR

132

1.1
Location : close
Killed by :
negated conditional → RUN_ERROR

134

1.1
Location : close
Killed by :
removed call to ogham/testing/org/jsmpp/session/SMPPServerSession::close → NO_COVERAGE

138

1.1
Location : close
Killed by :
negated conditional → RUN_ERROR

141

1.1
Location : close
Killed by :
removed call to ogham/testing/org/jsmpp/session/SMPPServerSessionListener::close → RUN_ERROR

157

1.1
Location : waitTillRunning
Killed by :
changed conditional boundary → RUN_ERROR

2.2
Location : waitTillRunning
Killed by :
negated conditional → RUN_ERROR

3.3
Location : waitTillRunning
Killed by :
negated conditional → RUN_ERROR

4.4
Location : waitTillRunning
Killed by :
Replaced long subtraction with addition → RUN_ERROR

5.5
Location : waitTillRunning
Killed by :
negated conditional → RUN_ERROR

158

1.1
Location : waitTillRunning
Killed by :
removed call to java/lang/Object::wait → RUN_ERROR

162

1.1
Location : waitTillRunning
Killed by :
removed call to java/lang/Thread::interrupt → NO_COVERAGE

166

1.1
Location : waitTillRunning
Killed by :
negated conditional → RUN_ERROR

170

1.1
Location : waitTillRunning
Killed by :
negated conditional → RUN_ERROR

171

1.1
Location : waitTillRunning
Killed by :
removed call to fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::close → NO_COVERAGE

189

1.1
Location : onAcceptSubmitSm
Killed by :
negated conditional → NO_COVERAGE

190

1.1
Location : onAcceptSubmitSm
Killed by :
removed call to java/util/concurrent/ExecutorService::execute → NO_COVERAGE

192

1.1
Location : onAcceptSubmitSm
Killed by :
replaced return value with null for fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::onAcceptSubmitSm → NO_COVERAGE

201

1.1
Location : onAcceptSubmitMulti
Killed by :
negated conditional → NO_COVERAGE

202

1.1
Location : onAcceptSubmitMulti
Killed by :
removed call to java/util/concurrent/ExecutorService::execute → NO_COVERAGE

205

1.1
Location : onAcceptSubmitMulti
Killed by :
replaced return value with null for fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::onAcceptSubmitMulti → NO_COVERAGE

242

1.1
Location : getReceivedMessages
Killed by :
replaced return value with Collections.emptyList for fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::getReceivedMessages → NO_COVERAGE

246

1.1
Location : getPort
Killed by :
replaced int return with 0 for fr/sii/ogham/testing/sms/simulator/jsmpp/JSMPPServerSimulator::getPort → RUN_ERROR

Active mutators

Tests examined


Report generated by PIT 1.13.1