Commit f9b34e7a authored by chiaming2000's avatar chiaming2000
Browse files

Added a simple heartbeat http monitor service example. Users can use a

browser to get a list of available kinetic services (drives/simulators)
in the response message.

To start the service, under <kinetic-java> folder, run
sh ./bin/heartbeatMonitor.sh

From a browser on the same host, type
http://<localhost>:<8080>

Use an appropriate hostname and port if the service was started on a
different host/port.
parent fc427006
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
#! /usr/bin/env bash

BASE_DIR=`dirname "$0"`/..
BASE_DIR=`cd "$BASE_DIR"; pwd`
#echo "BASE_DIR=$BASE_DIR"

JAVA=""
if [ "$JAVA_HOME" != "" ]; then
    JAVA=$JAVA_HOME/bin/java
else
   echo "JAVA_HOME must be set."
   exit 1
fi

#Set the classpath

if [ "$CLASSPATH" != "" ]; then
   CLASSPATH=${CLASSPATH}:$JAVA_HOME/lib/tools.jar
else
   CLASSPATH=$JAVA_HOME/lib/tools.jar
fi

CLASSPATH=${CLASSPATH}:$BASE_DIR/kinetic-test/target/test-classes

for f in $BASE_DIR/kinetic-test/target/*.jar; do
   CLASSPATH=${CLASSPATH}:$f
done

echo "CLASSPATH=$CLASSPATH"

exec "$JAVA" -classpath "$CLASSPATH" com.seagate.kinetic.example.heartbeat.rest.RestHeartbeatService "$@"
+99 −0
Original line number Diff line number Diff line
/**
 * 
 * Copyright (C) 2014 Seagate Technology.
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */
package com.seagate.kinetic.example.heartbeat.rest;

import java.io.IOException;
import java.io.StringReader;
import java.util.Collections;

import java.util.SortedMap;
import java.util.TreeMap;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.google.gson.Gson;

import com.google.gson.stream.JsonReader;
import com.seagate.kinetic.heartbeat.HeartbeatMessage;
import com.seagate.kinetic.monitor.HeartbeatListener;

/**
 * 
 * Collect heart beat information into a sorted map.
 * <p>
 * This is used by the HTTP service to get the drives IP and service ports.
 * 
 * @see RestHeartbeatService
 * @see HeartbeatHandler
 * 
 * @author chiaming
 *
 */
public class HeartbeatCollector extends HeartbeatListener {
    
    private final static Logger logger = Logger
            .getLogger(HeartbeatCollector.class.getName());
    
    private SortedMap <String, HeartbeatMessage> drives = 
            Collections.synchronizedSortedMap(new TreeMap<String, HeartbeatMessage>());

    public HeartbeatCollector() throws IOException {
        super();
    }
    
    @Override
    public void onMessage(byte[] data) {

        try {

            String message = new String(data, "UTF8");

            JsonReader reader = new JsonReader(new StringReader(message));
            reader.setLenient(true);
            
            Gson gson = new Gson();
            
            HeartbeatMessage hbm = gson
                    .fromJson(reader, HeartbeatMessage.class);
            
            String key = hbm.getNetworkInterfaces().get(0).getIpV4Address() + ":" + hbm.getPort();
            
            this.drives.put(key, hbm);

            logger.fine ("received heart beat: " + key);
            

        } catch (Exception e) {
            logger.log(Level.WARNING, e.getMessage(), e);
        }

    }
    
    /**
     * Get the heart beat map used by this collector.
     * 
     * @return the heart beat map used by this collector
     */
    public SortedMap<String, HeartbeatMessage> getHeartBeatMap() {
        return new TreeMap<String, HeartbeatMessage> (drives);
    }

}
+103 −0
Original line number Diff line number Diff line
/**
 * 
 * Copyright (C) 2014 Seagate Technology.
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */
package com.seagate.kinetic.example.heartbeat.rest;

import java.io.IOException;
import java.util.Date;

import java.util.SortedMap;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.server.Request;

import org.eclipse.jetty.server.handler.AbstractHandler;

import com.seagate.kinetic.heartbeat.HeartbeatMessage;

/**
 * Rest Heartbeat handler handles HTTP request.
 * <p>
 * The response is a HTML table that contains all the collected kinetic heartbeats.
 * 
 * @see RestHeartbeatService
 * 
 * @author chiaming
 *
 */
public class HeartbeatHandler extends AbstractHandler {
    
    private final static Logger logger = Logger
            .getLogger(HeartbeatHandler.class.getName());
    
    private HeartbeatCollector hbc = null;
    
    public HeartbeatHandler(HeartbeatCollector hbc) { 
        this.hbc = hbc;
    }
    
    @Override
    public void handle(String target, Request baseRequest,
            HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        response.setContentType("text/html;charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        baseRequest.setHandled(true);
        response.getWriter().println("<h1>Hearbeat Table</h1>");
        
        response.getWriter().println("<br>update time: " + new Date() + "</br>");
        
        SortedMap <String, HeartbeatMessage> map = hbc.getHeartBeatMap();
        
       int index = 0;
       
       String table = "<table border=\"1\" style=\"width:300px\">";
       response.getWriter().println(table);
       
       response.getWriter().println("<tr>");
       response.getWriter().println("<td>Num</td>");
       response.getWriter().println("<td>IP Address</td>");
       response.getWriter().println("<td>TCP Port</td>");
       response.getWriter().println("<td>TLS Port</td>");
       response.getWriter().println("</tr>");
       
        synchronized (this) {
            
            for (String key: map.keySet()) {
                //response.getWriter().println("<br>" + index + ":    " + key);
                response.getWriter().println("<tr>");
                response.getWriter().println("<td>" + index +"</td>");
                response.getWriter().println("<td>" + map.get(key).getNetworkInterfaces().get(0).getIpV4Address() +"</td>");
                response.getWriter().println("<td>" + map.get(key).getPort() +"</td>");
                response.getWriter().println("<td>" + map.get(key).getTlsPort() +"</td>");
                response.getWriter().println("</tr>");
                index ++;
            }
        }
        
        response.getWriter().println("</table>");
        
        logger.info("total kinetic services collected: " + map.size());
    }

}
+73 −0
Original line number Diff line number Diff line
/**
 * 
 * Copyright (C) 2014 Seagate Technology.
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */
package com.seagate.kinetic.example.heartbeat.rest;

import java.util.logging.Logger;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;

/**
 * Start simple kinetic heart beat monitor HTTP service.
 * <p>
 * Applications may use a browser to see the available kinetic services. The default URL for the service is:
 * <p>
 * http://<hostName>:<port>
 * 
 * <p>
 * For example, if the service is running on the same machine, the default url would be as follows.
 * 
 * http://localhost:8080
 * 
 * 
 * @author chiaming
 *
 */
public class RestHeartbeatService {
    
    private final static Logger logger = Logger
            .getLogger(RestHeartbeatService.class.getName());

    public static void main(String[] args) throws Exception {
        
        int port = 8080;
        
        if (args.length >0) {
            port = Integer.parseInt(args[0]);
        }
        
        HeartbeatCollector hbc = new HeartbeatCollector();
        HeartbeatHandler handler = new HeartbeatHandler (hbc);
        
        Server server = new Server(port);
        
        ContextHandler hbcontext = new ContextHandler("/");
        hbcontext.setContextPath("/");
        hbcontext.setHandler(handler);
        
        server.setHandler(hbcontext);
        
        server.start();
        
        logger.info("heartbeat rest service is ready ...");
        
        server.join();
    }
}