package au.com.dius.pact.provider.junit.target; import au.com.dius.pact.model.Interaction; import au.com.dius.pact.provider.ConsumerInfo; import au.com.dius.pact.provider.ProviderInfo; import au.com.dius.pact.provider.ProviderVerifier; import au.com.dius.pact.provider.junit.Provider; import au.com.dius.pact.provider.junit.TargetRequestFilter; import au.com.dius.pact.provider.junit.sysprops.SystemPropertyResolver; import au.com.dius.pact.provider.junit.sysprops.ValueResolver; import org.apache.http.HttpRequest; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.TestClass; import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; /** * Out-of-the-box implementation of {@link Target}, * that run {@link Interaction} against http service and verify response */ public class HttpTarget extends BaseTarget { private final String path; private final String host; private final int port; private final String protocol; private final boolean insecure; /** * @param host host of tested service * @param port port of tested service */ public HttpTarget(final String host, final int port) { this("http", host, port); } /** * Host of tested service is assumed as "localhost" * * @param port port of tested service */ public HttpTarget(final int port) { this("http", "localhost", port); } /** * @param host host of tested service * @param port port of tested service * @param protocol protocol of tested service */ public HttpTarget(final String protocol, final String host, final int port) { this(protocol, host, port, "/"); } /** * @param host host of tested service * @param port port of tested service * @param protocol protocol of tested service * @param path protocol of the tested service */ public HttpTarget(final String protocol, final String host, final int port, final String path) { this(protocol, host, port, path, false); } /** * * @param host host of tested service * @param port port of tested service * @param protocol protocol of the tested service * @param path path of the tested service * @param insecure true if certificates should be ignored */ public HttpTarget(final String protocol, final String host, final int port, final String path, final boolean insecure){ super(); this.host = host; this.port = port; this.protocol = protocol; this.path = path; this.insecure = insecure; } /** * @param url url of the tested service */ public HttpTarget(final URL url) { this(url, false); } /** * * @param url url of the tested service * @param insecure true if certificates should be ignored */ public HttpTarget(final URL url, final boolean insecure) { this(url.getProtocol() == null ? "http" : url.getProtocol(), url.getHost(), url.getPort() == -1 && url.getProtocol().equalsIgnoreCase("http") ? 8080 : url.getPort() == -1 && url.getProtocol().equalsIgnoreCase("https") ? 443 : url.getPort(), url.getPath() == null ? "/" : url.getPath(), insecure); } /** * {@inheritDoc} */ @Override public void testInteraction(final String consumerName, final Interaction interaction) { ProviderInfo provider = getProviderInfo(); ConsumerInfo consumer = new ConsumerInfo(consumerName); ProviderVerifier verifier = setupVerifier(interaction, provider, consumer); Map<String, Object> failures = new HashMap<>(); verifier.verifyResponseFromProvider(provider, interaction, interaction.getDescription(), failures); try { if (!failures.isEmpty()) { verifier.displayFailures(failures); throw getAssertionError(failures); } } finally { verifier.finialiseReports(); } } @Override protected ProviderVerifier setupVerifier(Interaction interaction, ProviderInfo provider, ConsumerInfo consumer) { ProviderVerifier verifier = new ProviderVerifier(); setupReporters(verifier, provider.getName(), interaction.getDescription()); verifier.initialiseReporters(provider); verifier.reportVerificationForConsumer(consumer, provider); if (interaction.getProviderState() != null) { verifier.reportStateForInteraction(interaction.getProviderState(), provider, consumer, true); } verifier.reportInteractionDescription(interaction); return verifier; } protected ProviderInfo getProviderInfo() { Provider provider = testClass.getAnnotation(Provider.class); final ProviderInfo providerInfo = new ProviderInfo(provider.value()); providerInfo.setPort(port); providerInfo.setHost(host); providerInfo.setProtocol(protocol); providerInfo.setPath(path); providerInfo.setInsecure(insecure); if (testClass != null) { final List<FrameworkMethod> methods = testClass.getAnnotatedMethods(TargetRequestFilter.class); if (!methods.isEmpty()) { providerInfo.setRequestFilter((Consumer<HttpRequest>) httpRequest -> methods.forEach(method -> { try { method.invokeExplosively(testTarget, httpRequest); } catch (Throwable t) { throw new AssertionError("Request filter method " + method.getName() + " failed with an exception", t); } })); } } return providerInfo; } }