I need to write a webservice client and call it from Jenkins. Below are my questions:
What is the best way to call a web service from Jenkins? Any default plug in available? I need to pass a XML data as input to the web service.
If plug in is not the option, can you please let me know what are the other ways we can achieve this (ANT+JAVA etc)?
If you have any sample code, that would be great.
Thanks
Aravind
It would be great to know you just need to call your client as part of some complex flow, implemented as a Jenkins job, or you want to concentrate on webservice testing.
WillieT has pointed you to several simple recipes which can be used to solve some basic tasks. If you need more power, better reporting, some additional features please consider the following:
Apache JMeter (details)
Building a WebService Test Plan
Web Service Testing in JMeter
Webservice testing with JMeter
JMeter can be integrated into Jenkins using Performance plugin. Report example:
Grinder (details)
I prefer to use this tool, but it might be to complex/heavy for you.
Grinder script gallery
How to Test REST Web Service Using The Grinder
Grinder can be integrated into Jenkins using Grinder plugin. Report example:
If you develop a plugin, e.g. extends hudson.tasks.Builder, include the following in pom.xml for JAX-RS Client:
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.25.1</version>
</dependency>
A sample JAX-RS Client:
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;
import org.glassfish.jersey.client.ClientConfig;
public class RestClient {
private static String BASE_URL = "http://localhost:8090/rest";
private static String ACCESS_TOKEN = "8900***bc1";
public static String query(String path) {
ClientConfig config = new ClientConfig();
Client client = ClientBuilder.newClient(config);
WebTarget target = client.target(getBaseURI());
// token authentication
String result = target.path(path).request().header("Authorization", "Token " + ACCESS_TOKEN)
.accept(MediaType.APPLICATION_JSON).get(String.class);
return result;
}
private static URI getBaseURI() {
return UriBuilder.fromUri(BASE_URL).build();
}
}
where http://localhost:8090/rest is the base rest url outside of Jenkins environment. Anywhere in your plugin code, you can simple call this as needed:
String rsData = RestClient.query("/project_type");
assume the full rest web service url is
http://localhost:8090/rest/project_type
You may also use Apache HttpClient, or OkHttp
I used 'HTTP Request' Plugin. This plugin works for REST as well as SOAP api.
enter image description here
Plugin image
Related
I am trying to learn Java Web-Service using REST architecture.
So far I have created a class but I don't know how to consume that service.
Here's my code:
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;
#Path("/SericeCreation")
public class SericeCreation {
#GET
#Produces("text/plain")
public String display(){
return "hello";
}
}
Now, I want to call this display method.
Can anyone help me to understand how this can be achieved?
In a very simplified point of view, rest services are bound to Http calls, in your example the #GET annotation tells you that this method is accessed by making an HTTP GET call.
You can simply point your browser to the url generated for this service and you should see the "hello" response. The url is something like this http://<server>:<port>/<AppContext>/<rest-servlet-mapping>/SericeCreation where:
<server> is your server name. Typically localhost
<port> the default server port number. If you are usin Jboss 8080
<AppContext> typically the name of your applicaction (War file)
<rest-servlet-mapping> the RestEasy or Jersey frameworks servlet path
/SericeCreation this comes from the #Path annotation that is used
in your class.
Another way to intereact with your services is using a Rest Client like this one.
And of course, if you want to create a java client you can use the apache http client library, java.net.* package or others. Remember, rest services are accessed by making http calls.
I recommend you read this two tutorials to get a general idea of rest architecture.
Rest RefCard
Beginner's Guide
This great tutorial shows you a lot of examples using Jersey or RestEasy in order to implement Java Rest Services.
How to consume Web service suing Apache CXF client API.
I have generated the client Code using eclispe but I didn't found any document specifying how to use that generated code in my web application.
How to configure CXF? I am using tomcat to run my java web appliation.
How to use the generated code?
Do I need to add anyhting in my my web.xml?
I have downloaded CXF binaries from apache CXF website but don't know which libraries are needed. I am affraid i may end up adding all the jars.
I am using Tomcat 7, Java 1.6 and plane jsp/Servlet for my application
I am new to web services.
Thanks in advance
One sample code that may help.
URL wsdlurl=SOAPWebServiceTransport.class.getClassLoader().
getResource("my.wsdl");
// MyService will be one of the service class that you have generated (with different name ofcourse)and which must be extending Service class
//getOnlineServicePort will be a method (with different name ofcourse) in your service class which will give you the interface referrer using which you'll call the webservice method
OnlinePort service= new MyService(wsdlurl).getOnlineServicePort();
Client proxy = ClientProxy.getClient(service);
//configure security user name password as required
//Add interceptors if needed
//Now you can directly call the webservice methods using the service object
service.method(parameter)
you can also refer to some example one is here
I have a piece of code that runs inside Spark Streaming and tries to get some data from a RESTful web service. The code snippet in question is:
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:2222/rest");
target = target.path("annotate")
.queryParam("text", UrlEscapers.urlFragmentEscaper().escape(spotlightSubmission))
.queryParam("confidence", "0.3");
logger.warn("!!! DEBUG !!! target: {}", target.getUri().toString());
String response = target.request().accept(MediaType.APPLICATION_JSON_TYPE).get(String.class);
logger.warn("!!! DEBUG !!! Spotlight response: {}", response);
When run inside a unit test as follows:
mvn clean test -Dtest=SpotlightTest#testCountWords
it contacts the RESTful web service and retrieves some data as expected. But when the same code is run as part of the application that is submitted to Spark, using spark-submit script, I receive the following error:
java.lang.NoSuchMethodError: javax.ws.rs.core.MultivaluedMap.addAll(Ljava/lang/Object;[Ljava/lang/Object;)V
as soon as it tries to run:
String response = target.request().accept(MediaType.APPLICATION_JSON_TYPE).get(String.class);
I'm using Spark 1.1.0 and for consuming the web service I'm using Jersey in my project's pom.xml:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.14</version>
</dependency>
So I suspect that when the application is submitted to Spark, somehow there's a different JAR in the environment that uses a different version of Jersey / javax.ws.rs.*
Does anybody know which version of Jersey / javax.ws.rs.* is used in the Spark environment, or how to solve this conflict?
Disclaimer: I'm not a Spark user
But doing a quick search I found the yarn module depends on Jersey 1.9.
What type of web service is supported by gwt application i have tried using Jersey, RESTful, Restlet, but nothing works with GWT. I want to deploy Web-Service on Tomcat and GWT application on app engine.
You can use RPC and RequestBuilder:
https://developers.google.com/web-toolkit/doc/latest/DevGuideServerCommunication
You can also use RESTful services:
How to call RESTFUL services from GWT?
Thanx all for your suport . . i have got the answer for my question.
i created a restfull web service using Jersey and called it using the following code in my gwt app engine application:
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource(UriBuilder.fromUri("http://localhost:8080/de.vogella.jersey.first").build());
String obj=service.path("rest").path("bye").accept(MediaType.TEXT_PLAIN).get(String.class);
and the web application code is :
package de.vogella.jersey.first;
import javax.ws.rs.*;
#Path("/bye")
public class Hello {
// This method is called if TEXT_PLAIN is request
#GET
#Produces(MediaType.TEXT_PLAIN)
public String sayPlainTextHello() {
return "Hello it worked";
}
For Web Application Code refer to this link:
http://www.vogella.com/articles/REST/article.html
Is it possible to use #RolesAllowed annotation on a JAX-WS webservice and if so how?
I have a webservice on glassfish 3.1.1 using Basic Authentication but restrictions expressed using #RolesAllowed are ignored. The role information should be available, as I can access it like this:
#Resource
WebServiceContext wsContext;
if (wsContext.isUserInRole("READ"))
log.info("Role: READ");
I get the expected role but still all methods are accessible, even if #RolesAllowed is set to different role. #DenyAll is not working as well.
If these annotations are not supported, is it possible to use deployment descriptors to manage access to webservice methods based on user roles?
Edit:
This part of the JAVA EE 6 tutorial describes the usage of #RolesAllowed annotation. It reads
For Java EE components, you define security roles using the #DeclareRoles and #RolesAllowed metadata annotations.
Web services are not listed as Java EE components in the first part of the tutorial, so it looks like the security annotations are not supported.
Edit2
Following Izan's post, I gave this another try. Here is what I did:
#Webservice
#DeclareRoles(value = {"READ", "UPDATE", "DELETE"})
public class ServiceImpl implements Service {
#Override
#WebMethod(operationName = "helloWorld")
#RolesAllowed({"NONE"})
public String helloWorld() throws Exception {
return "Hello World!";
}
}
Using this kind of setup, everybody can access the method, no matter what roles are set. Users get authenticated (can see that in audit.log) but no authorization takes place. As stated above, I can access the role from WebServiceContext (I actually do manual authorization using this info).
Adding #Stateless annotation, let's me use the security annotations. So #permitAll works as expected. But using roles still does not work, as user don't get authenticated now. They show up as ANONYMOUS in audit log and access is denied to them.
My web.xml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>OneMore</display-name>
<security-constraint>
<display-name>WebServiceSecurity</display-name>
<web-resource-collection>
<web-resource-name>Authorized users only</web-resource-name>
<url-pattern>/service</url-pattern>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>READ</role-name>
<role-name>UPDATE</role-name>
<role-name>DELETE</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<security-role>
<role-name>READ</role-name>
</security-role>
<security-role>
<role-name>UPDATE</role-name>
</security-role>
<security-role>
<role-name>DELETE</role-name>
</security-role>
</web-app>
Glassfish-web.xml just maps role names to group names, like this:
<security-role-mapping>
<role-name>READ</role-name>
<group-name>READ</group-name>
</security-role-mapping>
Edit 3
Thanks to Izan and countless tries later I finally got it working.
As said before, the main point was switching from a plain web service to an EJB web service by adding #Stateless annotation. This allows for using the security annotations.
This change required to change the deployment descriptors as well. While the original web service required a glassfish-web.xml for setting up the roles, a glassfish-ejb-jar.xml is required afterwards.
Maybe this is a pretty dumb question, but are your webservices EJBs? As noted in Security Annotations and Authorization in GlassFish and the Java EE 5 SDK
The annotations #PermitAll, #DenyAll and #RolesAllowed are defined for specifying permissions of EJB business method
I use those annotations with bottom-up WS from stateless EJBs and they work like a charm in JBoss.
EDIT 1 #TPete
I'll add some code to show you more or less what I'm doing.
#Stateless
#WebService()
#WebContext(contextRoot = WSContextRoot.CTX_ROOT,
authMethod = "BASIC")
#EndpointConfig(configName = "Standard WSSecurity Endpoint")
#SecurityDomain(value = "myDeclaredDomain")
#RolesAllowed({ "AUTHORISED" })
#SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
public class MyWS implements MyInterface {
#Override
public void doSomething(){
//impl
}
}
And as for the interface
#Remote
#WebService
public interface MyInterface {
#WebMethod(operationName="doSomething")
public void doSomething();
}
WebContext, EndpointConfig and SecurityDomain are JBoss annotation, but I suppose there is something similar for GlassFish, or an equivalent way of doing it. The security domain is included in a deployment descriptor for jboss, and defined in the login-config.xml from the configuration files of JBoss.
EDIT 2 #TPete
I suppose you need to add some EJB deployment descriptors from Glassfish, a sun-ejb-jar.xml file package inside your EAR. Again, from the same article as posted in the answer, there is a Using Deployment Descriptors chapter that states
For EJB web service endpoints with #RolesAllowed, you need to specify the type of authentication to use by specifying the and elements in sun-ejb-jar.xml. For username-password authentication, set the element to BASIC, as shown in the following example. This step is required only for EJB web service endpoints, and is not required for EJBs.
Since you are defining an EJB web service endpoint, I think you should put this descriptor in you EAR. Have a quick look at that article, it describes quite well the process you are following :-)
The original question is old but I'm still leaving a comment just in case someone like me stumbles across it. Starting with EJB 3.1, EJBs may be packaged in a WAR module but when it comes to securing them, EJB deployment descriptors need to be used. What is not clear in the spec is that EJBs may not be declared as Servlets in web.xml or else the app will fail to start.
Here's an excellent article about packaging EJBs in WAR modules and the differences with packaging in EJB JAR modules:
http://pic.dhe.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=%2Fcom.ibm.websphere.nd.multiplatform.doc%2Finfo%2Fae%2Fae%2Fcejb_ejbinwar.html