18 October 2015

API Documentation with Swagger

In this post I will discuss How to document REST API.There are several API documentation tools available.

So In here I will use Swagger as API documentation tool.

Why API Documentation

The Main purpose is Test the API work properly.For Test API normally what we do is using curl or postman send request and Test.So Let's think About Who don't have programming knowledge how to test API.API documentation is to help them to read our API.

Swagger Support user friendly UI to Test the API.For demonstrate behavior of swagger UI I have created sample rest API.

How to use Swagger

First Add these service beans and providers to your server.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<jaxrs:serviceBeans>
     <ref bean="studentManagementListener"/>
     <ref bean="swaggerResourceJSON"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
     <ref bean="jacksonProvider"/>
     <ref bean="resourceWriter"/>
     <ref bean="apiWriter"/>
     <ref bean="corsFilter"/>
</jaxrs:providers>


<bean id="corsFilter" class="org.apache.cxf.rs.security.cors.CrossOriginResourceSharingFilter"/>

    <bean id="swaggerResourceJSON" class="com.wordnik.swagger.jaxrs.listing.ApiListingResourceJSON"/>

    <!-- Swagger writers -->

    <bean id="resourceWriter" class="com.wordnik.swagger.jaxrs.listing.ResourceListingProvider"/>

    <bean id="apiWriter" class="com.wordnik.swagger.jaxrs.listing.ApiDeclarationProvider"/>


And Then Need to Add Swagger Config Bean.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<bean id="swaggerConfig" class="com.wordnik.swagger.jaxrs.config.BeanConfig">

        <property name="resourcePackage" value="dev.innova.rest.server.api"/>

        <property name="version" value="1.0.0"/>

        <property name="basePath" value="${student.management.api.url}"/>

        <property name="title" value="Student Management API"/>

        <property name="description" value="Student Management API Support to Manage Students in library"/>

        <property name="contact" value="sajith.vijesekara@gmail.com"/>

        <property name="license" value="Apache 2.0 License"/>

        <property name="licenseUrl" value="http://www.apache.org/licenses/LICENSE-2.0.html"/>

        <property name="scan" value="true"/>

    </bean>

And The Final Step is define Your API model.It is simple.Using swagger Annotations you can easily  make API visible in swagger UI.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@Path("/")
@ApiModel(value = "Student Management")
@Api(value = "Student Management Server", description = "Student Management")
@CrossOriginResourceSharing(allowAllOrigins = true, allowCredentials = true)
public interface StudentManagement {

    @POST
    @Path("/student/add")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "Add Student", response = Response.class, notes = "Add Student")
    @ApiResponses(value = {@ApiResponse(code = 200, message = "Add Student Successful"),
    @ApiResponse(code = 404, message = "Failed to Add Student"),
    @ApiResponse(code = 500, message = "Failed to connect to Server")})
    Response addStudent(Student student);



    @GET
    @Path("/student/search")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "Search Student", response = Response.class, notes = "Search Student")
    @ApiResponses(value = {@ApiResponse(code = 200, message = "Search Student Successful"),
    @ApiResponse(code = 404, message = "Failed to Search Student"),
    @ApiResponse(code = 500, message = "Failed to connect to Server")})
    Response searchUser(GetStudent name);



    @DELETE
    @Path("/student/remove")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "Delete Student", response = Response.class, notes = "Delete Student")
    @ApiResponses(value = {@ApiResponse(code = 200, message = "Delete Student Successful"),
    @ApiResponse(code = 404, message = "Failed to Delete Student"),
    @ApiResponse(code = 500, message = "Failed to connect to Server")})
    Response removeStudent(GetStudent name);

}

And One Thing I forgot to add what are the dependencies for swagger.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<dependency>
     <groupId>com.wordnik</groupId>
     <artifactId>swagger-jersey2-jaxrs_2.10</artifactId>
     <version>1.3.8</version>
      <exclusions>
         <exclusion>
             <groupId>javax.ws.rs</groupId>
             <artifactId>jsr311-api</artifactId>
         </exclusion>
      </exclusions>
  </dependency>

  <dependency>
       <groupId>org.apache.cxf</groupId>
       <artifactId>cxf-rt-rs-security-cors</artifactId>
       <version>2.6.1</version>
  </dependency>


How to use Swagger UI
Download Swagger UI and deploy in tomcat server.Then open swagger UI and enter API url with api-docs tag at end of URL.

Ex:- http://127.0.0.1:4738/api-docs



04 October 2015

Android Google cloud messaging Test server

Java GCM Testing Server

Today I will share how to create java Testing Application for send android GCM notifications to android client.There are lot of examples how to create android GCM client application but for testing the notification flow you need server.But I couldn't found any good example how to create java server.So I found Library for send notifications so i used that library and create simple swing application to send notification.



Sample Code

This is the code-sample which I have already pushed in to github location(https://github.com/sajith4u/android-gsm-sample).


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package dev.innova.sajith;

import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;


public class MainClass {

    public static void main(String[] args) {
        System.out.println("starting gcm-server Application");
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                init();
            }
        });

    }

    /**
     *  Send Notification to server
     * @param apiKey
     * @param registrationId
     * @param title
     * @param messagetext
     * @return
     */
    public static String send(String apiKey, String registrationId,String title,String messagetext) {
        Sender sender = new Sender(apiKey);
        Result result = null;
        Message message = new Message.Builder()
                .addData("message",messagetext)
                .addData("title", title)
                .build();
        try {
            result = sender.send(message, registrationId, 2);
            System.out.println("Result : " + result.getMessageId());
            System.out.println("Result ErrorCode : " + result.getErrorCodeName());
            System.out.println("Result : " + result.getCanonicalRegistrationId());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result.toString();
    }

    /**
     * Initialize the Swing form
     */
    public static void init() {
        JFrame frame = new JFrame("Notification Sender");
        frame.setSize(600, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();
        frame.add(panel);
        placeComponents(panel);

        frame.setVisible(true);
    }

    /**
     *  Add Items to Swing form
     * @param panel
     */
    private static void placeComponents(JPanel panel) {

        panel.setLayout(null);

        JLabel apiKeyLabel = new JLabel("ApiKey");
        apiKeyLabel.setBounds(50, 20, 100, 40);
        panel.add(apiKeyLabel);

       final JTextField apiKeyText = new JTextField(20);
        apiKeyText.setBounds(160, 20, 400, 40);
        panel.add(apiKeyText);

        JLabel registrationLabel = new JLabel("Registraion ID");
        registrationLabel.setBounds(50, 70, 100, 40);
        panel.add(registrationLabel);

        final JTextField registrationText = new JTextField(20);
        registrationText.setBounds(160, 70, 400, 40);
        panel.add(registrationText);

        JLabel titleLabel = new JLabel("Title :");
        titleLabel.setBounds(50, 120, 100, 40);
        panel.add(titleLabel);

        final JTextField titleText = new JTextField(20);
        titleText.setBounds(160, 120, 400, 40);
        panel.add(titleText);

        JLabel messageLabel = new JLabel("Message :");
        messageLabel.setBounds(50, 170, 100, 40);
        panel.add(messageLabel);

        final JTextField messageText = new JTextField(20);
        messageText.setBounds(160, 170, 400, 40);
        panel.add(messageText);

        JButton resetButton = new JButton("Reset");
        resetButton.setBounds(50, 220, 120, 40);
        panel.add(resetButton);

        JButton sendNotification = new JButton("Send");
        sendNotification.setBounds(250, 220, 120, 40);
        panel.add(sendNotification);

        final JLabel statusLabel = new JLabel("status :");
        statusLabel.setBounds(50, 270, 400, 100);
        panel.add(statusLabel);

        sendNotification.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                statusLabel.setText("");
                String message = messageText.getText();
                String apiKey = apiKeyText.getText();
                String registrationKey = registrationText.getText();
                String titleMessage = titleText.getText();
                if((registrationKey.equals("")||registrationKey.equals(null))||(apiKey.equals("")||apiKey.equals(null))||(message.equals("")||message.equals(null))){
                    statusLabel.setText("Please Fill the above three Fields");
                }else {
                    statusLabel.setText("sending message ...........");
                    String response = send(apiKey,registrationKey,titleMessage,message);
                    statusLabel.setText(response);
                }

            }
        });

        resetButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                statusLabel.setText("");
                messageText.setText("");
                apiKeyText.setText("");
                registrationText.setText("");
                titleText.setText("");
            }
        });

    }


}

For use this application you need API key which provided when creating application in Google could platform and registration Id.In the next post I will share simple android client application and how to test using this server.