Showing posts with label REST. Show all posts
Showing posts with label REST. Show all posts

Thursday, October 17, 2019

Mocking rest services with Mockito and MockRestServiceServer in Spring

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

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:

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:


  <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:


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!

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"



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

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)

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.

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)

Friday, April 23, 2010