Is it possible to write JUnit tests that are agnostic to your JAX-RS implementation? - rest

I wrote a REST web service using JAX-RS that knows nothing about the specific JAX-RS implementation I chose. I happen to be using TomEE which means my JAX-RS implementation is ApacheCXF.
I'd like to write unit tests for the web service that also know nothing about the JAX-RS implementation. Is this possible? So far every example I've found involves using classes from a specific JAX-RS implementation (JAXRSClientFactory for ApacheCXF, Jersey Test Framework, etc).
I've started experimenting with tomee-embedded and am able to test my EJB's but it doesn't seem to startup the REST services.

My solution was to use Arquillian paired with an Embedded TomEE. Arquillian provides a ton of functionality but I'm only using it to start/stop the Embedded TomEE. Therefore, all I needed to do was add this to my pom.xml:
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>arquillian-tomee-embedded</artifactId>
<version>${tomee.version}</version>
<scope>test</scope>
</dependency>
Then I could write a JUnit test with a little extra Arquillian stuff and plain JAX-RS:
#RunWith(Arquillian.class)
public class MyServiceIT {
#ArquillianResource
private URL webappUrl;
#Deployment()
public static WebArchive createDeployment() {
return ShrinkWrap.create(WebArchive.class)
.addClasses(MyService.class)
.addAsWebInfResource("META-INF/persistence.xml") //Refers to src/main/resources/META-INF/persistence.xml
.addAsWebInfResource("test-resources.xml", "resources.xml") //Refers to src/test/resources/test-resources.xml
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
}
#Test
public void randomTest() throws URISyntaxException {
//Get data from the web service.
Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target(webappUrl.toURI().resolve("myentity"));
Response response = webTarget.request(MediaType.APPLICATION_JSON).get();
int status = response.getStatus();
List<MyEntity> myEntities = response.readEntity(new GenericType<List<MyEntity>>() {});
//Perform some tests on the data
}
}

Related

WebServiceContext is null when both SOAP and RESTful wars are bundled in a single EAR and deployed in WebSphere

In our application, the business logic lies in a different layer. The SOAP Web Service is already available. Now I'm developing REST support to that application.
The SOAP is designed to use #WebServiceProvider. The WebServiceContext is injected by #Resource. The REST is designed to be initialized during deployment or start of the server using ServletContextListener. SOAP is working when the REST war is not present in the EAR. But WebServiceContext is null when the REST war is added to the EAR.
Strangely, if I change the REST code to be initialized on each request by removing ServletContextListener, the SOAP works without any issue. But it adds the overhead of initializing the REST on each request.
#WebServiceProvider(portName = "soapPort",
serviceName = "soapService",
targetNamespace = "http://webservices.soap.test.com",
wsdlLocation = "test.wsdl")
#ServiceMode(Mode.PAYLOAD)
public class WebServiceProvider implements Provider {
protected WebServiceContext context;
#Override
protected WebServiceContext getWebServiceContext() {
return context;
}
#Resource
public void setContext(final WebServiceContext context) {
this.context = context;
}
#Override
public Source invoke(final Source request) {
return process(request);
}
}
SOAP and REST are working fine when it's deployed in JBoss. The problem occurs only when the EAR is deployed in WebSphere.
Any help would be appreciated.

Swagger + jaxrs + embedded jetty + no web.xml

I have maven project with embedded jetty server.
I have already created apis using JAX-RS, which are working properly. Now I want to create swagger documentation for my apis.
To start with swagger I have added servlet configuration as describe below :
#WebServlet(name = "SwaggerConfig")
public class SwaggerServlet extends HttpServlet {
#Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
System.out.println("init SwaggerServlet");
BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion("1.0.0");
beanConfig.setSchemes(new String[]{"http"});
beanConfig.setHost("localhost:8082");
beanConfig.setBasePath("/api");
beanConfig.setResourcePackage("com.myCompany.myApisResourcePackage");
beanConfig.setScan(true);
}
}
Also, in main method,
along with my jersey configuration I have added following code :
//swagger
ServletHolder swaggerServletHolder = new ServletHolder(SwaggerServlet.class);
swaggerServletHolder.setInitOrder(1);
swaggerServletHolder.setInitParameter("swagger.api.basepath", "http://localhost:8082");
context.addServlet(swaggerServletHolder, "/api/*");
//swagger end
So, the problem is, I am not able to find where swagger.json will be created.
In this case, swagger scans packages as server log says it, but swagger.json still not getting created.
Note: I am currently not adding swagger-ui as I think it is not mandatory for creating swagger.json
I got swagger json by hitting url "localhost:8082/swagger.json". I used same configuration as posted in my question.

Struggling with Bean Validation within a JAX RS running in a Glassfish Container

I'm working on a simple Java EE Application, using Glassfish.
Everything runs fine, my Entity and Session Beans are working.
I also created some JAX RS Resources to invoke the Session Beans, which also works fine.
Now I'm struggling with Bean Validation.
Let's have a look at a little snippet:
#GET
#Path( "{portaluser}" )
#NotNull
public PortaluserResponse load( #PathParam( "portaluser" ) #NotBlank #Email final String strEmail )
{ ... some implementation ... }
My Jersey Application, which of course extends ResourceConfig looks like this:
public JerseyApplication()
{
packages( PortaluserService.class.getPackage().getName() );
register( JacksonFeature.class );
register( ValidationConfig.class);
property( ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true );
}
In my pom.xml I included following dependency:
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-bean-validation</artifactId>
<version>2.9</version>
</dependency>
If I invoke the REST Service with nonsense data, the validation doesn't kick in.
Why is that? I expect to get a validation error.
I found a jersey-Sample which covers the bean validation stuff. My REST-Resource works within that project.
The only difference is, that jersey-Sample doesn't run in Glassfish, but in a Jetty.
Can it be that jersey bean validation doesn't work when running in a Java EE container?
Would appreciate some hints.

Restlet - Connection Problems - 406 Not Acceptable - Plain Text

couldnt find somewhere else advice.
I am writing a Restlet JSE Client for a Jersey(!) Restful Service. I already wrote a Jersey client for that and it is working, so the jersey service is alright. Now I get problems in writing a restlet client:
My Service root adress is:
http://localhost:8080/com-project-core/rest, so I call:
ClientResource = service = new ClientResource("http://localhost:8080/com-project-core/rest");
My Basic Auth Credentiels are admin and xxx, so I call:
service.setChallengeResponse(ChallengeScheme.HTTP_BASIC, "admin", "xxx");
Now the problems:
ClientResource service = new ClientResource("http://localhost:8080/com-project-core/rest/ping");
calls up my service. After that I try
String myString = service.get(String.class);
System.out.println(myString);
I get a:
08.07.2012 17:41:48 org.restlet.engine.http.connector.HttpClientHelper start
INFO: Starting the default HTTP client
in my output. Not more! The Junit Test says:
Not Acceptable (406) - Not Acceptable
So he can find the resource but cannot produce #Produces("text/plain") ??
So when I remove #Produces("text/plain") on server side it works!!
For the resourcey my server side looks like this:
#Path("/ping")
#RolesAllowed({"admin", "user"})
public class ConnectedResourceBean implements ConnectedResourceIF {
#GET
#Produces("text/plain")
public String getPingMessage() throws NamingException {
return "Hello World";
}
}
For my pom in set this dependencies:
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet</artifactId>
<version>${restlet.version}</version>
</dependency>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet.ext.xstream</artifactId>
<version>${restlet.version}</version>
</dependency>
As I said, its working with my jersey client.
No way: Restlet had problems with
#Produces("text/plain")
on jersey server side. Can someone explain me that fact?
Edit:
Made it work with
<properties>
<restlet.version>2.1-M3</restlet.version>
</properties>

Shorten path of REST service in JBoss Seam application

I'm pretty new to JBoss and Seam. My project has a REST service of the style
#Path("/media")
#Name("mediaService")
public class MediaService {
#GET()
#Path("/test")
public Response getTest() throws Exception {
String result = "this works";
ResponseBuilder builder = Response.ok(result);
return builder.build();
}
}
I can reach this at http://localhost:8080/application/resource/rest/media/test. However, I don't like this URL at all and would prefer something much shorter like http://localhost:8080/application/test.
Can you please point me in the right direction on how to configure the application correctly? (Developing using Eclipse)
web.xml will contain seam resource servlet mapping , this should be modified to /*, and if you have more configuration to the path it will be in components.xml ,if it is resteasy seam is configured to use, it will look like the following
<resteasy:application resource-path-prefix="/rest"/>