Java server side API

Java™ adapters can use the IBM MobileFirst™ Platform Server Java API to perform server-related operations such as: calling other adapters, submitting push notifications, logging on to the server log, getting values of configuration properties, reporting activities to analytics, and getting the identity of the request issuer.

To get the server API interface use the following code:
WLServerAPI serverApi = WLServerAPIProvider.getWLServerAPI();
The WLServerAPI interface is the parent of all the API categories: analytics, configuration, push, adapters, authentication. If you want to use the push API, you can write:
PushAPI pushApi = serverApi.getPushAPI();

For more information on the Java API, see the com.worklight.adapters.rest.api package. Examples of the use of the API are provided in the following sections.

Logger
Adding a logger to the JAX-RS resource of your adapter is essential for logging debug information, information, warnings, and errors to the MobileFirst Server log. In the Java adapters, you can use the standard java.util.logging logger. To add logger declare the following static field:
static Logger logger = Logger.getLogger(UsersResource.class.getName());
Note: The logger is part of the new adapter template, so in most cases, there is no need to add it.
Push API
You can extend the UsersResource described in Implementing the JAX-RS service of the adapter to notify all the devices of a user when the user record is updated:
WLServerAPI serverAPI = WLServerAPIProvider.getWLServerAPI();
 
@PUT
@Consumes(MediaType.APPLICATION_JSON)
public Response updateUser(User u) {
         
    //TODO Really update the user...
         
    //Notify all devices that the user has been updated
    PushAPI push = serverAPI.getPushAPI();
    INotification notification = push.buildNotification();
    notification.getTarget().setUserIds(u.getId());//Targeted only for the updated user
         
    JSONObject payload = new JSONObject();
    payload.put("user", u.getId());
    notification.getSettings().getAPNS().setPayload(payload);
         
    try {
        push.sendMessage(notification, "myApp");
    } catch (MFPSendMessageFailedException e) {
        e.printStackTrace(); //Ignore failure in this case, since the update succeeded.
    }
    return Response.ok().build();
}
Security API
The security API provides the security context object that contains information about the identity of the request issuer. In the following example, a new validation is added to the user's resource: User records can be updated only by users themselves:
WLServerAPI serverAPI = WLServerAPIProvider.getWLServerAPI();
 
@PUT
@Consumes(MediaType.APPLICATION_JSON)
publis Response updateUser(User u) {
     
    SecurityAPI security = serverAPI.getSecurityAPI();
    String requestIssuerUserId = security.getSecurityContext().getUserIdentity().getId();
    if (!u.getId().equals(requestIssuerUserId)){
        return Response.status(Status.FORBIDDEN)
                       .entity("The user: "+requestIssuerUserId+
                               " is not allowed to modify the user record of another user").build();
    }
     
    //TODO Really update the user...
Adapters API
The adapters API makes it easy to perform requests to other adapters in the same server.

The following example shows how to use the adapters API to call a JavaScript adapter:

@Path("/")
public class JavaAdapter1Resource {
    static Logger logger = Logger.getLogger(JavaAdapter1Resource.class.getName());
     
    @GET
    @Path("/calljs")
    @Produces("application/json")
    public JSONObject callJSAdapterExample() throws Exception{
        AdaptersAPI adaptersAPI = WLServerAPIProvider.getWLServerAPI().getAdaptersAPI();
        //Using helper method to create a request to the JS adapter
        HttpUriRequest req = adaptersAPI.createJavascriptAdapterRequest("JSAdapter", "getStories");
        //Execute the request and get the response
        HttpResponse resp = adaptersAPI.executeAdapterRequest(req);
        //Convert the response to JSON since we know that JS adapters always return JSON
        JSONObject json = adaptersAPI.getResponseAsJSON(resp);
        //Return the json response as the response of the current request that is being taking care of
        return json;
    }
Configuration API
The configuration API enables the adapter to read server-side configuration properties defined in the worklight.properties file or as JNDI entries. For more information about MobileFirst configuration properties, see CLI Commands.

For example, to get the value of the serverSessionTimeout property, write the following code:

String serverSessionTimeout = serverAPI.getConfigurationAPI().getMFPConfigurationProperty("serverSessionTimeout");
Saving applicative state between requests in Java RESTful adapters

In versions earlier than V7.1.0, developers were able to store the applicative state in the HTTP session, by using the session object, namely request.getSession() (see WL.Server).

If you are working in session-independent mode that became available starting with IBM MobileFirst Platform Foundation V7.1.0, the applicative state of the adapter must be persisted outside the session, for example, by using a database such as Cloudant®. For more information on session-independent mode, including steps for upgrading projects that were created in earlier versions of IBM MobileFirst Platform Foundation, see Session-independent mode.

The following code snippets provide examples for migrating code from an earlier version of IBM MobileFirst Platform Foundation so that it support the changes for session-independent mode in V7.1.0.

Consider a shopping-cart app, in which users can add items to a cart, see the list of items that are already in the cart, and submit an order when satisfied with the items in it.

Before V7.1.0, this functionality might have been implemented in the following code:
//Define the server API to be able to perform server operations
WLServerAPI api = WLServerAPIProvider.getWLServerAPI();

@GET
@Path("/addItemToCart")
public void addItemToCart(@Context HttpServletRequest request, @HeaderParam("item") String item) {

    String oldItems = getItemsFromCart(request);
    
    HttpSession session = request.getSession();
    session.setAttribute("items", oldItems + " " + item);
    
}

@GET
@Path("/getItemsFromCart")
public String getItemsFromCart(@Context HttpServletRequest request) {
    HttpSession session = request.getSession();
    return (String) session.getAttribute("items");
}
Assume you are using Cloudant as the persist store over the Cloudant Java Client API and that you are implementing a Java RESTful HTTP adapter called ShoppingCartAdapter. See Figure 1: using OAuthSecurityContext.getClientId(), the adapter requests the ID that is associated with the current client from MobileFirst Serverand uses it when reading or writing applicative data to or from Cloudant.
Figure 1. Retrieving applicative data using the server-side OAuthSecurityContext.getClientId API.
Using server-side getClientId method for retrieving applicative data
If you adapt the code to work in session-independent mode under V7.1.0, the code for MobileFirst V7.1.0 might look as follows:
//Define the server API to be able to perform server operations
WLServerAPI api = WLServerAPIProvider.getWLServerAPI();

CloudantClient client = new CloudantClient("cloudantId", "username", "password");
@GET
@Path("/addItemToCart")
public void addItemToCart(@HeaderParam("item") String item) {
    // Get the clientID from the MFP API (new in 7.1.0)
    String userId = api.getSecurityAPI().getSecurityContext().getClientId();
    saveItemToCloudant("shoppingcartdb", userId, item);
    }
    
@GET
@Path("/getItemsFromCart")
public String getItemsFromCart() {
    // Get the clientID from the MFP API (new in 7.1.0)
    String userId = api.getSecurityAPI().getSecurityContext().getClientId();
    return (String) readItemFromCloudant("shoppingcartdb", userId).get("items");
}
    
/**
 * Reads a JSONObject shopping cart item from Cloudant and returns the document 
 * that corresponds to this _id
 * @param db
 * @param key
 * @return a JSONObject
 */
public JSONObject readItemFromCloudant(String db, String key){
    Database cloudantDb = client.database(db, false);
     
    // Search for the document
    return cloudantDb.find(JSONObject.class, key);
}
   
/**
 * Saves a JSONObject shopping cart item to Cloudant
 * @param db - the DB to save to
 * @param key - the _id
 * @param value
 */
public void saveItemToCloudant(String db, String key, String value){
    Database cloudantDb = client.database(db, false);
    
    // Search for the document
    try{
        JSONObject document = cloudantDb.find(JSONObject.class, key);
        String listOfItems = (String) document.get("items");
        // Add new shopping cart item to list
        listOfItems += " " + value;
        document.put("items", listOfItems);
            
        // Update the document
        cloudantDb.update(document);
    }catch(NoDocumentException e){
        // New Document
        JSONObject obj = new JSONObject();
        obj.put("_id", key);
        obj.put("items", value);

        // Save the object to cloudant db
        cloudantDb.save(obj);
    }