geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hiteshkhame...@apache.org
Subject [64/83] [abbrv] incubator-geode git commit: GEODE-37 renamed pulse package
Date Fri, 09 Sep 2016 21:44:01 GMT
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eff7f216/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/json/README
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/json/README b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/json/README
new file mode 100644
index 0000000..2d7cdcf
--- /dev/null
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/json/README
@@ -0,0 +1,68 @@
+JSON in Java [package com.vmware.gemfire.tools.pulse.internal.json]
+
+Douglas Crockford
+douglas@crockford.com
+
+2011-02-02
+
+
+JSON is a light-weight, language independent, data interchange format.
+See http://www.JSON.org/
+
+The files in this package implement JSON encoders/decoders in Java. 
+It also includes the capability to convert between JSON and XML, HTTP 
+headers, Cookies, and CDL. 
+
+This is a reference implementation. There is a large number of JSON packages
+in Java. Perhaps someday the Java community will standardize on one. Until 
+then, choose carefully.
+
+The license includes this restriction: "The software shall be used for good, 
+not evil." If your conscience cannot live with that, then choose a different
+package.
+
+The package compiles on Java 1.2 thru Java 1.4.
+
+
+JSONObject.java: The JSONObject can parse text from a String or a JSONTokener
+to produce a map-like object. The object provides methods for manipulating its
+contents, and for producing a JSON compliant object serialization.
+
+JSONArray.java: The JSONObject can parse text from a String or a JSONTokener
+to produce a vector-like object. The object provides methods for manipulating 
+its contents, and for producing a JSON compliant array serialization.
+
+JSONTokener.java: The JSONTokener breaks a text into a sequence of individual
+tokens. It can be constructed from a String, Reader, or InputStream.
+
+JSONException.java: The JSONException is the standard exception type thrown
+by this package.
+
+
+JSONString.java: The JSONString interface requires a toJSONString method, 
+allowing an object to provide its own serialization.
+
+JSONStringer.java: The JSONStringer provides a convenient facility for 
+building JSON strings.
+
+JSONWriter.java: The JSONWriter provides a convenient facility for building 
+JSON text through a writer.
+ 
+
+CDL.java: CDL provides support for converting between JSON and comma
+delimited lists.
+
+Cookie.java: Cookie provides support for converting between JSON and cookies.
+
+CookieList.java: CookieList provides support for converting between JSON and
+cookie lists.
+
+HTTP.java: HTTP provides support for converting between JSON and HTTP headers.
+
+HTTPTokener.java: HTTPTokener extends JSONTokener for parsing HTTP headers.
+
+XML.java: XML provides support for converting between JSON and XML.
+
+JSONML.java: JSONML provides support for converting between JSONML and XML.
+
+XMLTokener.java: XMLTokener extends JSONTokener for parsing XML text.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eff7f216/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/json/XML.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/json/XML.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/json/XML.java
new file mode 100644
index 0000000..2aa8b8d
--- /dev/null
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/json/XML.java
@@ -0,0 +1,503 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.geode.tools.pulse.internal.json;
+
+import java.util.Iterator;
+
+
+/**
+ * This provides static methods to convert an XML text into a JSONObject,
+ * and to covert a JSONObject into an XML text.
+ * @author JSON.org
+ * @version 2011-02-11
+ */
+public class XML {
+
+    /** The Character '&'. */
+    public static final Character AMP   = new Character('&');
+
+    /** The Character '''. */
+    public static final Character APOS  = new Character('\'');
+
+    /** The Character '!'. */
+    public static final Character BANG  = new Character('!');
+
+    /** The Character '='. */
+    public static final Character EQ    = new Character('=');
+
+    /** The Character '>'. */
+    public static final Character GT    = new Character('>');
+
+    /** The Character '<'. */
+    public static final Character LT    = new Character('<');
+
+    /** The Character '?'. */
+    public static final Character QUEST = new Character('?');
+
+    /** The Character '"'. */
+    public static final Character QUOT  = new Character('"');
+
+    /** The Character '/'. */
+    public static final Character SLASH = new Character('/');
+
+    /**
+     * Replace special characters with XML escapes:
+     * <pre>
+     * &amp; <small>(ampersand)</small> is replaced by &amp;amp;
+     * &lt; <small>(less than)</small> is replaced by &amp;lt;
+     * &gt; <small>(greater than)</small> is replaced by &amp;gt;
+     * &quot; <small>(double quote)</small> is replaced by &amp;quot;
+     * </pre>
+     * @param string The string to be escaped.
+     * @return The escaped string.
+     */
+    public static String escape(String string) {
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0, length = string.length(); i < length; i++) {
+            char c = string.charAt(i);
+            switch (c) {
+            case '&':
+                sb.append("&amp;");
+                break;
+            case '<':
+                sb.append("&lt;");
+                break;
+            case '>':
+                sb.append("&gt;");
+                break;
+            case '"':
+                sb.append("&quot;");
+                break;
+            case '\'':
+                sb.append("&apos;");
+                break;
+            default:
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+    
+    /**
+     * Throw an exception if the string contains whitespace. 
+     * Whitespace is not allowed in tagNames and attributes.
+     * @param string
+     * @throws JSONException
+     */
+    public static void noSpace(String string) throws JSONException {
+        int i, length = string.length();
+        if (length == 0) {
+            throw new JSONException("Empty string.");
+        }
+        for (i = 0; i < length; i += 1) {
+            if (Character.isWhitespace(string.charAt(i))) {
+                throw new JSONException("'" + string + 
+                        "' contains a space character.");
+            }
+        }
+    }
+
+    /**
+     * Scan the content following the named tag, attaching it to the context.
+     * @param x       The XMLTokener containing the source string.
+     * @param context The JSONObject that will include the new material.
+     * @param name    The tag name.
+     * @return true if the close tag is processed.
+     * @throws JSONException
+     */
+    private static boolean parse(XMLTokener x, JSONObject context,
+                                 String name) throws JSONException {
+        char       c;
+        int        i;
+        JSONObject jsonobject = null;
+        String     string;
+        String     tagName;
+        Object     token;
+
+// Test for and skip past these forms:
+//      <!-- ... -->
+//      <!   ...   >
+//      <![  ... ]]>
+//      <?   ...  ?>
+// Report errors for these forms:
+//      <>
+//      <=
+//      <<
+
+        token = x.nextToken();
+
+// <!
+
+        if (token == BANG) {
+            c = x.next();
+            if (c == '-') {
+                if (x.next() == '-') {
+                    x.skipPast("-->");
+                    return false;
+                }
+                x.back();
+            } else if (c == '[') {
+                token = x.nextToken();
+                if ("CDATA".equals(token)) {
+                    if (x.next() == '[') {
+                        string = x.nextCDATA();
+                        if (string.length() > 0) {
+                            context.accumulate("content", string);
+                        }
+                        return false;
+                    }
+                }
+                throw x.syntaxError("Expected 'CDATA['");
+            }
+            i = 1;
+            do {
+                token = x.nextMeta();
+                if (token == null) {
+                    throw x.syntaxError("Missing '>' after '<!'.");
+                } else if (token == LT) {
+                    i += 1;
+                } else if (token == GT) {
+                    i -= 1;
+                }
+            } while (i > 0);
+            return false;
+        } else if (token == QUEST) {
+
+// <?
+
+            x.skipPast("?>");
+            return false;
+        } else if (token == SLASH) {
+
+// Close tag </
+
+            token = x.nextToken();
+            if (name == null) {
+                throw x.syntaxError("Mismatched close tag " + token);
+            }            
+            if (!token.equals(name)) {
+                throw x.syntaxError("Mismatched " + name + " and " + token);
+            }
+            if (x.nextToken() != GT) {
+                throw x.syntaxError("Misshaped close tag");
+            }
+            return true;
+
+        } else if (token instanceof Character) {
+            throw x.syntaxError("Misshaped tag");
+
+// Open tag <
+
+        } else {
+            tagName = (String)token;
+            token = null;
+            jsonobject = new JSONObject();
+            for (;;) {
+                if (token == null) {
+                    token = x.nextToken();
+                }
+
+// attribute = value
+
+                if (token instanceof String) {
+                    string = (String)token;
+                    token = x.nextToken();
+                    if (token == EQ) {
+                        token = x.nextToken();
+                        if (!(token instanceof String)) {
+                            throw x.syntaxError("Missing value");
+                        }
+                        jsonobject.accumulate(string, 
+                                XML.stringToValue((String)token));
+                        token = null;
+                    } else {
+                        jsonobject.accumulate(string, "");
+                    }
+
+// Empty tag <.../>
+
+                } else if (token == SLASH) {
+                    if (x.nextToken() != GT) {
+                        throw x.syntaxError("Misshaped tag");
+                    }
+                    if (jsonobject.length() > 0) {
+                        context.accumulate(tagName, jsonobject);
+                    } else {
+                        context.accumulate(tagName, "");
+                    }
+                    return false;
+
+// Content, between <...> and </...>
+
+                } else if (token == GT) {
+                    for (;;) {
+                        token = x.nextContent();
+                        if (token == null) {
+                            if (tagName != null) {
+                                throw x.syntaxError("Unclosed tag " + tagName);
+                            }
+                            return false;
+                        } else if (token instanceof String) {
+                            string = (String)token;
+                            if (string.length() > 0) {
+                                jsonobject.accumulate("content", 
+                                        XML.stringToValue(string));
+                            }
+
+// Nested element
+
+                        } else if (token == LT) {
+                            if (parse(x, jsonobject, tagName)) {
+                                if (jsonobject.length() == 0) {
+                                    context.accumulate(tagName, "");
+                                } else if (jsonobject.length() == 1 &&
+                                       jsonobject.opt("content") != null) {
+                                    context.accumulate(tagName, 
+                                            jsonobject.opt("content"));
+                                } else {
+                                    context.accumulate(tagName, jsonobject);
+                                }
+                                return false;
+                            }
+                        }
+                    }
+                } else {
+                    throw x.syntaxError("Misshaped tag");
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Try to convert a string into a number, boolean, or null. If the string
+     * can't be converted, return the string. This is much less ambitious than
+     * JSONObject.stringToValue, especially because it does not attempt to
+     * convert plus forms, octal forms, hex forms, or E forms lacking decimal 
+     * points.
+     * @param string A String.
+     * @return A simple JSON value.
+     */
+    public static Object stringToValue(String string) {
+        if ("".equals(string)) {
+            return string;
+        }
+        if ("true".equalsIgnoreCase(string)) {
+            return Boolean.TRUE;
+        }
+        if ("false".equalsIgnoreCase(string)) {
+            return Boolean.FALSE;
+        }
+        if ("null".equalsIgnoreCase(string)) {
+            return JSONObject.NULL;
+        }
+        if ("0".equals(string)) {
+            return new Integer(0);
+        }
+
+// If it might be a number, try converting it. If that doesn't work, 
+// return the string.
+
+        try {
+            char initial = string.charAt(0);
+            boolean negative = false;
+            if (initial == '-') {
+                initial = string.charAt(1);
+                negative = true;
+            }
+            if (initial == '0' && string.charAt(negative ? 2 : 1) == '0') {
+                return string;
+            }
+            if ((initial >= '0' && initial <= '9')) {
+                if (string.indexOf('.') >= 0) {
+                    return Double.valueOf(string);
+                } else if (string.indexOf('e') < 0 && string.indexOf('E') < 0) {
+                    Long myLong = new Long(string);
+                    if (myLong.longValue() == myLong.intValue()) {
+                        return new Integer(myLong.intValue());
+                    } else {
+                        return myLong;
+                    }
+                }
+            }
+        }  catch (Exception ignore) {
+        }
+        return string;
+    }
+
+    
+    /**
+     * Convert a well-formed (but not necessarily valid) XML string into a
+     * JSONObject. Some information may be lost in this transformation
+     * because JSON is a data format and XML is a document format. XML uses
+     * elements, attributes, and content text, while JSON uses unordered
+     * collections of name/value pairs and arrays of values. JSON does not
+     * does not like to distinguish between elements and attributes.
+     * Sequences of similar elements are represented as JSONArrays. Content
+     * text may be placed in a "content" member. Comments, prologs, DTDs, and
+     * <code>&lt;[ [ ]]></code> are ignored.
+     * @param string The source string.
+     * @return A JSONObject containing the structured data from the XML string.
+     * @throws JSONException
+     */
+    public static JSONObject toJSONObject(String string) throws JSONException {
+        JSONObject jo = new JSONObject();
+        XMLTokener x = new XMLTokener(string);
+        while (x.more() && x.skipPast("<")) {
+            parse(x, jo, null);
+        }
+        return jo;
+    }
+
+
+    /**
+     * Convert a JSONObject into a well-formed, element-normal XML string.
+     * @param object A JSONObject.
+     * @return  A string.
+     * @throws  JSONException
+     */
+    public static String toString(Object object) throws JSONException {
+        return toString(object, null);
+    }
+
+
+    /**
+     * Convert a JSONObject into a well-formed, element-normal XML string.
+     * @param object A JSONObject.
+     * @param tagName The optional name of the enclosing tag.
+     * @return A string.
+     * @throws JSONException
+     */
+    public static String toString(Object object, String tagName)
+            throws JSONException {
+        StringBuffer sb = new StringBuffer();
+        int          i;
+        JSONArray    ja;
+        JSONObject   jo;
+        String       key;
+        Iterator     keys;
+        int          length;
+        String       string;
+        Object       value;
+        if (object instanceof JSONObject) {
+
+// Emit <tagName>
+
+            if (tagName != null) {
+                sb.append('<');
+                sb.append(tagName);
+                sb.append('>');
+            }
+
+// Loop thru the keys.
+
+            jo = (JSONObject)object;
+            keys = jo.keys();
+            while (keys.hasNext()) {
+                key = keys.next().toString();
+                value = jo.opt(key);
+                if (value == null) {
+                    value = "";
+                }
+                if (value instanceof String) {
+                    string = (String)value;
+                } else {
+                    string = null;
+                }
+
+// Emit content in body
+
+                if ("content".equals(key)) {
+                    if (value instanceof JSONArray) {
+                        ja = (JSONArray)value;
+                        length = ja.length();
+                        for (i = 0; i < length; i += 1) {
+                            if (i > 0) {
+                                sb.append('\n');
+                            }
+                            sb.append(escape(ja.get(i).toString()));
+                        }
+                    } else {
+                        sb.append(escape(value.toString()));
+                    }
+
+// Emit an array of similar keys
+
+                } else if (value instanceof JSONArray) {
+                    ja = (JSONArray)value;
+                    length = ja.length();
+                    for (i = 0; i < length; i += 1) {
+                        value = ja.get(i);
+                        if (value instanceof JSONArray) {
+                            sb.append('<');
+                            sb.append(key);
+                            sb.append('>');
+                            sb.append(toString(value));
+                            sb.append("</");
+                            sb.append(key);
+                            sb.append('>');
+                        } else {
+                            sb.append(toString(value, key));
+                        }
+                    }
+                } else if ("".equals(value)) {
+                    sb.append('<');
+                    sb.append(key);
+                    sb.append("/>");
+
+// Emit a new tag <k>
+
+                } else {
+                    sb.append(toString(value, key));
+                }
+            }
+            if (tagName != null) {
+
+// Emit the </tagname> close tag
+
+                sb.append("</");
+                sb.append(tagName);
+                sb.append('>');
+            }
+            return sb.toString();
+
+// XML does not have good support for arrays. If an array appears in a place
+// where XML is lacking, synthesize an <array> element.
+
+        } else {
+            if (object.getClass().isArray()) {
+                object = new JSONArray(object);
+            }
+            if (object instanceof JSONArray) {
+                ja = (JSONArray)object;
+                length = ja.length();
+                for (i = 0; i < length; i += 1) {
+                    sb.append(toString(ja.opt(i), tagName == null ? "array" : tagName));
+                }
+                return sb.toString();
+            } else {
+                string = (object == null) ? "null" : escape(object.toString());
+                return (tagName == null) ? "\"" + string + "\"" :
+                    (string.length() == 0) ? "<" + tagName + "/>" :
+                    "<" + tagName + ">" + string + "</" + tagName + ">";
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eff7f216/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/json/XMLTokener.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/json/XMLTokener.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/json/XMLTokener.java
new file mode 100644
index 0000000..7995af0
--- /dev/null
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/json/XMLTokener.java
@@ -0,0 +1,360 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.geode.tools.pulse.internal.json;
+
+/**
+ * The XMLTokener extends the JSONTokener to provide additional methods
+ * for the parsing of XML texts.
+ * @author JSON.org
+ * @version 2010-12-24
+ */
+public class XMLTokener extends JSONTokener {
+
+
+   /** The table of entity values. It initially contains Character values for
+    * amp, apos, gt, lt, quot.
+    */
+   public static final java.util.HashMap entity;
+
+   static {
+       entity = new java.util.HashMap(8);
+       entity.put("amp",  XML.AMP);
+       entity.put("apos", XML.APOS);
+       entity.put("gt",   XML.GT);
+       entity.put("lt",   XML.LT);
+       entity.put("quot", XML.QUOT);
+   }
+
+    /**
+     * Construct an XMLTokener from a string.
+     * @param s A source string.
+     */
+    public XMLTokener(String s) {
+        super(s);
+    }
+
+    /**
+     * Get the text in the CDATA block.
+     * @return The string up to the <code>]]&gt;</code>.
+     * @throws JSONException If the <code>]]&gt;</code> is not found.
+     */
+    public String nextCDATA() throws JSONException {
+        char         c;
+        int          i;
+        StringBuffer sb = new StringBuffer();
+        for (;;) {
+            c = next();
+            if (end()) {
+                throw syntaxError("Unclosed CDATA");
+            }
+            sb.append(c);
+            i = sb.length() - 3;
+            if (i >= 0 && sb.charAt(i) == ']' &&
+                          sb.charAt(i + 1) == ']' && sb.charAt(i + 2) == '>') {
+                sb.setLength(i);
+                return sb.toString();
+            }
+        }
+    }
+
+
+    /**
+     * Get the next XML outer token, trimming whitespace. There are two kinds
+     * of tokens: the '<' character which begins a markup tag, and the content
+     * text between markup tags.
+     *
+     * @return  A string, or a '<' Character, or null if there is no more
+     * source text.
+     * @throws JSONException
+     */
+    public Object nextContent() throws JSONException {
+        char         c;
+        StringBuffer sb;
+        do {
+            c = next();
+        } while (Character.isWhitespace(c));
+        if (c == 0) {
+            return null;
+        }
+        if (c == '<') {
+            return XML.LT;
+        }
+        sb = new StringBuffer();
+        for (;;) {
+            if (c == '<' || c == 0) {
+                back();
+                return sb.toString().trim();
+            }
+            if (c == '&') {
+                sb.append(nextEntity(c));
+            } else {
+                sb.append(c);
+            }
+            c = next();
+        }
+    }
+
+
+    /**
+     * Return the next entity. These entities are translated to Characters:
+     *     <code>&amp;  &apos;  &gt;  &lt;  &quot;</code>.
+     * @param ampersand An ampersand character.
+     * @return  A Character or an entity String if the entity is not recognized.
+     * @throws JSONException If missing ';' in XML entity.
+     */
+    public Object nextEntity(char ampersand) throws JSONException {
+        StringBuffer sb = new StringBuffer();
+        for (;;) {
+            char c = next();
+            if (Character.isLetterOrDigit(c) || c == '#') {
+                sb.append(Character.toLowerCase(c));
+            } else if (c == ';') {
+                break;
+            } else {
+                throw syntaxError("Missing ';' in XML entity: &" + sb);
+            }
+        }
+        String string = sb.toString();
+        Object object = entity.get(string);
+        return object != null ? object : ampersand + string + ";";
+    }
+
+
+    /**
+     * Returns the next XML meta token. This is used for skipping over <!...>
+     * and <?...?> structures.
+     * @return Syntax characters (<code>< > / = ! ?</code>) are returned as
+     *  Character, and strings and names are returned as Boolean. We don't care
+     *  what the values actually are.
+     * @throws JSONException If a string is not properly closed or if the XML
+     *  is badly structured.
+     */
+    public Object nextMeta() throws JSONException {
+        char c;
+        char q;
+        do {
+            c = next();
+        } while (Character.isWhitespace(c));
+        switch (c) {
+        case 0:
+            throw syntaxError("Misshaped meta tag");
+        case '<':
+            return XML.LT;
+        case '>':
+            return XML.GT;
+        case '/':
+            return XML.SLASH;
+        case '=':
+            return XML.EQ;
+        case '!':
+            return XML.BANG;
+        case '?':
+            return XML.QUEST;
+        case '"':
+        case '\'':
+            q = c;
+            for (;;) {
+                c = next();
+                if (c == 0) {
+                    throw syntaxError("Unterminated string");
+                }
+                if (c == q) {
+                    return Boolean.TRUE;
+                }
+            }
+        default:
+            for (;;) {
+                c = next();
+                if (Character.isWhitespace(c)) {
+                    return Boolean.TRUE;
+                }
+                switch (c) {
+                case 0:
+                case '<':
+                case '>':
+                case '/':
+                case '=':
+                case '!':
+                case '?':
+                case '"':
+                case '\'':
+                    back();
+                    return Boolean.TRUE;
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Get the next XML Token. These tokens are found inside of angle
+     * brackets. It may be one of these characters: <code>/ > = ! ?</code> or it
+     * may be a string wrapped in single quotes or double quotes, or it may be a
+     * name.
+     * @return a String or a Character.
+     * @throws JSONException If the XML is not well formed.
+     */
+    public Object nextToken() throws JSONException {
+        char c;
+        char q;
+        StringBuffer sb;
+        do {
+            c = next();
+        } while (Character.isWhitespace(c));
+        switch (c) {
+        case 0:
+            throw syntaxError("Misshaped element");
+        case '<':
+            throw syntaxError("Misplaced '<'");
+        case '>':
+            return XML.GT;
+        case '/':
+            return XML.SLASH;
+        case '=':
+            return XML.EQ;
+        case '!':
+            return XML.BANG;
+        case '?':
+            return XML.QUEST;
+
+// Quoted string
+
+        case '"':
+        case '\'':
+            q = c;
+            sb = new StringBuffer();
+            for (;;) {
+                c = next();
+                if (c == 0) {
+                    throw syntaxError("Unterminated string");
+                }
+                if (c == q) {
+                    return sb.toString();
+                }
+                if (c == '&') {
+                    sb.append(nextEntity(c));
+                } else {
+                    sb.append(c);
+                }
+            }
+        default:
+
+// Name
+
+            sb = new StringBuffer();
+            for (;;) {
+                sb.append(c);
+                c = next();
+                if (Character.isWhitespace(c)) {
+                    return sb.toString();
+                }
+                switch (c) {
+                case 0:
+                    return sb.toString();
+                case '>':
+                case '/':
+                case '=':
+                case '!':
+                case '?':
+                case '[':
+                case ']':
+                    back();
+                    return sb.toString();
+                case '<':
+                case '"':
+                case '\'':
+                    throw syntaxError("Bad character in a name");
+                }
+            }
+        }
+    }
+    
+    
+    /**
+     * Skip characters until past the requested string.
+     * If it is not found, we are left at the end of the source with a result of false.
+     * @param to A string to skip past.
+     * @throws JSONException
+     */
+    public boolean skipPast(String to) throws JSONException {
+        boolean b;
+        char c;
+        int i;
+        int j;
+        int offset = 0;
+        int length = to.length();
+        char[] circle = new char[length];
+        
+        /*
+         * First fill the circle buffer with as many characters as are in the
+         * to string. If we reach an early end, bail.
+         */
+        
+        for (i = 0; i < length; i += 1) {
+            c = next();
+            if (c == 0) {
+                return false;
+            }
+            circle[i] = c;
+        }
+        /*
+         * We will loop, possibly for all of the remaining characters.
+         */
+        for (;;) {
+            j = offset;
+            b = true;
+            /*
+             * Compare the circle buffer with the to string. 
+             */
+            for (i = 0; i < length; i += 1) {
+                if (circle[j] != to.charAt(i)) {
+                    b = false;
+                    break;
+                }
+                j += 1;
+                if (j >= length) {
+                    j -= length;
+                }
+            }
+            /*
+             * If we exit the loop with b intact, then victory is ours.
+             */
+            if (b) {
+                return true;
+            }
+            /*
+             * Get the next character. If there isn't one, then defeat is ours.
+             */
+            c = next();
+            if (c == 0) {
+                return false;
+            }
+            /*
+             * Shove the character in the circle buffer and advance the 
+             * circle offset. The offset is mod n.
+             */
+            circle[offset] = c;
+            offset += 1;
+            if (offset >= length) {
+                offset -= length;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eff7f216/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/LogWriter.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/LogWriter.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/LogWriter.java
new file mode 100644
index 0000000..72c9831
--- /dev/null
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/LogWriter.java
@@ -0,0 +1,265 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.geode.tools.pulse.internal.log;
+
+/**
+ * interface LogWriter
+ * 
+ * LogWriter interface for Pulse Logging.
+ * 
+ * @since GemFire 7.0.1
+ * 
+ */
+public interface LogWriter {
+  /**
+   * Returns true if "severe" log messages are enabled. Returns false if
+   * "severe" log messages are disabled.
+   */
+  public boolean severeEnabled();
+
+  /**
+   * Writes both a message and exception to this writer. The message level is
+   * "severe".
+   */
+  public void severe(String msg, Throwable ex);
+
+  /**
+   * Writes a message to this writer. The message level is "severe".
+   */
+  public void severe(String msg);
+
+  /**
+   * Writes an exception to this writer. The exception level is "severe".
+   */
+  public void severe(Throwable ex);
+
+  /**
+   * Returns true if "error" log messages are enabled. Returns false if "error"
+   * log messages are disabled.
+   */
+  // public boolean errorEnabled();
+  /**
+   * Writes both a message and exception to this writer. The message level is
+   * "error".
+   */
+  // public void error(String msg, Throwable ex);
+  /**
+   * Writes a message to this writer. The message level is "error".
+   */
+  // public void error(String msg);
+  /**
+   * Writes an exception to this writer. The exception level is "error".
+   */
+  // public void error(Throwable ex);
+  /**
+   * Returns true if "warning" log messages are enabled. Returns false if
+   * "warning" log messages are disabled.
+   */
+  public boolean warningEnabled();
+
+  /**
+   * Writes both a message and exception to this writer. The message level is
+   * "warning".
+   */
+  public void warning(String msg, Throwable ex);
+
+  /**
+   * Writes a message to this writer. The message level is "warning".
+   */
+  public void warning(String msg);
+
+  /**
+   * Writes an exception to this writer. The exception level is "warning".
+   */
+  public void warning(Throwable ex);
+
+  /**
+   * Returns true if "info" log messages are enabled. Returns false if "info"
+   * log messages are disabled.
+   */
+  public boolean infoEnabled();
+
+  /**
+   * Writes both a message and exception to this writer. The message level is
+   * "information".
+   */
+  public void info(String msg, Throwable ex);
+
+  /**
+   * Writes a message to this writer. The message level is "information".
+   */
+  public void info(String msg);
+
+  /**
+   * Writes an exception to this writer. The exception level is "information".
+   */
+  public void info(Throwable ex);
+
+  /**
+   * Returns true if "config" log messages are enabled. Returns false if
+   * "config" log messages are disabled.
+   */
+  public boolean configEnabled();
+
+  /**
+   * Writes both a message and exception to this writer. The message level is
+   * "config".
+   */
+  public void config(String msg, Throwable ex);
+
+  /**
+   * Writes a message to this writer. The message level is "config".
+   */
+  public void config(String msg);
+
+  /**
+   * Writes an exception to this writer. The exception level is "config".
+   */
+  public void config(Throwable ex);
+
+  /**
+   * Returns true if "fine" log messages are enabled. Returns false if "fine"
+   * log messages are disabled.
+   */
+  public boolean fineEnabled();
+
+  /**
+   * Writes both a message and exception to this writer. The message level is
+   * "fine".
+   */
+  public void fine(String msg, Throwable ex);
+
+  /**
+   * Writes a message to this writer. The message level is "fine".
+   */
+  public void fine(String msg);
+
+  /**
+   * Writes an exception to this writer. The exception level is "fine".
+   */
+  public void fine(Throwable ex);
+
+  /**
+   * Returns true if "finer" log messages are enabled. Returns false if "finer"
+   * log messages are disabled.
+   */
+  public boolean finerEnabled();
+
+  /**
+   * Writes both a message and exception to this writer. The message level is
+   * "finer".
+   */
+  public void finer(String msg, Throwable ex);
+
+  /**
+   * Writes a message to this writer. The message level is "finer".
+   */
+  public void finer(String msg);
+
+  /**
+   * Writes an exception to this writer. The exception level is "finer".
+   */
+  public void finer(Throwable ex);
+
+  /**
+   * Log a method entry.
+   * <p>
+   * The logging is done using the <code>finer</code> level. The string message
+   * will start with <code>"ENTRY"</code> and include the class and method
+   * names.
+   * 
+   * @param sourceClass
+   *          Name of class that issued the logging request.
+   * @param sourceMethod
+   *          Name of the method that issued the logging request.
+   */
+  public void entering(String sourceClass, String sourceMethod);
+
+  /**
+   * Log a method return.
+   * <p>
+   * The logging is done using the <code>finer</code> level. The string message
+   * will start with <code>"RETURN"</code> and include the class and method
+   * names.
+   * 
+   * @param sourceClass
+   *          Name of class that issued the logging request.
+   * @param sourceMethod
+   *          Name of the method that issued the logging request.
+   */
+  public void exiting(String sourceClass, String sourceMethod);
+
+  /**
+   * Log throwing an exception.
+   * <p>
+   * Use to log that a method is terminating by throwing an exception. The
+   * logging is done using the <code>finer</code> level.
+   * <p>
+   * This is a convenience method that could be done instead by calling
+   * {@link #finer(String, Throwable)}. The string message will start with
+   * <code>"THROW"</code> and include the class and method names.
+   * 
+   * @param sourceClass
+   *          Name of class that issued the logging request.
+   * @param sourceMethod
+   *          Name of the method that issued the logging request.
+   * @param thrown
+   *          The Throwable that is being thrown.
+   */
+  public void throwing(String sourceClass, String sourceMethod, Throwable thrown);
+
+  /**
+   * Returns true if "finest" log messages are enabled. Returns false if
+   * "finest" log messages are disabled.
+   */
+  public boolean finestEnabled();
+
+  /**
+   * Writes both a message and exception to this writer. The message level is
+   * "finest".
+   */
+  public void finest(String msg, Throwable ex);
+
+  /**
+   * Writes a message to this writer. The message level is "finest".
+   */
+  public void finest(String msg);
+
+  /**
+   * Writes an exception to this writer. The exception level is "finest".
+   */
+  public void finest(Throwable ex);
+
+  /**
+   * Returns a 1.4 logging handler that can be used to direct application output
+   * to this GemFire logger using the standard JDK logger APIs. Each time this
+   * method is called it creates a new instance of a Handler so care should be
+   * taken to not call this method too often.
+   */
+  // public Handler getHandler();
+
+  /**
+   * A mechanism for accessing the abstraction layer used for
+   * internationalization.
+   * 
+   * @return LogWriterI18n
+   */
+  // public LogWriterI18n convertToLogWriterI18n();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eff7f216/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/MessageFormatter.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/MessageFormatter.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/MessageFormatter.java
new file mode 100644
index 0000000..3828759
--- /dev/null
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/MessageFormatter.java
@@ -0,0 +1,102 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.geode.tools.pulse.internal.log;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+
+import org.apache.geode.tools.pulse.internal.data.PulseConstants;
+import org.apache.geode.tools.pulse.internal.data.Repository;
+
+/**
+ * Class MessageFormatter
+ * 
+ * MessageFormatter is the custom formatter class for formatting the log
+ * messages.
+ * 
+ * @since GemFire version 7.0.1
+ */
+public class MessageFormatter extends Formatter {
+
+  public MessageFormatter() {
+    super();
+  }
+
+  @Override
+  public String format(LogRecord record) {
+    DateFormat df = new SimpleDateFormat(Repository.get().getPulseConfig()
+        .getLogDatePattern());
+    StringWriter sw = new StringWriter();
+    PrintWriter pw = new PrintWriter(sw);
+
+    pw.println();
+    pw.print("[");
+    pw.print(record.getLevel().getName());
+    pw.print(" ");
+    pw.print(df.format(new Date(record.getMillis())));
+    String threadName = Thread.currentThread().getName();
+    if (threadName != null) {
+      pw.print(" ");
+      pw.print(threadName);
+    }
+    pw.print(" tid=0x");
+    pw.print(Long.toHexString(Thread.currentThread().getId()));
+    pw.print("] ");
+    pw.print("(msgTID=");
+    pw.print(record.getThreadID());
+
+    pw.print(" msgSN=");
+    pw.print(record.getSequenceNumber());
+
+    pw.print(") ");
+
+    pw.println("[" + PulseConstants.APP_NAME + "]");
+
+    pw.println("[" + record.getLoggerName() + "]");
+
+    pw.println(record.getMessage());
+
+    if (record.getThrown() != null) {
+      record.getThrown().printStackTrace(pw);
+    }
+    pw.close();
+    try {
+      sw.close();
+    } catch (IOException ignore) {
+    }
+    String result = sw.toString();
+    return result;
+  }
+
+  public String getHead(Handler h) {
+    return super.getHead(h);
+  }
+
+  public String getTail(Handler h) {
+    return super.getTail(h);
+  }
+} // End of Class MessageFormatter

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eff7f216/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/PulseLogWriter.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/PulseLogWriter.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/PulseLogWriter.java
new file mode 100644
index 0000000..901f2f4
--- /dev/null
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/PulseLogWriter.java
@@ -0,0 +1,299 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.geode.tools.pulse.internal.log;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.logging.FileHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.geode.tools.pulse.internal.data.PulseConfig;
+import org.apache.geode.tools.pulse.internal.data.Repository;
+
+/**
+ * Class PulseLogWriter
+ * 
+ * PulseLogWriter is the implementation of LogWriter.
+ * 
+ * @since GemFire 7.0.1
+ * 
+ */
+public class PulseLogWriter implements LogWriter {
+
+  // Log File handle Object
+  private FileHandler fileHandler;
+
+  // Message Formatter Object
+  private static MessageFormatter messageformatter;
+
+  // pulse log writer
+  private static PulseLogWriter pulseLogger = null;
+
+  // Logger Object
+  private Logger logger;
+
+  private PulseLogWriter() {
+    PulseConfig pulseConfig = Repository.get().getPulseConfig();
+    // Create Logger
+    logger = Logger.getLogger(this.getClass().getName());
+
+    // Set minimum log level to level passed
+    logger.setLevel(pulseConfig.getLogLevel());
+
+    try {
+      // Get file handler to log messages into log file.
+      if (fileHandler == null) {
+        fileHandler = new FileHandler(
+            pulseConfig.getLogFileFullName(),
+            pulseConfig.getLogFileSize(),
+            pulseConfig.getLogFileCount(),
+            pulseConfig.getLogAppend());
+
+        // Log Message Formatter
+        messageformatter = new MessageFormatter();
+        fileHandler.setFormatter(messageformatter);
+      }
+
+      // Add File Handler to logger object
+      logger.addHandler(fileHandler);
+    } catch (SecurityException e) {
+      logger.setUseParentHandlers(true);
+      e.printStackTrace();
+    } catch (IOException e) {
+      logger.setUseParentHandlers(true);
+      e.printStackTrace();
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  /**
+   * @param jsonErr
+   * @param errorData
+   */
+  public void logJSONError(Exception jsonErr, Object errorData) {
+
+    // print details of thrown exception and data that couldn't be converted to
+    // json
+    if (this.fineEnabled()) {
+
+      // write errors
+      StringWriter swBuffer = new StringWriter();
+      PrintWriter prtWriter = new PrintWriter(swBuffer);
+      jsonErr.printStackTrace(prtWriter);
+      this.fine("JSON Error Details : " + swBuffer.toString() + "\n");
+
+      this.fine("Erroneous Data : "
+          + ((errorData != null) ? errorData.toString()
+              : "Not Available for output") + "\n");
+    }
+  }
+
+  public static synchronized PulseLogWriter getLogger() {
+    if (null == pulseLogger) {
+      pulseLogger = new PulseLogWriter();
+    }
+    return pulseLogger;
+  }
+
+  @Override
+  public boolean severeEnabled() {
+    return logger.isLoggable(Level.SEVERE);
+  }
+
+  @Override
+  public void severe(String msg, Throwable ex) {
+    logger.logp(Level.SEVERE, "", "", msg, ex);
+  }
+
+  @Override
+  public void severe(String msg) {
+    logger.severe(msg);
+  }
+
+  @Override
+  public void severe(Throwable ex) {
+    logger.logp(Level.SEVERE, "", "", "", ex);
+  }
+
+  /*
+  @Override
+  public boolean errorEnabled() {
+    // TODO Auto-generated method stub
+    return false;
+  }
+
+  @Override
+  public void error(String msg, Throwable ex) {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void error(String msg) {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public void error(Throwable ex) {
+    // TODO Auto-generated method stub
+
+  }
+  */
+
+  @Override
+  public boolean warningEnabled() {
+    return logger.isLoggable(Level.WARNING);
+  }
+
+  @Override
+  public void warning(String msg, Throwable ex) {
+    logger.logp(Level.WARNING, "", "", msg, ex);
+  }
+
+  @Override
+  public void warning(String msg) {
+    logger.warning(msg);
+  }
+
+  @Override
+  public void warning(Throwable ex) {
+    logger.logp(Level.WARNING, "", "", "", ex);
+  }
+
+  @Override
+  public boolean infoEnabled() {
+    return logger.isLoggable(Level.INFO);
+  }
+
+  @Override
+  public void info(String msg, Throwable ex) {
+    logger.logp(Level.INFO, "", "", msg, ex);
+  }
+
+  @Override
+  public void info(String msg) {
+    logger.info(msg);
+  }
+
+  @Override
+  public void info(Throwable ex) {
+    logger.logp(Level.WARNING, "", "", "", ex);
+  }
+
+  @Override
+  public boolean configEnabled() {
+    return logger.isLoggable(Level.CONFIG);
+  }
+
+  @Override
+  public void config(String msg, Throwable ex) {
+    logger.logp(Level.CONFIG, "", "", msg, ex);
+  }
+
+  @Override
+  public void config(String msg) {
+    logger.config(msg);
+  }
+
+  @Override
+  public void config(Throwable ex) {
+    logger.logp(Level.CONFIG, "", "", "", ex);
+  }
+
+  @Override
+  public boolean fineEnabled() {
+    return logger.isLoggable(Level.FINE);
+  }
+
+  @Override
+  public void fine(String msg, Throwable ex) {
+    logger.logp(Level.FINE, "", "", msg, ex);
+  }
+
+  @Override
+  public void fine(String msg) {
+    logger.fine(msg);
+  }
+
+  @Override
+  public void fine(Throwable ex) {
+    logger.logp(Level.FINE, "", "", "", ex);
+  }
+
+  @Override
+  public boolean finerEnabled() {
+    return logger.isLoggable(Level.FINER);
+  }
+
+  @Override
+  public void finer(String msg, Throwable ex) {
+    logger.logp(Level.FINER, "", "", msg, ex);
+  }
+
+  @Override
+  public void finer(String msg) {
+    logger.finer(msg);
+  }
+
+  @Override
+  public void finer(Throwable ex) {
+    logger.logp(Level.FINER, "", "", "", ex);
+  }
+
+  @Override
+  public void entering(String sourceClass, String sourceMethod) {
+    logger.entering(sourceClass, sourceMethod);
+  }
+
+  @Override
+  public void exiting(String sourceClass, String sourceMethod) {
+    logger.exiting(sourceClass, sourceMethod);
+  }
+
+  @Override
+  public void throwing(String sourceClass, String sourceMethod, Throwable thrown) {
+    logger.throwing(sourceClass, sourceMethod, thrown);
+  }
+
+  @Override
+  public boolean finestEnabled() {
+    return logger.isLoggable(Level.FINEST);
+  }
+
+  @Override
+  public void finest(String msg, Throwable ex) {
+    logger.logp(Level.FINEST, "", "", msg, ex);
+  }
+
+  @Override
+  public void finest(String msg) {
+    logger.finest(msg);
+  }
+
+  @Override
+  public void finest(Throwable ex) {
+    logger.logp(Level.FINEST, "", "", "", ex);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eff7f216/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/PulseLogger.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/PulseLogger.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/PulseLogger.java
new file mode 100644
index 0000000..b4f08c1
--- /dev/null
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/log/PulseLogger.java
@@ -0,0 +1,142 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.geode.tools.pulse.internal.log;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.logging.FileHandler;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.apache.geode.tools.pulse.internal.data.PulseConstants;
+
+/**
+ * Class PulseLogger
+ * 
+ * PulseLogger is the custom logger class for Pulse Web Application. It logs
+ * messages to the file in custom format.
+ * 
+ * @since GemFire version 7.0.Beta
+ */
+public class PulseLogger {
+
+  // Pulse Application Log File
+  private static final String LOG_FILE_NAME = PulseConstants.PULSE_LOG_FILE_LOCATION
+      + "/" + PulseConstants.PULSE_LOG_FILE;
+
+  // Date pattern to be used in log messages
+  public static final String LOG_MESSAGE_DATE_PATTERN = "dd/MM/yyyy hh:mm:ss.SSS";
+
+  // The log file size is set to 1MB.
+  public static final int FILE_SIZE = 1024 * 1024;
+
+  // The log file count set to 1 files.
+  public static final int FILE_COUNT = 5;
+
+  // Append logs is set to true.
+  public static final boolean FLAG_APPEND = true;
+
+  // Log File handle Object
+  private static FileHandler fileHandler;
+
+  // Message Formatter Object
+  private static MessageFormatter messageformatter;
+
+  // Logger Object
+  private static Logger logger;
+
+  public static Logger getLogger(String name) {
+    // Create Logger
+    logger = Logger.getLogger(name);
+
+    // Set minimum log level to inform
+    logger.setLevel(Level.INFO);
+
+    // Get file handler to log messages into log file.
+    try {
+      // fileHandler = new FileHandler(LOG_FILE_NAME, FILE_SIZE, FILE_COUNT,
+      // FLAG_APPEND);
+      fileHandler = new FileHandler(LOG_FILE_NAME, FLAG_APPEND);
+
+      // Log Message Formatter
+      messageformatter = new MessageFormatter();
+
+      fileHandler.setFormatter(messageformatter);
+
+      // Add File Handler to logger object
+      logger.addHandler(fileHandler);
+
+    } catch (SecurityException e) {
+      e.printStackTrace();
+    } catch (IOException e) {
+      e.printStackTrace();
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+
+    return logger;
+  }
+
+  /**
+   * Class MessageFormatter
+   * 
+   * MessageFormatter is the custom formatter class for formatting the log
+   * messages.
+   * 
+   * @since GemFire version 7.0.Beta 2012-09-23
+   */
+  private static class MessageFormatter extends Formatter {
+
+    public MessageFormatter() {
+      super();
+    }
+
+    @Override
+    public String format(LogRecord record) {
+      // Set DateFormat
+      DateFormat df = new SimpleDateFormat(PulseLogger.LOG_MESSAGE_DATE_PATTERN);
+      StringBuilder builder = new StringBuilder(1000);
+
+      // Format Log Message
+      builder.append(df.format(new Date(record.getMillis()))).append(" - ");
+      builder.append("[ " + PulseConstants.APP_NAME + " ] - ");
+      builder.append("[").append(record.getSourceClassName()).append(".");
+      builder.append(record.getSourceMethodName()).append("] - ");
+      builder.append("[").append(record.getLevel()).append("] - ");
+      builder.append(formatMessage(record));
+      builder.append(System.getProperty("line.separator"));
+
+      return builder.toString();
+    }
+
+    public String getHead(Handler h) {
+      return super.getHead(h);
+    }
+
+    public String getTail(Handler h) {
+      return super.getTail(h);
+    }
+  } // End of Class MessageFormatter
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eff7f216/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/security/GemFireAuthentication.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/security/GemFireAuthentication.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/security/GemFireAuthentication.java
new file mode 100644
index 0000000..425f5a5
--- /dev/null
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/security/GemFireAuthentication.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geode.tools.pulse.internal.security;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+
+import org.apache.geode.tools.pulse.internal.data.PulseConstants;
+import org.apache.geode.tools.pulse.internal.log.PulseLogWriter;
+
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.SpringSecurityCoreVersion;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+
+/**
+ * Spring security authentication object for GemFire
+ * <p>
+ * To use GemFire Integrated Security Model set Spring Application Profile to pulse.authentication.gemfire
+ * <p>
+ * 1. Authentication :
+ * 1.a GemFire profile creates JMX connection with given credentials at the login time.
+ * 1.b Successful connect is considered as Successful Authentication for Pulse WebApp
+ * <p>
+ * <p>
+ * 2. Authorization :
+ * 2.a Using newly created authenticated connection AccessControlMXBean is called to get authentication
+ * levels. See @See {@link #populateAuthorities(JMXConnector)}. This sets Spring Security Authorities
+ * 2.b DataBrowser end-points are required to be authorized against Spring Granted Authority
+ * @since GemFire version 9.0
+ */
+public class GemFireAuthentication extends UsernamePasswordAuthenticationToken {
+
+  private final static PulseLogWriter logger = PulseLogWriter.getLogger();
+
+  private JMXConnector jmxc = null;
+
+  public GemFireAuthentication(Object principal, Object credentials, Collection<GrantedAuthority> list, JMXConnector jmxc) {
+    super(principal, credentials, list);
+    this.jmxc = jmxc;
+  }
+
+  private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
+
+  public static ArrayList<GrantedAuthority> populateAuthorities(JMXConnector jmxc) {
+    ObjectName name;
+    ArrayList<GrantedAuthority> authorities = new ArrayList<>();
+    try {
+      name = new ObjectName(PulseConstants.OBJECT_NAME_ACCESSCONTROL_MBEAN);
+      MBeanServerConnection mbeanServer = jmxc.getMBeanServerConnection();
+
+      for (String role : PulseConstants.PULSE_ROLES) {
+        Object[] params = role.split(":");
+        String[] signature = new String[] { String.class.getCanonicalName(), String.class.getCanonicalName() };
+        boolean result = (Boolean) mbeanServer.invoke(name, "authorize", params, signature);
+        if (result) {
+          authorities.add(new SimpleGrantedAuthority(role));
+        }
+      }
+    }
+    catch (Exception e) {
+      throw new RuntimeException(e.getMessage(), e);
+    }
+
+    return authorities;
+
+  }
+
+  public JMXConnector getJmxc() {
+    return jmxc;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eff7f216/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/security/GemFireAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/security/GemFireAuthenticationProvider.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/security/GemFireAuthenticationProvider.java
new file mode 100644
index 0000000..f4575cc
--- /dev/null
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/security/GemFireAuthenticationProvider.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geode.tools.pulse.internal.security;
+
+import java.util.Collection;
+import javax.management.remote.JMXConnector;
+
+import org.apache.geode.tools.pulse.internal.data.Repository;
+import org.apache.geode.tools.pulse.internal.log.PulseLogWriter;
+
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.AuthenticationServiceException;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.GrantedAuthority;
+
+/**
+ * Spring security AuthenticationProvider for GemFire. It connects to gemfire manager using given credentials.
+ * Successful connect is treated as successful authentication and web user is authenticated
+ * @since GemFire version 9.0
+ */
+public class GemFireAuthenticationProvider implements AuthenticationProvider {
+
+  private final static PulseLogWriter LOGGER = PulseLogWriter.getLogger();
+
+  public GemFireAuthenticationProvider() {
+    System.out.println("here");
+  }
+
+  @Override
+  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+
+    if (authentication instanceof GemFireAuthentication) {
+      GemFireAuthentication gemAuth = (GemFireAuthentication) authentication;
+      LOGGER.fine("GemAuthentication is connected? = " + gemAuth.getJmxc());
+      if (gemAuth.getJmxc() != null && gemAuth.isAuthenticated()) return gemAuth;
+    }
+
+    String name = authentication.getName();
+    String password = authentication.getCredentials().toString();
+
+    try {
+      LOGGER.fine("Connecting to GemFire with user=" + name);
+      JMXConnector jmxc = Repository.get().getCluster(name, password).connectToGemFire();
+      if (jmxc != null) {
+        Collection<GrantedAuthority> list = GemFireAuthentication.populateAuthorities(jmxc);
+        GemFireAuthentication auth = new GemFireAuthentication(authentication.getPrincipal(),
+            authentication.getCredentials(), list, jmxc);
+        LOGGER.fine("For user " + name + " authList=" + list);
+        return auth;
+      } else {
+        throw new AuthenticationServiceException("JMX Connection unavailable");
+      }
+    } catch (Exception e) {
+      throw new BadCredentialsException("Error connecting to GemFire JMX Server", e);
+    }
+  }
+
+  @Override
+  public boolean supports(Class<?> authentication) {
+    return authentication.equals(UsernamePasswordAuthenticationToken.class);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eff7f216/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/security/LogoutHandler.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/security/LogoutHandler.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/security/LogoutHandler.java
new file mode 100644
index 0000000..451e19a
--- /dev/null
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/security/LogoutHandler.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geode.tools.pulse.internal.security;
+
+import java.io.IOException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.geode.tools.pulse.internal.data.Repository;
+import org.apache.geode.tools.pulse.internal.log.PulseLogWriter;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
+import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
+
+/**
+ * Handler is used to close jmx connection maintained at user-level
+ *
+ */
+public class LogoutHandler extends SimpleUrlLogoutSuccessHandler implements LogoutSuccessHandler {
+
+  public LogoutHandler(String defaultTargetURL) {
+    this.setDefaultTargetUrl(defaultTargetURL);
+  }
+
+  public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
+      throws IOException, ServletException {
+    PulseLogWriter LOGGER = PulseLogWriter.getLogger();
+    LOGGER.fine("Invoked #LogoutHandler ...");
+    if (Repository.get().isUseGemFireCredentials()) {
+      GemFireAuthentication gemauthentication = (GemFireAuthentication) authentication;
+      if(gemauthentication!=null) {
+        gemauthentication.getJmxc().close();
+        LOGGER.info("#LogoutHandler : Closing GemFireAuthentication JMX Connection...");
+      }
+    }
+    super.onLogoutSuccess(request, response, authentication);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eff7f216/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterDetailsService.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterDetailsService.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterDetailsService.java
new file mode 100644
index 0000000..0216cb0
--- /dev/null
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterDetailsService.java
@@ -0,0 +1,104 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.geode.tools.pulse.internal.service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.geode.tools.pulse.internal.data.Cluster;
+import org.apache.geode.tools.pulse.internal.data.PulseConstants;
+import org.apache.geode.tools.pulse.internal.data.Repository;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletRequest;
+import java.text.DecimalFormat;
+
+/**
+ * Class ClusterDetailsService
+ * 
+ * This service class has implementation for providing cluster's basic
+ * statistical data.
+ * 
+ * @since GemFire version 7.5
+ */
+
+@Component
+@Service("ClusterDetails")
+@Scope("singleton")
+public class ClusterDetailsService implements PulseService {
+
+  private final ObjectMapper mapper = new ObjectMapper();
+
+  public ObjectNode execute(final HttpServletRequest request) throws Exception {
+
+    String userName = request.getUserPrincipal().getName();
+
+    // get cluster object
+    Cluster cluster = Repository.get().getCluster();
+
+    // json object to be sent as response
+    ObjectNode responseJSON = mapper.createObjectNode();
+
+    Cluster.Alert[] alertsList = cluster.getAlertsList();
+    int severeAlertCount = 0;
+    int errorAlertCount = 0;
+    int warningAlertCount = 0;
+    int infoAlertCount = 0;
+
+    for (Cluster.Alert alertObj : alertsList) {
+      if (alertObj.getSeverity() == Cluster.Alert.SEVERE) {
+        severeAlertCount++;
+      } else if (alertObj.getSeverity() == Cluster.Alert.ERROR) {
+        errorAlertCount++;
+      } else if (alertObj.getSeverity() == Cluster.Alert.WARNING) {
+        warningAlertCount++;
+      } else {
+        infoAlertCount++;
+      }
+    }
+    // getting basic details of Cluster
+    responseJSON.put("clusterName", cluster.getServerName());
+    responseJSON.put("severeAlertCount", severeAlertCount);
+    responseJSON.put("errorAlertCount", errorAlertCount);
+    responseJSON.put("warningAlertCount", warningAlertCount);
+    responseJSON.put("infoAlertCount", infoAlertCount);
+
+    responseJSON.put("totalMembers", cluster.getMemberCount());
+    responseJSON.put("servers", cluster.getServerCount());
+    responseJSON.put("clients", cluster.getClientConnectionCount());
+    responseJSON.put("locators", cluster.getLocatorCount());
+    responseJSON.put("totalRegions", cluster.getTotalRegionCount());
+    Long heapSize = cluster.getTotalHeapSize();
+
+    DecimalFormat df2 = new DecimalFormat(
+        PulseConstants.DECIMAL_FORMAT_PATTERN);
+    Double heapS = heapSize.doubleValue() / 1024;
+    responseJSON.put("totalHeap", Double.valueOf(df2.format(heapS)));
+    responseJSON.put("functions", cluster.getRunningFunctionCount());
+    responseJSON.put("uniqueCQs", cluster.getRegisteredCQCount());
+    responseJSON.put("subscriptions", cluster.getSubscriptionCount());
+    responseJSON.put("txnCommitted", cluster.getTxnCommittedCount());
+    responseJSON.put("txnRollback", cluster.getTxnRollbackCount());
+    responseJSON.put("userName", userName);
+
+    return responseJSON;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eff7f216/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterDiskThroughputService.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterDiskThroughputService.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterDiskThroughputService.java
new file mode 100644
index 0000000..b50b551
--- /dev/null
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterDiskThroughputService.java
@@ -0,0 +1,71 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.geode.tools.pulse.internal.service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.geode.tools.pulse.internal.data.Cluster;
+import org.apache.geode.tools.pulse.internal.data.Repository;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Class ClusterDiskThroughput This class contains implementations for getting
+ * cluster's current disk throughput details and its trend over time
+ * 
+ * @since GemFire version 7.0.Beta
+ */
+
+@Component
+@Service("ClusterDiskThroughput")
+@Scope("singleton")
+public class ClusterDiskThroughputService implements PulseService {
+
+  private final ObjectMapper mapper = new ObjectMapper();
+
+  public ObjectNode execute(final HttpServletRequest request) throws Exception {
+
+    // get cluster object
+    Cluster cluster = Repository.get().getCluster();
+
+    // json object to be sent as response
+    ObjectNode responseJSON = mapper.createObjectNode();
+
+    // cluster's Throughout Writes trend added to json response object
+    // CircularFifoBuffer throughoutWritesTrend =
+    // cluster.getThroughoutWritesTrend();
+    double currentThroughputWrites = cluster.getDiskWritesRate();
+    double currentThroughputReads = cluster.getDiskReadsRate();
+
+    responseJSON.put("currentThroughputReads", currentThroughputReads);
+    responseJSON.put("throughputReads",
+        mapper.valueToTree(cluster.getStatisticTrend(Cluster.CLUSTER_STAT_THROUGHPUT_READS)));
+
+    responseJSON.put("currentThroughputWrites", currentThroughputWrites);
+    responseJSON.put("throughputWrites",
+        mapper.valueToTree( cluster.getStatisticTrend(Cluster.CLUSTER_STAT_THROUGHPUT_WRITES)));
+
+    // Send json response
+    return responseJSON;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eff7f216/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterGCPausesService.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterGCPausesService.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterGCPausesService.java
new file mode 100644
index 0000000..164e7e3
--- /dev/null
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterGCPausesService.java
@@ -0,0 +1,69 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.geode.tools.pulse.internal.service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.geode.tools.pulse.internal.data.Cluster;
+import org.apache.geode.tools.pulse.internal.data.Repository;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Class ClusterGCPausesService
+ * 
+ * This class contains implementations of getting Cluster's GC Pauses (JVM
+ * Pauses) Details and its trend over the time.
+ * 
+ * @since GemFire version 7.5
+ */
+
+@Component
+@Service("ClusterJVMPauses")
+@Scope("singleton")
+public class ClusterGCPausesService implements PulseService {
+
+  private final ObjectMapper mapper = new ObjectMapper();
+
+  public ObjectNode execute(final HttpServletRequest request) throws Exception {
+
+    // get cluster object
+    Cluster cluster = Repository.get().getCluster();
+
+    // json object to be sent as response
+    ObjectNode responseJSON = mapper.createObjectNode();
+    // cluster's GC Pauses trend added to json response object
+
+    ArrayNode pauses = mapper.createArrayNode();
+    for (Object obj : cluster.getStatisticTrend(Cluster.CLUSTER_STAT_GARBAGE_COLLECTION)) {
+      if (obj instanceof Number) {
+        pauses.add(((Number) obj).longValue());
+      }
+    }
+    responseJSON.put("currentGCPauses", cluster.getGarbageCollectionCount());
+    responseJSON.put("gCPausesTrend", pauses);
+    // Send json response
+    return responseJSON;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eff7f216/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterKeyStatisticsService.java
----------------------------------------------------------------------
diff --git a/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterKeyStatisticsService.java b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterKeyStatisticsService.java
new file mode 100644
index 0000000..9c35a3c
--- /dev/null
+++ b/geode-pulse/src/main/java/org/apache/geode/tools/pulse/internal/service/ClusterKeyStatisticsService.java
@@ -0,0 +1,69 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.geode.tools.pulse.internal.service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.geode.tools.pulse.internal.data.Cluster;
+import org.apache.geode.tools.pulse.internal.data.Repository;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Class ClusterKeyStatisticsService
+ * 
+ * This class contains implementations of getting Cluster's current Reads,
+ * Writes and queries details and their trends over the time.
+ * 
+ * @since GemFire version 7.5
+ */
+
+@Component
+@Service("ClusterKeyStatistics")
+@Scope("singleton")
+public class ClusterKeyStatisticsService implements PulseService {
+
+  private final ObjectMapper mapper = new ObjectMapper();
+
+  public ObjectNode execute(final HttpServletRequest request) throws Exception {
+
+    // get cluster object
+    Cluster cluster = Repository.get().getCluster();
+
+    // json object to be sent as response
+    ObjectNode responseJSON = mapper.createObjectNode();
+
+    responseJSON.put("writePerSecTrend",
+        mapper.valueToTree(cluster.getStatisticTrend(Cluster.CLUSTER_STAT_WRITES_PER_SECOND)));
+
+    responseJSON.put("readPerSecTrend",
+        mapper.valueToTree(cluster.getStatisticTrend(Cluster.CLUSTER_STAT_READ_PER_SECOND)));
+
+    responseJSON.put("queriesPerSecTrend",
+        mapper.valueToTree(cluster.getStatisticTrend(Cluster.CLUSTER_STAT_QUERIES_PER_SECOND)));
+
+    // Send json response
+    return responseJSON;
+
+  }
+}


Mime
View raw message