Free API management choices for distributed Restful Web Service

If you are looking for cheaper solution for the web service API management, this list might can help to give some hints.

As far you have distributed or micro web service, you will involve in the how to put all the shared feature into one place for each WS, such security, authentication and auditing. Here I list some free or low cost solution for the API lifecycle management framework and products.  When you use amazon AWS or Microsoft Azure cloud, they already supply similar service. For the open source way for small companies who do not want the bundle to a cloud provider, a self-controlled API management solution will give you more flexibility and independence for future migration.

Basically they have either on-premise or as-a-service model to go. With on-premise, means be deployed in either a physical or virtual data center. And as-a-service cloud version will let you integrate with cloud based API management and you can manage it from anywhere.

  1. WSO2 on-premises – WSO2 API Manager is a 100% open source enterprise-class solution that supports API publishing, lifecycle management, application development, access control, rate limiting and analytics in one cleanly integrated system. Running on java, most database and Apache ActiveMQ. Apache 2.0 license.
  2. Kong Community Edition  – open source with a lot customers base. Kong’s server, based on the widely adopted NGINX HTTP server, which is a reverse proxy processing your clients’ requests to your upstream services. Kong’s datastore, in which the configuration is stored to allow you to horizontally scale Kong nodes. Apache Cassandra and PostgreSQL be used.
  1. Tyk On-Premises – not open source, Single gateway Tyk Pro licences are FREE forever. Simply install your preferred package FREE for a single gateway, affordable at scale. No need to maintain forks, third party dependencies, or purchase SaaS add-ons. Just download the FREE Open Source API Gateway, get a FREE Tyk dashboard licence, use Tyk commercially… for FREE. No hidden costs, no restrictions on number of users, APIs or analytics retention. The entire platform, under your control, on your own servers. Priced according to the number of gateways in your environment, not the size of your team. Full access to the entire platform, no features held-back, starts from FREE!
  2. Apiman (not add new feature any more after redhat get the 3scale) – simple to use, install on wildfly ( Elasticsearch) or tomcat 8
  3. Api Umbleralla – looks like easy to use and install – require MongoDB and Elasticsearch
  4. gravitee.io – a very new API manager, has the gateway, manange API and portal three parts,   required MongoDB to store mandatory data and ElasticSearch (Apache License V2)
  5. Apigee – acquired by google, not free.
  6. Apiary free edition – with oracle, API Blueprint is simple and accessible to everybody involved in the API lifecycle. Its syntax is concise yet expressive. API Blueprint is completely open sourced under the MIT license. Its future is transparent and open. API Blueprint doesn’t need a closed work group. Instead it uses the RFC process similar to Rust language  or Django Enhancement Proposal RFC processes.
Advertisements

Solve the Json/Java polymorphism request by Jackson

By W.ZH

When convert between json and jave objects, you could often face the polymorphism issue.
Such as a json of Content could be:

{
  "type":"valuea",
  "value": {
    "valueaName": "corn",
    "bar":  "sweet"
  }
}

and also could be

{
  "type":"valueb",
  "value": {
    "valuebName": "toy",
    "color":  "yellow",
    "price":  "20"     
  }
}

Value objects in fact is depends on the type data to change. This requires that depending on the type data and create different value’s object at Java side, How to do?

Here is the solution at the Jackson code by using the     @JsonTypeInfo

let us define a abstract class Value and another two class ValueA and ValueB to Extends it.

public abstract class Value {
}

and ValueA to inherit Value

@JsonInclude(JsonInclude.Include.NON_NULL)
public class ValueA extends Value {

    @JsonProperty("valueaName")
    private String valueaName = "";

    @JsonProperty("bar")
    private String bar;
....................................
....................................
}

and ValueB Class to inherit Value.

@JsonInclude(JsonInclude.Include.NON_NULL)
public class ValueB extends Value {

    @JsonProperty("valuebName")
    private String valuebName = "";

    @JsonProperty("color")
    private String color;

    @JsonProperty("price")
    private String price;
....................................
....................................
}

 

Then after that we can create a Class for Content to let “type” files  work as a EXTERNAL_PROPERTY to control the Value object in side the Content:

@JsonInclude(JsonInclude.Include.NON_NULL)
public class Content {

    @JsonProperty("type")
    private String type;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonProperty("value")
    private Value value = null;
    
    public Content (){
    }
    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
    @JsonSubTypes({ @Type(value = ValueA.class, name = "valuea"),@Type(value = ValueB.class, name = "valueb")})
    public void setValue(Value value) {
        this.value = value;
    }

    public Value getValue() {
        return value;
    }

}

In this way. @JsonTypeInfo in fact define how to rely on “type” to dynamically  serialize and de-serialize the json/java object.

To make this properly work, your Jackson version must higher than the 2.5 version. As I have faced the duplicated fields bug in the 2.5  version Jackson , here is sample dependency:

 

        <!-- Jackson -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.8.0</version>
        </dependency>

 

 

Spring MVC + Security Note (4) – Migrate from Spring Security 3.X to 4.X

By W.ZH

Refer to this link

http://docs.spring.io/spring-security/site/migrate/current/3-to-4/html5/migrate-3-to-4-xml.html

Here are some notes that common change in page or configuration files:

  1. default URL for login and logout form action are changed:
    /j_spring_security_logout     to /logout
    /j_spring_security_check     to /login
    So we need to change our JSP content for these two.
  2. Default csrf is enabled… so if you want to be disabled, just add this
    <csrf disabled=”true”/> in the <http />tag
    If you want enable, you do not need to do sth.
  3. <access-denied-handler error-page=”/page/403″ />  put inside the <http />
    not like old on as the attribute <http *** />
  4. If you have more than one roles, you can not use the
    access=”ROLE_USER,ROLE_ADMIN”  any more, you have to change to<http auto-config=”true” use-expressions=”true” >
    …..
    <intercept-url  ……. access=”hasAnyRole(‘ROLE_USER’,’ROLE_ADMIN’)” …..you maybe have others need changes, need to refer to reference page

How to consume json object from Spring MVC controller input directly

By WZH

This is small note about the json input directly to Spring MVC controller side, jackson will auto convert it to Java object you want:

  1. Make sure has this jar added

 <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.5.0</version>
  </dependency>

2.  Controller side

@RequestMapping(value = urlPatternController, method = RequestMethod.POST)
public @ResponseBody Person createPerson(@RequestBody Person jsonString) {
   Person person=personService.savedata(jsonString);
   return person;
}

@RequestBody – Covert Json object to java
@ResponseBody– convert Java object to json

3. JS client side :

 

$.ajax("<%=path%>/web/urlPatternController", {
                           type:'POST',
                           dataType: 'json',
                           data: person
                    })

 

Link can be refered

 

 

A special case for de-serialize Polymorphic class by Jackson

A special case for de-serialize Polymorphic class by Jackson

 

By WZh   Apr 2015

A very good article about the de-serialize the data in Jackson from Json to JAVA is already at this article

  1. http://programmerbruce.blogspot.co.uk/2011/05/deserialize-json-with-jackson-into.html

But a special case we have met is not in that article. Input json sample:

//   {

“type”:”dog”,

//     “animal”:

//           {“name”:”Spike”,

// “breed”:”mutt”,

//            “leash_color”:”red”}

}

or

//   {

“type”:”cat”,

//     “animal”:

//           {“name”:”Fluffy”,

//           “favorite_toy”:”spider ring”}

//   }

This means type is not inside the abstract class itself, type is controlled by parent class fields and also we want to use getter and setter in the parent class for “type” in other java code, to type must be cleared defined at Zoo class as Java field.

Here is the solution after research!

class Zoo

{

private String type;

private Animal animal;  

@JsonTypeId

public String getType() {

return type;

}

public void setType(String type) {

this.type = type;

}

@JsonTypeInfo(

use = JsonTypeInfo.Id.NAME,

include = JsonTypeInfo.As.EXTERNAL_PROPERTY,

property = “type”)

@JsonSubTypes({     @Type(value = Cat.class, name = “cat”),  

    @Type(value = Dog.class, name = “dog”) })  

public void setAnimal ( Animal value) {

this.animal = value;

}

public Animal getAnimal () {

return animal;

}

}

abstract class Animal

{

}

class Dog extends Animal

{

  public String name;

  public String breed;

  public String leashColor;

}

class Cat extends Animal

{

  public String name;

  public String favoriteToy;

}

the most important thing in the code is :

  1. @JsonTypeId set to getter for “type” and let the jackson do not create duplicate “type” in the json
  2. @JsonTypeInfo defined with JsonTypeInfo.As.EXTERNAL_PROPERTY to let the Animal class can be controlled by the external property “type” to do the Polymorphic
  3. @JsonTypeInfo is put to the setter of the abstract class to contorl the Polymorphic

workarea SOAP header cause the SOAPFaultException

By W.ZH Dec 2014

Issue:

When I was working on a project about the WS, my client jar always get this error:

Get Eligibility failed. Severity level is 5. Msg=SOAPFaultException – FaultCode [{http://schemas.xmlsoap.org/soap/envelope/}Server] FaultString [15
] FaultActor [null] Detail [<detail><bea_fault:stacktrace xmlns:bea_fault=”http://www.bea.com/servers/wls70/webservice/fault/1.0.0″>java.lang.ArrayIndexOutOfBoundsException: 15
at com.sun.beans.ObjectHandler.dequeueResult(ObjectHandler.java:139)
at java.beans.XMLDecoder.readObject(XMLDecoder.java:201)
at weblogic.wsee.workarea.WorkContextXmlInputAdapter.readUTF(WorkContextXmlInputAdapter.java:111)
at weblogic.workarea.spi.WorkContextEntryImpl.readEntry(WorkContextEntryImpl.java:92)
at weblogic.workarea.WorkContextLocalMap.receiveResponse(WorkContextLocalMap.java:226)
at weblogic.workarea.WorkContextMapImpl.receiveResponse(WorkContextMapImpl.java:182)
at weblogic.wsee.workarea.WorkAreaClientHandler.handleResponse(WorkAreaClientHandler.java:49)
at weblogic.wsee.handler.HandlerIterator.handleResponse(HandlerIterator.java:287)
at weblogic.wsee.handler.HandlerIterator.handleResponse(HandlerIterator.java:271)
at weblogic.wsee.ws.dispatch.client.ClientDispatcher.handleResponse(ClientDispatcher.java:213)
at weblogic.wsee.ws.dispatch.client.ClientDispatcher.dispatch(ClientDispatcher.java:150)
at weblogic.wsee.ws.WsStub.invoke(WsStub.java:87)
at weblogic.wsee.jaxrpc.StubImpl._invoke(StubImpl.java:341)

When I look at the SOAP XML. found this in the header:

<work:WorkContext xmlns:wsu=”http://schemas.xmlsoap.org/ws/2002/07/utility&#8221;

                      xmlns:work=”http://bea.com/2004/06/soap/workarea/”&gt;

     <java class=”java.beans.XMLDecoder”>

      <string>**************</string>

      <int>214</int>

      <string>weblogic.workarea.StringWorkContext</string>

      <string>1.4.1.18</string>

      <string>oracle.dms.context.internal.wls.WLSContextFamily</string>

      <int>335</int>

      <string>weblogic.workarea.SerializableWorkContext</string>

      <int>356</int>

      <array class=”byte” length=”356″>

       <void index=”0″>

       ……………………………………..

      <boolean>false</boolean>

      <string/>

     </java>

    </work:WorkContext>

 

Reason:

As my jar client is legacy code, so it in fact can not read this extra header properly, so it will get error.

Solution:

Use this flag at your setDomainEnv.sh to change java flag for this extra header:

-Dweblogic.wsee.workarea.skipWorkAreaHeader=true

after restart server. it will be fine

Some cool tips of Jackson

Some cool tips of Jackson

from Ted M. Young

  • To make the JSON easier to read, you can tell ObjectMapper to use a “pretty printer”,

ObjectMapper objectMapper = new ObjectMapper();

Book jacksonCookbook = new JacksonCookbook();

String json = objectMapper

.writerWithDefaultPrettyPrinter()

.writeValueAsString(jacksonCookbook);

System.out.println(json);

 

If you always want to pretty-print the output, you can configure the ObjectMapper instance directly using the SerializationFeature class:


ObjectMapper objectMapper = new ObjectMapper();

objectMapper.enable(SerializationFeature.INDENT_OUTPUT);

 

The enable method here turns on the INDENT_OUTPUT feature, which tells Jackson to use the DefaultPrettyPrinter when serializing your objects. The code

objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true)

  • If you have property values in your data that can be null, but don’t want them serialized when they are, you can do the following to make the setting global for all uses of this objectMapper reference:

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

If you only want to do this on a per-class basis, you can add the @JsonInclude annotation above the class or interface definition:


@JsonSerialize(include = Inclusion.NON_NULL)
public class HasNullValues {private String optionalSecondAddress; // nullable field

 

  • Sometimes you’ll want the properties that in your JSON output to be in a specific order, perhaps because you have tests or clients that rely on the ordering (I’d try to avoid that, but sometimes it’snot under your control), or you want it to be easier to find a certain property when looking at the JSON during debugging.

To order on a per-class basis, use the @JsonPropertyOrder annotation:


@JsonPropertyOrder({“id”, “symbol”})
public class Currency {public String symbol;

public String shortName;

public String longName;

public long id;

}

This will ensure that the id property will be first, followed by the symbol property, with the rest in an undetermined order.

If you wanted them simply in alphabetic order, you would use the alphabetic parameter in the annotation:

@JsonPropertyOrder(alphabetic = true)

If you always want the properties sorted alphabetically, configure the ObjectMapper instance directly:

objectMapper.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);

Note that the above settings won’t affect the order of the contents of any maps that you have (e.g., a HashMap). If you want the output of maps to be ordered by their keys, you’ll need to turn on the ORDER_MAP_ENTRIES_BY_KEYS feature:

objectMapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS);