https://www.baeldung.com/spring-mock-rest-template
the code in the article is broken, here https://github.com/vernetto/mockrest you find a fixed version.
It's very simple and elegant solution.
You see @InjectMocks and @Mock annotations in action. Here they are explained https://www.baeldung.com/mockito-annotations
Here the javadoc of https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/test/web/client/MockRestServiceServer.html
Showing posts with label REST. Show all posts
Showing posts with label REST. Show all posts
Thursday, October 17, 2019
Thursday, May 17, 2018
Swagger Editor and generation of a Java API for REST Nexus API
first, let's run a docker container for swagger editor:
https://hub.docker.com/r/swaggerapi/swagger-editor/
docker run -d --rm --name swaggereditor -p 9080:8080 swaggerapi/swagger-editor
http://localhost:9080/
then http://localhost:8181/service/rest/swagger.json (8181 is the Nexus port) , download the file, feed it into the swagger-editor (file , import file). Import URL will not work, apparently you must be authenticated in Nexus to be able to download it.
then generate client /java , this will produce a java-client-generated.zip file with your Java client API. You extract this file, run "mvn install", then open the README.md to understand how it works...
I create a Java project, add this maven dependency
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-java-client</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
then try this code:
actually you don't even need to run swagger-editor locally, you can use the online version https://editor.swagger.io//?_ga=2.252946753.972179590.1526550450-1850471649.1526550450#/
To test, populate your nexus repos as explained here http://www.javamonamour.org/2017/09/nexus-and-maven-setup.html
If you get a 403 Unauthorized, try assigning to the user "Anonymous" the role "nx2-repository-any-full" (=nx-repository-view-*-*-*)
in the request.log you see this
127.0.0.1 - - [18/Dec/2018:17:57:01 +0100] "GET /service/rest/v1/assets?repository=central HTTP/1.1" 200 - 4698 328 "Swagger-Codegen/1.0.0/java"
Soem sample code is here
https://hub.docker.com/r/swaggerapi/swagger-editor/
docker run -d --rm --name swaggereditor -p 9080:8080 swaggerapi/swagger-editor
http://localhost:9080/
then http://localhost:8181/service/rest/swagger.json (8181 is the Nexus port) , download the file, feed it into the swagger-editor (file , import file). Import URL will not work, apparently you must be authenticated in Nexus to be able to download it.
then generate client /java , this will produce a java-client-generated.zip file with your Java client API. You extract this file, run "mvn install", then open the README.md to understand how it works...
I create a Java project, add this maven dependency
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-java-client</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
then try this code:
package nexusclient;
import io.swagger.client.*;
import io.swagger.client.auth.*;
import io.swagger.client.model.*;
import io.swagger.client.api.AssetsApi;
public class NexucClientTest {
public static void main(String[] args) throws Exception {
AssetsApi apiInstance = new AssetsApi();
apiInstance.getApiClient().setBasePath("http://localhost:8181/service/rest");
String continuationToken = null;
PageAssetXO assets = apiInstance.getAssets("maven-central", continuationToken );
for (AssetXO asset : assets.getItems()) {
System.out.println(asset.toString());
}
}
}
actually you don't even need to run swagger-editor locally, you can use the online version https://editor.swagger.io//?_ga=2.252946753.972179590.1526550450-1850471649.1526550450#/
To test, populate your nexus repos as explained here http://www.javamonamour.org/2017/09/nexus-and-maven-setup.html
If you get a 403 Unauthorized, try assigning to the user "Anonymous" the role "nx2-repository-any-full" (=nx-repository-view-*-*-*)
in the request.log you see this
127.0.0.1 - - [18/Dec/2018:17:57:01 +0100] "GET /service/rest/v1/assets?repository=central HTTP/1.1" 200 - 4698 328 "Swagger-Codegen/1.0.0/java"
Soem sample code is here
Thursday, December 14, 2017
Openshift REST Client API written in Java
https://github.com/openshift/openshift-restclient-java/
immensely more usable than the CLI...
I ask myself who wants to learn by heart the hyper-complicated Openshift command line interface, when you can easily wrap all that crap in a nice fluent Java API....
Life is short, I am too busy, no time to learn all the freaking CLIs of the planet... please give me simple and powerful programming tools... I don't want to type any commands...
To get started, create a Maven Java Project, add this in pom.xml:
then run this:
immensely more usable than the CLI...
I ask myself who wants to learn by heart the hyper-complicated Openshift command line interface, when you can easily wrap all that crap in a nice fluent Java API....
Life is short, I am too busy, no time to learn all the freaking CLIs of the planet... please give me simple and powerful programming tools... I don't want to type any commands...
To get started, create a Maven Java Project, add this in pom.xml:
<dependencies>
<dependency>
<groupId>com.openshift</groupId>
<artifactId>openshift-restclient-java</artifactId>
<version>5.9.3.Final</version>
</dependency>
</dependencies>
then run this:
package org.pierre.ocpclient;
import com.openshift.restclient.ClientBuilder;
import com.openshift.restclient.IClient;
import com.openshift.restclient.ResourceKind;
import com.openshift.restclient.model.IProject;
import com.openshift.restclient.model.IResource;
public class CreateProject {
public static void main(String[] args) {
IClient client = new ClientBuilder("https://localhost:8443")
.withUserName("admin")
.withPassword("admin")
.build();
IResource request = client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, "myfirstproject");
IProject project = (IProject)client.create(request);
}
}
Wednesday, October 11, 2017
JAX-RS tutorials and documentation
Here a reasoned discussion about CacheControl and ETag https://abhirockzz.wordpress.com/2016/03/27/efficient-jax-rs-conditional-gets-puts/
Here https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html all the HTTP 1.1 headers specifications
http://www.logicbig.com/tutorials/java-ee-tutorial/jax-rs/request-context/
deploy it in a PVRestRS project and hit it with http://localhost:8080/PVRestRS/users
it's an excellent simple example showing the use of:
http://docs.oracle.com/javaee/7/api/javax/ws/rs/core/Request.html
specifically, here http://docs.oracle.com/javaee/7/api/javax/ws/rs/core/Request.html#evaluatePreconditions-javax.ws.rs.core.EntityTag- some explanations on the use of an ETag.
http://docs.oracle.com/javaee/7/api/javax/ws/rs/core/CacheControl.html
Some explanations on "what ETag is for?" here http://www.logicbig.com/quick-info/web/etag-header/
I open Chrome, STRL-SHIFT.I (developer tools) , Networks, select "users", right-click, console / Headers/all (it took me a lot of clicking to find it...) and I see this:
If I request http://localhost:8080/PVRestRS/users/pippo , I see also ETag:"version1" and (the second time only) If-None-Match:"version1"
"The If-None-Match request-header field is used with a method to make it conditional. A client that has one or more entities previously obtained from the resource can verify that none of those entities is current by including a list of their associated entity tags in the If-None-Match header field. The purpose of this feature is to allow efficient updates of cached information with a minimum amount of transaction overhead. It is also used to prevent a method (e.g. PUT) from inadvertently modifying an existing resource when the client believes that the resource does not exist. "
"1. If the response includes the "s-maxage" cache-control
directive, the cache MAY use that response in replying to a
subsequent request. But (if the specified maximum age has
passed) a proxy cache MUST first revalidate it with the origin
server, using the request-headers from the new request to allow
the origin server to authenticate the new request. (This is the
defined behavior for s-maxage.) If the response includes "s-
maxage=0", the proxy MUST always revalidate it before re-using
it."
"s-maxage
If a response includes an s-maxage directive, then for a shared cache (but not for a private cache), the maximum age specified by this directive overrides the maximum age specified by either the max-age directive or the Expires header. The s-maxage directive also implies the semantics of the proxy-revalidate directive (see section 14.9.4), i.e., that the shared cache must not use the entry after it becomes stale to respond to a subsequent request without first revalidating it with the origin server. The s- maxage directive is always ignored by a private cache. "
This book is on my to-read list https://leanpub.com/rest-assured-with-jaxrs
The excellent article about JAX-RS on Java Magazine jan/feb 2016 by Abishek is available here http://www.javamagazine.mozaicreader.com/JanFeb2016#&pageSet=32&page=0
Here https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html all the HTTP 1.1 headers specifications
http://www.logicbig.com/tutorials/java-ee-tutorial/jax-rs/request-context/
deploy it in a PVRestRS project and hit it with http://localhost:8080/PVRestRS/users
it's an excellent simple example showing the use of:
http://docs.oracle.com/javaee/7/api/javax/ws/rs/core/Request.html
specifically, here http://docs.oracle.com/javaee/7/api/javax/ws/rs/core/Request.html#evaluatePreconditions-javax.ws.rs.core.EntityTag- some explanations on the use of an ETag.
http://docs.oracle.com/javaee/7/api/javax/ws/rs/core/CacheControl.html
Some explanations on "what ETag is for?" here http://www.logicbig.com/quick-info/web/etag-header/
I open Chrome, STRL-SHIFT.I (developer tools) , Networks, select "users", right-click, console / Headers/all (it took me a lot of clicking to find it...) and I see this:
Request URL:http://localhost:8080/PVRestRS/users Request Method:GET Status Code:304 Not Modified Remote Address:127.0.0.1:8080 Referrer Policy:no-referrer-when-downgrade Response Headers view source Date:Wed, 11 Oct 2017 00:31:57 GMT Server:WildFly/11 X-Powered-By:Undertow/1 Request Headers view source Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding:gzip, deflate, br Accept-Language:en-US,en;q=0.8 Cache-Control:max-age=0 Connection:keep-alive Cookie:Idea-f3d396f=f1a96b31-981d-4574-a116-314fe061816e; __utma=111872281.364080227.1506531800.1506531800.1506531800.1; __utmc=111872281; __utmz=111872281.1506531800.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none) Host:localhost:8080 If-Modified-Since:Tue, 19 Sep 2017 22:00:00 GMT Upgrade-Insecure-Requests:1 User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
If I request http://localhost:8080/PVRestRS/users/pippo , I see also ETag:"version1" and (the second time only) If-None-Match:"version1"
"The If-None-Match request-header field is used with a method to make it conditional. A client that has one or more entities previously obtained from the resource can verify that none of those entities is current by including a list of their associated entity tags in the If-None-Match header field. The purpose of this feature is to allow efficient updates of cached information with a minimum amount of transaction overhead. It is also used to prevent a method (e.g. PUT) from inadvertently modifying an existing resource when the client believes that the resource does not exist. "
"1. If the response includes the "s-maxage" cache-control
directive, the cache MAY use that response in replying to a
subsequent request. But (if the specified maximum age has
passed) a proxy cache MUST first revalidate it with the origin
server, using the request-headers from the new request to allow
the origin server to authenticate the new request. (This is the
defined behavior for s-maxage.) If the response includes "s-
maxage=0", the proxy MUST always revalidate it before re-using
it."
"s-maxage
If a response includes an s-maxage directive, then for a shared cache (but not for a private cache), the maximum age specified by this directive overrides the maximum age specified by either the max-age directive or the Expires header. The s-maxage directive also implies the semantics of the proxy-revalidate directive (see section 14.9.4), i.e., that the shared cache must not use the entry after it becomes stale to respond to a subsequent request without first revalidating it with the origin server. The s- maxage directive is always ignored by a private cache. "
This book is on my to-read list https://leanpub.com/rest-assured-with-jaxrs
The excellent article about JAX-RS on Java Magazine jan/feb 2016 by Abishek is available here http://www.javamagazine.mozaicreader.com/JanFeb2016#&pageSet=32&page=0
Friday, August 11, 2017
Spring boot Rest controller with Embedded Tomcat
really simple, and the code is available here
https://github.com/vernetto/restapi
I just realize that I had already done this exercise here http://www.javamonamour.org/2017/03/spring-boot-starter-web-app.html , even better explained!
Labels:
REST,
Spring,
springboot
Sunday, May 3, 2015
Stateful REST : it can be done
Even in the SOA Philosophy, mostly based on SOAP over HTTP, a Service can be Stateful:
you just need to enable javax.xml.ws.BindingProvider.SESSION_MAINTAIN_PROPERTY on the BindingProvider
in order to maintain state, you don't necessarily need to implement a Service as a Stateful EJB!
See http://docs.oracle.com/cd/E19226-01/820-7627/6nisfjmk8/index.html :
Stateful interactions through hyperlinks. Every interaction with a resource is stateless; that is, request messages are self-contained. Stateful interactions are based on the concept of explicit state transfer. Several techniques exist to exchange state, such as URI rewriting, cookies, and hidden form fields. State can be embedded in response messages to point to valid future states of the interaction. This topic is discussed somewhat in Using Entity Providers to Map HTTP Response and Request Entity Bodies, is discussed somewhat in the section Building URIs in the JAX-RS Overview document, and may be discussed in more detail in a forthcoming advanced version of this tutorial.
One can achieve this in JAX-RS 2.0 by using the javax.ws.rs.client.ClientResponseFilter for saving the cookie(s) from the HttpRequest and the javax.ws.rs.client.ClientRequestFilter for adding them again in the (subsequent) requests.
If you use WebLogic on the server side, remember that Jersey 2.5.1 is the supported "JAX-RS 2.0 Reference Implementation"
in order to maintain state, you don't necessarily need to implement a Service as a Stateful EJB!
See http://docs.oracle.com/cd/E19226-01/820-7627/6nisfjmk8/index.html :
Stateful interactions through hyperlinks. Every interaction with a resource is stateless; that is, request messages are self-contained. Stateful interactions are based on the concept of explicit state transfer. Several techniques exist to exchange state, such as URI rewriting, cookies, and hidden form fields. State can be embedded in response messages to point to valid future states of the interaction. This topic is discussed somewhat in Using Entity Providers to Map HTTP Response and Request Entity Bodies, is discussed somewhat in the section Building URIs in the JAX-RS Overview document, and may be discussed in more detail in a forthcoming advanced version of this tutorial.
One can achieve this in JAX-RS 2.0 by using the javax.ws.rs.client.ClientResponseFilter for saving the cookie(s) from the HttpRequest and the javax.ws.rs.client.ClientRequestFilter for adding them again in the (subsequent) requests.
If you use WebLogic on the server side, remember that Jersey 2.5.1 is the supported "JAX-RS 2.0 Reference Implementation"
Tuesday, August 2, 2011
Firefox REST plugin made in China
https://addons.mozilla.org/en-US/firefox/addon/restclient/
https://github.com/chao/RESTClient
just install it, restart Firefox, then enter
chrome://restclient/content/restclient.xul
(I know, we are using Firefox, not chrome...)
and it's pretty straightforward to use.... EXCELLENT STUFF!
You can do simple POST. I can't think of anything simpler to use.
Remember that for SOAP request you must post the entire SOAP Envelope:
http://www.w3schools.com/soap/soap_example.asp
Since lately the above plugin is failing, I am not using this one, the Poster plugin
https://github.com/chao/RESTClient
just install it, restart Firefox, then enter
chrome://restclient/content/restclient.xul
(I know, we are using Firefox, not chrome...)
and it's pretty straightforward to use.... EXCELLENT STUFF!
You can do simple POST. I can't think of anything simpler to use.
Remember that for SOAP request you must post the entire SOAP Envelope:
http://www.w3schools.com/soap/soap_example.asp
Since lately the above plugin is failing, I am not using this one, the Poster plugin
Tuesday, July 5, 2011
Putting OSB to REST
this is my URI that I "GET" in my browser:
http://acme.com:7009/GUTools/Caches/LoadCache/validityDate=2001-07-05/id=90
being GUTools/Caches/LoadCache the URI of my "REST" AnyXML Proxy Service
assign $inbound/ctx:transport/ctx:request/http:relative-URI/text() to relativeURI
(relativeURI = validityDate=2001-07-05/id=90)
assign
let $mySequence := fn:tokenize($relativeURI, "/")
return
<parameters>
{for $item in $mySequence
return <parameter><name>{fn:substring-before($item, '=')}</name><value>{fn:substring-after($item, '=')}</value></parameter>
}
</parameters>
to parameters
this is $parameters :
<parameters>
<parameter>
<name>validityDate</name>
<value>2001-07-05</value>
</parameter>
<parameter>
<name>id</name>
<value>90</value>
</parameter>
</parameters>
For Each [ parameter ] in [ ./parameter ] of [ parameters ]
Indexed by [ parameterIndex ] with total count in [ parameterCount ]
log $parameter/name/text()
log $parameter/value/text()
Great! I was able to get all the parameters from the URI. At this point I can process them using simple XPath to thet their value:
$parameters/parameter[name='validityDate']/value/text()
this returns 2001-07-05
I can invoke from a CRON job this command:
lwp-request -m GET http://acme.com:7009//GUTools/Caches/LoadCache/validityDate=2001-07-02
to trigger the Proxy Service with a simple GET (no more bloody SOAP)
http://acme.com:7009/GUTools/Caches/LoadCache/validityDate=2001-07-05/id=90
being GUTools/Caches/LoadCache the URI of my "REST" AnyXML Proxy Service
assign $inbound/ctx:transport/ctx:request/http:relative-URI/text() to relativeURI
(relativeURI = validityDate=2001-07-05/id=90)
assign
let $mySequence := fn:tokenize($relativeURI, "/")
return
<parameters>
{for $item in $mySequence
return <parameter><name>{fn:substring-before($item, '=')}</name><value>{fn:substring-after($item, '=')}</value></parameter>
}
</parameters>
to parameters
this is $parameters :
<parameters>
<parameter>
<name>validityDate</name>
<value>2001-07-05</value>
</parameter>
<parameter>
<name>id</name>
<value>90</value>
</parameter>
</parameters>
For Each [ parameter ] in [ ./parameter ] of [ parameters ]
Indexed by [ parameterIndex ] with total count in [ parameterCount ]
log $parameter/name/text()
log $parameter/value/text()
Great! I was able to get all the parameters from the URI. At this point I can process them using simple XPath to thet their value:
$parameters/parameter[name='validityDate']/value/text()
this returns 2001-07-05
I can invoke from a CRON job this command:
lwp-request -m GET http://acme.com:7009//GUTools/Caches/LoadCache/validityDate=2001-07-02
to trigger the Proxy Service with a simple GET (no more bloody SOAP)
Monday, April 4, 2011
ROA: Resource Oriented Architecture
I am reading RESTful Web Services
I am not in love with the book as I find it really verbose, it doesn't really catch my attention.
Anyway at page 216 they refer to ROA. The wikipedia article is very clarifying, the guidelines express the essence of the REST approach.
- stick all what you can in a URI
- documents should contain links (URIs) to related documents
- everything should be stateless
They talk a lot about "REPRESENTATION".
The table "RESTful Web Service HTTP methods" clearly shows what GET PUT POST and DELETE are supposed to do.
Here http://www.infoq.com/articles/rest-introduction
a good introduction on REST.
As usual, I keep thinking that all these technologies are simply CRAP, and that CORBA 20 years ago was doing much better than this. If you find a technology good only because anybody can write a URL in a browser and get a result, and you want to base on that your enterprise architecture, then good luck.
I am not in love with the book as I find it really verbose, it doesn't really catch my attention.
Anyway at page 216 they refer to ROA. The wikipedia article is very clarifying, the guidelines express the essence of the REST approach.
- stick all what you can in a URI
- documents should contain links (URIs) to related documents
- everything should be stateless
They talk a lot about "REPRESENTATION".
The table "RESTful Web Service HTTP methods" clearly shows what GET PUT POST and DELETE are supposed to do.
Here http://www.infoq.com/articles/rest-introduction
a good introduction on REST.
As usual, I keep thinking that all these technologies are simply CRAP, and that CORBA 20 years ago was doing much better than this. If you find a technology good only because anybody can write a URL in a browser and get a result, and you want to base on that your enterprise architecture, then good luck.
Sunday, March 20, 2011
JAX-RS, RestEasy, Restful WS
A great tutorial from Luciano:
http://blog.aestasit.com/develop-restful-services-like-a-ninja-part-1/
http://blog.aestasit.com/develop-restful-services-like-a-ninja-%E2%80%93-part-2/
JAX-RS = Java API for RESTful Web Services
here http://www.ibm.com/developerworks/webservices/library/wa-jaxrs/index.html general presentation of JAX-RS
The Resteasy doc is here (don't expect complete examples, only code snippets are provided)
http://docs.jboss.org/resteasy/docs/1.0.1.GA/userguide/html/
the annotations are in javax.ws.rs package
Path(value="/contacts")
@GET
@Consumes
@Produces
@Provider
@QueryParam
@HeaderParam
@MatrixParam
@CookieParam
(see the rest on the javadoc...)
Here a decent example (better than the official doc anyway)
http://blog.aestasit.com/develop-restful-services-like-a-ninja-part-1/
http://blog.aestasit.com/develop-restful-services-like-a-ninja-%E2%80%93-part-2/
JAX-RS = Java API for RESTful Web Services
here http://www.ibm.com/developerworks/webservices/library/wa-jaxrs/index.html general presentation of JAX-RS
The Resteasy doc is here (don't expect complete examples, only code snippets are provided)
http://docs.jboss.org/resteasy/docs/1.0.1.GA/userguide/html/
the annotations are in javax.ws.rs package
Path(value="/contacts")
@GET
@Consumes
@Produces
@Provider
@QueryParam
@HeaderParam
@MatrixParam
@CookieParam
(see the rest on the javadoc...)
Here a decent example (better than the official doc anyway)
Labels:
REST,
Resteasy,
webservices
Friday, April 23, 2010
SOAP or REST? Which is the BEST?
An interesting article examining REST features
https://www.ibm.com/developerworks/webservices/library/ws-restful/
and a good introduction to REST
http://www.ibm.com/developerworks/webservices/library/wa-jaxrs/index.html
more later....
https://www.ibm.com/developerworks/webservices/library/ws-restful/
and a good introduction to REST
http://www.ibm.com/developerworks/webservices/library/wa-jaxrs/index.html
more later....
Labels:
REST
Subscribe to:
Posts (Atom)
