Deploy production and UAT web services at once - web-services

I have a web service that runs on Wildfly on http://localhost:8080/ws which I deploy from maven using wildfly-maven-plugin.
I would like to deploy the same web service, but pointing to a test datasource, to http://localhost:8080/ws_test so I can use it as a UAT enviroment and run tests without affecting the production database.
Is there an easy way to do that?
More information:
The root (ws) is configured in jboss-web.xml:
<jboss-web>
<context-root>/ws</context-root>
</jboss-web>
I have this class:
#ApplicationPath("/")
public class MyApplication extends Application { }
my production datasource is "hardcoded":
#Resource(lookup = "java:jboss/jdbc/prod")
private javax.sql.DataSource ds;
the maven pom (extract):
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>1.0.2.Final</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
<configuration>
<hostname>localhost</hostname>
<username>user</username>
<password>pass</password>
</configuration>
</execution>
</executions>
</plugin>

What I ended up doing is this:
add a second datasource corresponding to the test DB:
#Resource(lookup = "java:jboss/jdbc/test")
private javax.sql.DataSource dsTest;
let my controller know it could be called from two URIs:
#Path("{a:(test/)?}some_page")
public class MyController { ... }
direct the calls to the right DB:
private #Context UriInfo uriInfo;
DataSource getDatasource() {
LOG.info("in mode: {}", uriInfo.getPath());
return uriInfo.getPath().startsWith("/test") ? dsTest : ds;
}

Related

Exception on service activation in mock OSGi context

In my Maven project, I've created a simple OSGi service that does nothing but accepts one reference:
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
#Component
public class MyFoo {
#Reference
private ResourceResolverFactory factory;
}
Then, using osgi-mock tutorial, I've created the following test class:
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
public class MyFooTest {
#Rule
public OsgiContext mockContext = new OsgiContext();
#Test
public void test() {
ResourceResolverFactory mockFactory = Mockito.mock(ResourceResolverFactory.class);
mockContext.registerService(ResourceResolverFactory.class, mockFactory);
mockContext.registerInjectActivateService(new MyFoo());
}
}
The test crashes on the last line with the following exception:
org.apache.sling.testing.mock.osgi.NoScrMetadataException: No OSGi SCR metadata found for class MyFoo
at org.apache.sling.testing.mock.osgi.OsgiServiceUtil.injectServices(OsgiServiceUtil.java:381)
at org.apache.sling.testing.mock.osgi.MockOsgi.injectServices(MockOsgi.java:148)
at org.apache.sling.testing.mock.osgi.context.OsgiContextImpl.registerInjectActivateService(OsgiContextImpl.java:153)
at org.apache.sling.testing.mock.osgi.context.OsgiContextImpl.registerInjectActivateService(OsgiContextImpl.java:141)
at MyFooTest.testGetResolver(MyFooTest.java:22)
//snippet
Following the advice on the internet, I've reached this configuration guide and ensured that my pom.xml has exactly this configuration for maven-bundle-plugin - this however did not resolve the issue.
Any idea where am I making a mistake?
I tried replicating your issue, ran into the same exception initially and got it working now. Issue is probably due to spoiled classpath because of transitive dependencies between maven-scr-plugin and maven-bundle-plugin.
Ensure you have the following in place:
Use osgi-mock 2.x mock dependency which is OSGI R6 compatible. This is what I used.
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.testing.osgi-mock</artifactId>
<version>2.3.6</version>
<scope>test</scope>
</dependency>
Remove scr maven plugins and dependencies (maven-scr-plugin and org.apache.felix.scr) as this leads to classpath conflicts when used in conjunction with OSGi R6 annotations. This is the version of maven-bundle-plugin I've used. I picked up all the required dependencies from here.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.2.0</version>
</plugin>
Ensure your plugin build section contains the required configurations to generate the required DS metadata. You can refer to the felix docs that you've linked for more info on this.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>scr-metadata</id>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<exportScr>true</exportScr>
<instructions>
<Bundle-SymbolicName>com.aem.chula.chula</Bundle-SymbolicName>
<Sling-Model-Packages>
com.aem.models
</Sling-Model-Packages>
<_dsannotations>*</_dsannotations>
<_metatypeannotations>*</_metatypeannotations>
</instructions>
</configuration>
</plugin>
Do a mvn clean install which will generate the DS output in /OSG-INF.
Run your tests. I've used MockitoJunitRunner, should work fine with PowerMock as well.
In my case I had to add the ds-annotations dependency
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.scr.ds-annotations</artifactId>
<version>1.2.10</version>
<scope>provided</scope>
</dependency>
As described in http://felix.apache.org/documentation/subprojects/apache-felix-maven-scr-plugin/apache-felix-maven-scr-plugin-use.html

why ElastiMq keeps requiring server and check parameters since I am passing it

I am using AWS SQS for the first time. I work in certain company which blocks us via firewall to connect from our local network to SQS for some reasons beyond my control. I can upload anything I have developed to our TomCat in AWS or even run via our Linux command line with our ec2-user (upload via WinSCP and trigger via Putty).
Since I need to provide certain solution using sqs but I can't debug accessing it from my Eclipse I am interested to mock sqs. Additionally, I see advantages on such approach from test perspective. That said, after few hours searching I found exactly what I need: http://www.schibsted.pl/blog/mocking-amazon-sqs-with-elasticmq/
I downloaded the example (https://github.com/JanGurda/elastc-mq-rule-sample) but I can't start it. I understand that there is an elasticmq embbeded which should be started together with such jar. I tried other way by downloading the elasticmq and started it before running the sample but I am still getting the same output.
Basically, I am getting this output
usage: java -jar project.jar [-h] [-v] {server,check} ...
positional arguments:
{server,check} available commands
optional arguments:
-h, --help show this help message and exit
-v, --version show the application version and exit
It seems I am doing something very silly but I didn't find a north.
PS. I checked and the pom has lombok and elasticmq properly settup.
pom
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pl.schibsted.spid</groupId>
<artifactId>elastc-mq-rule-sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-core</artifactId>
<version>0.8.0</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sqs</artifactId>
<version>1.10.1</version>
</dependency>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-testing</artifactId>
<version>0.8.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.elasticmq</groupId>
<artifactId>elasticmq-rest-sqs_2.11</artifactId>
<version>0.8.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>pl.schibsted.spid.elasticmq.server.ElasticMqRuleSampleApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<includes>
<include>**/ITest*.java</include>
</includes>
</configuration>
<executions>
<execution>
<id>integration-tests</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
DropwizardAppRule:
public class ITestPingResource {
#ClassRule
public static DropwizardAppRule<ElasticMqRuleSampleApplicationConfiguration> app =
new DropwizardAppRule<>(ElasticMqRuleSampleApplication.class,
ITestPingResource.class.getClassLoader().getResource("test.yml").getPath());
#ClassRule
public static SqsRule sqs = new SqsRule(SqsRuleConfiguration.builder()
.queue("sample-queue").port(8888).build());
private Client client = ClientBuilder.newClient();
#After
public void tearDown() {
sqs.purgeAllQueues();
}
#Test
public void shouldPublishProcessedRequestPayload() throws Exception {
// given
String toSend = "abcdefgh";
// when
Response response = client
.target("http://127.0.0.1:" + app.getLocalPort() + "/ping")
.request().post(Entity.json(toSend));
// then
assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
List<Message> messagesFromQueue = sqs.getQueue("sample-queue").read(10);
assertEquals(1, messagesFromQueue.size());
assertEquals("ABCDEFGH", messagesFromQueue.get(0).getBody());
}
}
test.yml
queueUrl: http://localhost:8888/queue/sample-queue
awsAccessKey: x
awsSecretKey: x
main:
public class ElasticMqRuleSampleApplication extends Application<ElasticMqRuleSampleApplicationConfiguration> {
public static void main(String[] args) throws Exception {
new ElasticMqRuleSampleApplication().run(args);
}
#Override
public void run(ElasticMqRuleSampleApplicationConfiguration configuration, Environment environment) throws Exception {
PingResource resource = new PingResource(configuration);
environment.jersey().register(resource);
}
}
Demetrio,
The error you get is simply standard output of Dropwizard. You should use “server” parameter to start Dropwizard application. So command you use to start Dropwizard is java -jar <> server.
If you however would like to run sample integration test (which I discussed in my article) just use Maven. Type mvn clean install. It’ll build project and run integration test.
Thanks

jmeter-maven-plugin blocked at getting service port from "javax.xml.ws.Service" when executing JMX file

I'm using jmeter-maven-plugin to run Performance test using JMX files:
<plugins>
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>1.9.0</version>
<dependencies>
<dependency>
<groupId>com.gemalto.pse.pim</groupId>
<artifactId>pim-ws-client</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>jmeter-tests</id>
<phase>verify</phase>
<goals>
<goal>jmeter</goal>
</goals>
<configuration>
<testFilesIncluded>
<jMeterTestFile>file_1.jmx</jMeterTestFile>
<jMeterTestFile>file_2.jmx</jMeterTestFile>
</testFilesIncluded>
</configuration>
</execution>
</executions>
</plugin>
The JMX file file_1.jmx execute a method in a class that call a web-service as follows:
final String ENDPOINT_ADDRESS = "http://10.256.45.147:8080/service-ejb/ServiceClass?wsdl";
final QName SERVICE_NAME = new QName(
"http://service.tools.com/", "ServiceClassService");
javax.xml.ws.Service service = javax.xml.ws.Service.create(
new URL(ENDPOINT_ADDRESS), SERVICE_NAME);
IServiceClass myService = dataFinderService.getPort(IServiceClass.class);
The problem is that Jmeter plugin is blocked at execution of file_1.jmx and does not process the file_2.jmx, the process is blocked at:
IServiceClass myService = dataFinderService.getPort(IServiceClass.class);
And when i cancel the execution (type Ctrl+C) the process continues and Jmeter-maven-plugin generate the output report file
Any one have encounter this problem ? ... Thanks a lot in advance :)
The problem is resolved, all what i implimented is right, the problem is just that i should use jmeter-maven-plugin version 1.8.0 instead of 1.9.0 :)

Configuring context path for jetty with static resources

I have a maven application configured to start Jetty and also load statics from ../client . Configuration is below:
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.4.v20120524</version>
<configuration>
<scanIntervalSeconds>25</scanIntervalSeconds>
<connectors>
<connector implementation="org.eclipse.jetty.server.bio.SocketConnector">
<port>9095</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
<webAppSourceDirectory>../client/</webAppSourceDirectory>
<webAppConfig>
<resourceBases>
<resourceBase>src/main/webapp</resourceBase>
<resourceBase>../client/</resourceBase>
</resourceBases>
</webAppConfig>
</configuration>
</plugin>
What I am trying to do is to move only webapp under /API resource base. To be more explicit I want to have the mappings:
src/main/webapp ---> /API
../client/ ---> /
Finally found the right config:
<webAppConfig>
<contextPath>/API</contextPath>
</webAppConfig>
<contextHandlers>
<contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
<contextPath>/</contextPath>
<resourceBase>../client/</resourceBase>
</contextHandler>
</contextHandlers>

Connect to AXIS 1.4 Webservice through a proxy

I am using AXIS 1.4 to generate the subs for my webservice. The generation works fine as it is, but I am facing a problem to connect to the webservice though a WebProxy.
I use the axistools-maven-plugin to generate my axis classes.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>axistools-maven-plugin</artifactId>
<version>1.4</version>
<configuration>
<urls>
<url>http://mywiki/rpc/soap-axis/confluenceservice-v1?wsdl</url>
</urls>
<outputDirectory>${project.build.directory}/generated-wsdl-sources</outputDirectory>
<packageSpace>de.allianz.wsdl.confluence</packageSpace>
<testCases>false</testCases>
<serverSide>false</serverSide>
<subPackageByFileName>false</subPackageByFileName>
</configuration>
<executions>
<execution>
<id>add wsdl source</id>
<phase>generate-sources</phase>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>axis</groupId>
<artifactId>axis</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
If I use the following properties before the connect - everything works fine, but I set the properties VM wide which is not desirable:
public void setProxyHost(String proxyHost) {
this.proxyHost = proxyHost;
if(proxyHost != null){
System.setProperty("http.proxyHost", proxyHost);
AxisProperties.setProperty("http.proxyHost", proxyHost);
}
}
public void setProxyPort(int proxyPort) {
this.proxyPort = proxyPort;
System.setProperty("http.proxyPort", ""+proxyPort);
AxisProperties.setProperty("http.proxyPort", ""+proxyPort);
}
Is there any way to tell axis to generate sources to connect through a proxy? (I already read about how th specify a proxy when generating the sources (to access the WSDL) but this is not what I need - I need to connect to the final webservice through a proxy)
I already tried to do the following:
private ConfluenceSoapService createConfluenceSoapService()
throws ServiceException {
ConfluenceSoapServiceServiceLocator csssl = new ConfluenceSoapServiceServiceLocator();
ConfluenceSoapService confluenceSoapService;
if (confluenceserviceAddress == null) {
confluenceSoapService = csssl.getConfluenceserviceV1();
} else {
URL endpoint;
try {
//endpoint = new URL(confluenceserviceAddress);
endpoint = new URL("http",proxyHost,proxyPort,confluenceserviceAddress);
} catch (java.net.MalformedURLException e) {
throw new javax.xml.rpc.ServiceException(e);
}
confluenceSoapService = csssl.getConfluenceserviceV1(endpoint);
}
ConfluenceserviceV1SoapBindingStub stub = (ConfluenceserviceV1SoapBindingStub) confluenceSoapService;
stub.setTimeout(timeout);
return confluenceSoapService;
}
and change the endpoint to an URL using a proxy - but this leads to the following problem at runtime (even though the proxy settings are set correctly to the URL object. If I use the URL object without the proxy, I get to errors.
java.net.MalformedURLException: For input string: "8080http:"
at org.apache.axis.AxisFault.makeFault(AxisFault.java:101)
at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:154)
at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
My Questions:
- Am I missing something?
- Is there a way to tell axis to generate the sources to work with a web proxy (to be accessed through a web proxy)
Thanks a lot for your help! Please let me know if you need more/other information to help.
Try this, in my case it works, it is not a good idea to use System.setProperty as it sets the value for VM. Using AxisProperties will set the value only for specific connection. I am using AXIS 1.4 client.
AxisProperties.getProperties().put("proxySet","true");
AxisProperties.setProperty("http.proxyHost", PROXY_HOST);
AxisProperties.setProperty("http.proxyPort", PROXY_PORT);