SmppServerExtension.java
package fr.sii.ogham.testing.extension.junit.sms;
import fr.sii.ogham.testing.extension.junit.sms.config.ServerConfig;
import fr.sii.ogham.testing.extension.junit.sms.config.SmppServerConfig;
import fr.sii.ogham.testing.sms.simulator.SmppServerException;
import fr.sii.ogham.testing.sms.simulator.SmppServerSimulator;
import fr.sii.ogham.testing.sms.simulator.SmppServerStartException;
import fr.sii.ogham.testing.sms.simulator.config.SimulatorConfiguration;
import ogham.testing.io.github.resilience4j.retry.Retry;
import ogham.testing.io.github.resilience4j.retry.RetryConfig;
import ogham.testing.io.github.resilience4j.retry.RetryRegistry;
import org.junit.jupiter.api.extension.*;
import org.junit.platform.commons.support.AnnotationSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* JUnit {@link Extension} for starting a local SMPP server for integration
* tests.
*
* <p>
* The extension starts the server before every test, execute the test and stops
* the server.
* </p>
* <p>
* The server stores the received messages (raw messages). These messages are
* available in testing through {@link #getReceivedMessages()}.
* </p>
*
* @param <M>
* The type of the received messages
*
* @author Aurélien Baudet
*
*/
public abstract class SmppServerExtension<M> extends AbstractJUnitSmppServerExt<M> implements BeforeEachCallback, AfterEachCallback, ParameterResolver {
private static final Logger LOG = LoggerFactory.getLogger(SmppServerExtension.class);
/**
* Initializes with the default configuration to use for the SMPP server:
* <ul>
* <li>Starts on random port</li>
* <li>No delay</li>
* <li>No credentials</li>
* <li>Do not keep messages between tests</li>
* </ul>
*/
public SmppServerExtension() {
super();
}
/**
* Initializes with the configuration to use for the SMPP server
*
* @param builder
* the configuration for the server
*/
public SmppServerExtension(ServerConfig builder) {
super(builder);
}
@Override
public void beforeEach(ExtensionContext context) throws Exception {
RetryConfig retryConfig = builder.build().getStartRetryConfig();
Retry retry = RetryRegistry.of(retryConfig).retry("SmppServer.start()");
retry.getEventPublisher().onRetry((event) -> {
LOG.info("SMPP server failed to start on port {}. Retrying...", getPort());
});
try {
retry.<Void>executeCheckedSupplier(() -> {
start(context);
return null;
});
} catch (Throwable e) {
throw new SmppServerStartException("Failed to start SMPP server", e);
}
}
private void start(ExtensionContext context) throws SmppServerException {
SmppServerConfig config = AnnotationSupport.findAnnotation(context.getElement(), SmppServerConfig.class).orElse(null);
SimulatorConfiguration serverConfig = builder.annotationConfig(config).build();
server = initServer(serverConfig);
LOG.info("starting SMPP server on port {}...", getPort());
server.start();
LOG.info("SMPP server started on port {}", getPort());
}
@Override
public void afterEach(ExtensionContext context) throws Exception {
stop();
}
private void stop() throws SmppServerException {
LOG.info("stopping SMPP server...");
server.stop();
LOG.info("SMPP server stopped");
}
@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
return isSmppServerSimulatorParam(parameterContext) || isSmppServerExtensionParam(parameterContext);
}
@Override
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
if (isSmppServerSimulatorParam(parameterContext)) {
return server;
}
if (isSmppServerExtensionParam(parameterContext)) {
return this;
}
return null;
}
private boolean isSmppServerSimulatorParam(ParameterContext parameterContext) {
return SmppServerSimulator.class.isAssignableFrom(parameterContext.getParameter().getType());
}
private boolean isSmppServerExtensionParam(ParameterContext parameterContext) {
return SmppServerExtension.class.isAssignableFrom(parameterContext.getParameter().getType());
}
}