Hot questions for Using Azure in jax rs

Question:

Hi

I need to develop simple web service on java. I'm new to java tech and based on several articles decided to use JAX-RS (Jersey) with embedded http server (Grizzly2), because it looks suitable for building REST services and deployment seems to be trivial.

In my dev environment all works perfect (using IntllijIdea).

But when I try to deploy on test server every request returns "500 Internal Error" (even /application.wadl)

Here more info:

Simple resource

@Path("resource")
public class SpeechRecognition {
    @GET
    public Response test() {
        Logger.getGlobal().log(Level.INFO, "resource test");
        return Response.ok("success", MediaType.TEXT_PLAIN).build();
    }
}

Simple resource config

public class SimpleApiServer extends ResourceConfig {
    public SimpleApiServer() {
        register(MultiPartFeature.class);
        register(LoggingFilter.class);
        register(JacksonFeature.class);

        property(ServerProperties.TRACING, "ALL");
        property(ServerProperties.TRACING_THRESHOLD, "VERBOSE");

        packages("com.mydomain");
    }
}

Simple app start

public static void main(String[] args) throws IOException {
    final HttpServer server = GrizzlyHttpServerFactory.createHttpServer("http://0.0.0.0:80", new SimpleApiServer());

    System.out.println(String.format("Jersey app started with WADL available at "
            + "%sapplication.wadl\nHit enter to stop it...", serverUri.toString()));
    System.in.read();
    server.stop();
}

Exception mapping

@Provider
public class AppExceptionMapper implements ExceptionMapper<Throwable> {
    @Override
    public Response toResponse(Throwable ex) {
        Logger.getGlobal().log(Level.WARNING, "exception response");

        ex.printStackTrace();

        return Response.status(500).entity(Exceptions.getStackTraceAsString(ex)).type("text/plain")
            .build();
    }
}
What is happening

For every request I see in console

- that grizzly accepts it (prints all information about headers etc.) - and that resource code is executed ("resource test" is printed)

And nothing more.

In postman I receive "500 Request Failed" with no trace from Jersey in headers (though I specified property(ServerProperties.TRACING, "ALL");)

No information printed in server console about any exceptions.

I have an idea, that something bad happens when jersey tries to pass response to grizzly.

Does anyone has any thoughts about where should I look to troubleshoot this problem? I really stuck with it.

And I really don't want to rewrite everything (not this simple ill example, but lots more) to traditional java servlet-oriented code ('cause it's another piece of tech to learn about)

P.S.

Test server - is the docker container on azure linux VM. Requests are proxied by nginx to exposed docker port. Got web-site on Rails using the same scheme, which works fine.

When grizzly prints info about request it prints incorrect hostname. I.e. actual host name is test.api.mydomain.com and grizzly writes GET http://test.api:80/resource


Answer:

Ok. It was the Jersey version mismatch in dev and test environments.

Remote debugging (with IntellijIdea) showed, that in process of forming response

Exception: AbstractMethodError: javax.ws.rs.core.Response.getStatusInfo()Ljavax/ws/rs/core/Response$StatusType;

is thrown, wich led me to this post. After fixing the dependencies all works fine.

Question:

Have an call to an API

And i create as of now a POJO to map the Json response

@JsonInclude(JsonInclude.Include.NON_NULL)
JsonIgnoreProperties(ignoreUnknown = true)
public  class ResponseBricks<T>{

public ResponseBricks<T>(@JsonProperty("location") Location location,
        @JsonProperty("properties") Properties properties, 
         @JsonProperty("error") AzureError error) {

    this.location = location;
    this.properties = properties;
    this.error = error;
}

public Location getLocation() {
    return location;
}

public void setLocation(Location  location) {
    this.location = location;
}

public T getProperties() {
    return properties;
}

public void setProperties(T properties) {
    this.properties = properties;
}

public AzureError getError() {
    return error;
}

public void setErrorAzureError error) {
    this.error = error;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}



public Response getResponse() {
    return response;
}

public void setResponse(Response response) {
    this.response = response;
}



private Location location;
private T properties;
private String id;
private String name;
private AzureError error;
private Response response;

}

Now i need Headers from the response and thus included

private Response response;

However the Response isnt mapped to exactly the response from the azure call and the Response comes as null. I can get headers if i keep the response as Response than my custom POJO.However is there any way to use the custom pojo with the response as a variable inside it?


Answer:

So tried this out.The only way is to use Response.Custom Pojo for response wont give the headers. Response has many methods to not only get the headers but also the body.

Question:

I'm using Azure for the first time and wanting to make a very simple RESTful API, but trying to follow the example using Swagger.io feels like a lot of work for what I want to achieve. Is there a way to just write Java code for JAX-RX without going through the Swagger.io generator process?


Answer:

Service description stating that you can bring your API as is:

Bring your existing API as-is - You don't have to change any of the code in your existing APIs to take advantage of API Apps -- just deploy your code to an API app. Your API can use any language or framework supported by App Service, including ASP.NET and C#, Java, PHP, Node.js, and Python.

Swagger support facilitate ease of consumption, since you able to auto generate client sdks in various languages based on swagger spec. Nothing prevent you not having swagger and still use service.