How-to’s: Introducing REST Web Services Capabilities of Avaya Breeze

With the Avaya Breeze Platform™ developers can easily create new and innovative communication solutions using telephony and HTTP(S)-based applications. With web service applications, REST (Representational State Transfer) has become the predominant design model for delivery of services. Avaya Breeze includes JAX-RS-based REST web service capabilities right out of the box. While there are a large number of freely available tutorials about creating JAX-RS-based REST web services, this blog gives a brief introduction to REST capabilities of Avaya Breeze.
REST APIs are designed around resources that are somewhat like Java classes, where each resource has a URI that references it. These resources can include create, read, update and delete (CRUD) requests using corresponding HTTP operations like GET, POST, PUT and DELETE. With JAX-RS, the implementation of REST is simplified through runtime annotations in your classes, which create helper classes and artifacts associated with your resources. These annotations include the notion of a base URI for your application, where you annotate your classes with the resource name that will follow that base URI.
Creating REST-based web services with Avaya Breeze is a snap. Applications running within the Avaya Breeze environment are called “Snap-ins” because new capabilities can be easily snapped into the environment as needed. Creating Snap-ins is a simple exercise thanks to Maven and the Avaya-provided archetype artifact that automatically generates the Java Snap-in project. Included in the generated project are functional examples of Snap-in invocation. These include classes supporting call processing, HTTP web service or web page, and of course a default JAX-RS based-REST web service using Jersey annotations. (Learn more about creating Snap-ins at Avaya DevConnect.)
For this blog, I’ve created a new Snap-in named BreezeRestExample. All of the classes generated by the archetype are located in the project’s WAR module where two classes, namely MyApplication and MyResource, constitute the Snap-in’s sample REST interface.
The MyApplication class below forms the base resource path for the Snap-in’s REST interface with the @ApplicationPath(“/ws”)annotation.

package com.avaya.BreezeRestExample;
 
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath(“/ws”)
public class MyApplication extends Application
{
     //Don’t need to implement getClasses
}
The “/ws” value can be changed where the default Breeze REST path is:
http(s)://<IP Address or FQDN of the Breeze cluster>/services/<snap-in name>/ws/myResource.
But where is the “/myResource” portion of the URL actually defined? In the same folder, the MyResource class defines the Snap-in’s single REST resource using the JAX-RS @Path(“/myResource”) annotation. This resource includes the @GET annotation associating the doGet() method with HTTP GET operations. When invoked, the resource returns a simple “Hello World” string.

package com.avaya.BreezeRestExample;
 
import javax.ws.rs.GET;
import javax.ws.rs.Path;
 
@Path(“/myResource”)
public class MyResource {
     @GET
     public String doGet(){
           return “Hello World”;
     }
}

Exercising the Snap-in’s sample web service resource can be done from your favorite Browser or REST client like Postman using the Snap-in’s full URI:
http(s)://<IP Address or FQDN of the Breezecluster>/services/BreezeRestExample/ws/myResource.
 
Response:
200 OK
Hello World!
Adding resources to the Snap-in’s web service is easy. Additional resource operations (like those supporting GET and POST) could be placed into the MyResource class, but this is an example class. Instead, creating classes that both define the resources, their paths, and capabilities delivered is likely a better choice. This practice is also aligned with Object Oriented Programming principals. Following the latter approach, I created the new class below called Message.

package com.avaya.BreezeRestExample;
 
import javax.enterprise.context.ApplicationScoped;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
 
@ApplicationScoped
@Path(“message/”)
public class Message {
     /*
      * String to store the Message of the Day.
      * */
  private String msgOfTheDay = “No message today”;
  @GET
  @Produces(MediaType.TEXT_PLAIN)
  public String getMessage(){
      return “The Message of the Day is: ” + msgOfTheDay;
  }
  @POST
  @Produces(MediaType.TEXT_PLAIN)
  @Consumes(MediaType.TEXT_PLAIN)
  @Path(“{msgText}”)
  public String setMessage(@PathParam (“msgText”)String msgText) {
     msgOfTheDay = msgText;
     return “Got it! The New Message of the Day is: ” + msgOfTheDay;
  }
}
You will notice familiar annotations in this the Message class, but also a few new annotations. First with the annotations already discussed, the Message class includes the @Path(“message/”) annotation forming a new URL to the Message class resource operations, defined later in the Class.

http(s)://<IP Address or FQDN of the Breezecluster>/services/BreezeRestExample/ws/message/

The first operation in our new resource can be found with the familiar @GET annotation that associates the public String getMessage() method with HTTP GET operations. This method returns a string value representing the Message of the Day. The msgOfTheDay String is a class member variable used to store the Message of the Day value between different REST requests.
You might ask, aren’t REST web services by nature stateless? Yes, the default scope of @Dependant is automatically used unless otherwise defined. With the @Dependant scope, the object exists to serve exactly one client (bean) and has the same lifecycle as that client (bean). (See Oracle, January 1, 2013. The Java EE 6 Tutorial, retrieved September 27, 2017, from https://docs.oracle.com/javaee/6/tutorial/doc/gjbbk.html.)
Since the Message of the Day string will need to persist between REST requests, the @ApplicationScoped annotation is used. This is declared just prior to the class definition allowing the class instance to be shared across all users’ of the web application, thereby functioning as a Singleton object. In addition, the application must contain a beans.xml file in the project’s WEB-INF folder forcing the web server (Websphere in this case) to scan the project for Contexts and Dependency Injection (CDI) annotations like @ApplicationScoped. For reference, the beans.xml file is listed below:

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://java.sun.com/xml/ns/javaee” xmlns:xsi=”http://www.w3.org/2001/
XMLSchema-instance” xsi:schemeLocation=”http://java.sun.com/xml/ns/javaee http://
java.sun.com/xml/ns/javaee/beans_1_0.xsd”>
<!– This is empty on purpose. –>
</beans>
The second supported operation of our Message resource is defined by the @POST annotation. This associates the public String setMessage(@PathParam (“msgText”)String msgText) method with HTTP POST operations.
Included in this Resource’s operation is also a new @Path(“{msgText}”) annotation building upon the class’s URL specifying a required input parameter. The URL for this is http(s)://<IP Address or FQDN of the Breezecluster>/services/BreezeRestExample/ws/message/< some message text>
Again thanks to JAX-RS and the use of the @PathParam annotation in the setMessage() declaration, the <some message text> portion of the POST operation’s URL is automatically copied to the method’s local msgText variable.
Once received, the msgText is copied to the class’s msgOfTheDay variable, which as mentioned previously, is persisted between sessions because of the @ApplicationScoped annotation.
Testing our new Message resource, operations with a REST client like Postman produces the following results.
With GET operations prior to setting the Message of the Day string for the first time, the default “No message today” is returned:
http(s)://<IP Address or FQDN of the Breezecluster>/services/BreezeRestExample/ws/message.
Response:
200 OK
The Message of the Day is: No message today
POST operations that set the Message of the Day also confirm the input parameter passed in the request:
http(s)://<IP Address or FQDN of the Breezecluster>/services/BreezeRestExample/ws/message/Happy Halloween.
Response:
200 OK
Got it! The New Message of the Day is: Happy Halloween
Subsequent GET operations confirm the persistence of the Message of the Day string:
http(s)://<IP Address or FQDN of the Breezecluster>/services/BreezeRestExample/ws/message/
Response:
200 OK
The Message of the Day is: Happy Halloween
Finally, the last of the new annotations used in the Message class include @Produces(MediaType.TEXT_PLAIN) and @Consumes(MediaType.TEXT_PLAIN) which specify the MIME media types resources can produce and consume. In this example, we used text plain for simplicity where a litany of others can be used including APPLICATION_XML_TYPE , APPLICATION_JSON_TYPE and TEXT_HTML_TYPE depending on the requirements of your application. JAX-RS will automatically convert values to and from these formats to your class objects, which is a huge bonus.
While there is much more to explore in developing REST web services using JAX-RS, hopefully this example demonstrates how easy it is to create REST-based web services with Avaya Breeze.
The post How-to’s: Introducing REST Web Services Capabilities of Avaya Breeze appeared first on Avaya Connected Blog.
Source: Avaya

Leave a Reply

Your email address will not be published. Required fields are marked *