You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2013/06/28 20:11:06 UTC

svn commit: r1497865 - in /sling/trunk/contrib/extensions/healthcheck: hc-sling/src/main/java/org/apache/sling/hc/sling/impl/ hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/ sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/

Author: bdelacretaz
Date: Fri Jun 28 18:11:06 2013
New Revision: 1497865

URL: http://svn.apache.org/r1497865
Log:
SLING-2822 - RequestStatusRuleBuilder added, checks the status of Sling requests

Added:
    sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/InternalRequest.java   (with props)
    sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/InternalResponse.java   (with props)
    sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/RequestStatusRuleBuilder.java   (with props)
    sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/sling-requests-status.json   (with props)
Modified:
    sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/HtmlResultRendererImpl.java

Modified: sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/HtmlResultRendererImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/HtmlResultRendererImpl.java?rev=1497865&r1=1497864&r2=1497865&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/HtmlResultRendererImpl.java (original)
+++ sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/HtmlResultRendererImpl.java Fri Jun 28 18:11:06 2013
@@ -73,19 +73,18 @@ public class HtmlResultRendererImpl impl
                 dataRow(c, "Info", sb.toString());
             }
             
-            if(r.anythingToReport()) {
-                final StringBuilder sb = new StringBuilder();
-                for(EvaluationResult.LogMessage msg : r.getLogMessages()) {
-                    sb.append("<div class='log").append(msg.getLevel().toString()).append("'>");
-                    sb.append(msg.getLevel().toString())
-                    .append(" ")
-                    .append(ResponseUtil.escapeXml(msg.getMessage()))
-                    .append("</div>");
-                }
-                dataRow(c, "Log", sb.toString());
-            } else {
-                dataRow(c, "Log", "<span class='nothingToReport'>Nothing to report</a>");
+            final StringBuilder sb = new StringBuilder();
+            if(!r.anythingToReport()) {
+                sb.append("<div class='nothingToReport'>Nothing to report</div>");
             }
+            for(EvaluationResult.LogMessage msg : r.getLogMessages()) {
+                sb.append("<div class='log").append(msg.getLevel().toString()).append("'>");
+                sb.append(msg.getLevel().toString())
+                .append(" ")
+                .append(ResponseUtil.escapeXml(msg.getMessage()))
+                .append("</div>");
+            }
+            dataRow(c, "Log", sb.toString());
         }
         pw.println("</table>");
     }

Added: sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/InternalRequest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/InternalRequest.java?rev=1497865&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/InternalRequest.java (added)
+++ sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/InternalRequest.java Fri Jun 28 18:11:06 2013
@@ -0,0 +1,317 @@
+/*
+ * 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 SF 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.sling.hc.sling.impl.rules;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+public class InternalRequest implements HttpServletRequest {
+
+    private final String path;
+    
+    public InternalRequest(String path) {
+        this.path = path;
+    }
+    
+    @Override
+    public Object getAttribute(String arg0) {
+        return null;
+    }
+
+    @Override
+    public Enumeration<?> getAttributeNames() {
+        return null;
+    }
+
+    @Override
+    public String getCharacterEncoding() {
+        return "UTF-8";
+    }
+
+    @Override
+    public int getContentLength() {
+        return 0;
+    }
+
+    @Override
+    public String getContentType() {
+        return "text/plain";
+    }
+
+    @Override
+    public ServletInputStream getInputStream() throws IOException {
+        return new ServletInputStream() {
+            @Override
+            public int read() throws IOException {
+                return 0;
+            }
+        };
+    }
+
+    @Override
+    public String getLocalAddr() {
+        return "127.0.0.1";
+    }
+
+    @Override
+    public String getLocalName() {
+        return "localhost";
+    }
+
+    @Override
+    public int getLocalPort() {
+        return 0;
+    }
+
+    @Override
+    public Locale getLocale() {
+        return Locale.getDefault();
+    }
+
+    @Override
+    public Enumeration<?> getLocales() {
+        return new Vector<Locale>().elements();
+    }
+
+    @Override
+    public String getParameter(String arg0) {
+        return null;
+    }
+
+    @Override
+    public Map<?,?> getParameterMap() {
+        return new HashMap<String, Object>();
+    }
+
+    @Override
+    public Enumeration<?> getParameterNames() {
+        return new Vector<String>().elements();
+    }
+
+    @Override
+    public String[] getParameterValues(String arg0) {
+        return null;
+    }
+
+    @Override
+    public String getProtocol() {
+        return "http";
+    }
+
+    @Override
+    public BufferedReader getReader() throws IOException {
+        return new BufferedReader(new StringReader(""));
+    }
+
+    @Override
+    public String getRealPath(String arg0) {
+        return path;
+    }
+
+    @Override
+    public String getRemoteAddr() {
+        return "127.0.0.1";
+    }
+
+    @Override
+    public String getRemoteHost() {
+        return "localhost";
+    }
+
+    @Override
+    public int getRemotePort() {
+        return 1234;
+    }
+
+    @Override
+    public RequestDispatcher getRequestDispatcher(String arg0) {
+        return null;
+    }
+
+    @Override
+    public String getScheme() {
+        return "http";
+    }
+
+    @Override
+    public String getServerName() {
+        return "localhost";
+    }
+
+    @Override
+    public int getServerPort() {
+        return 80;
+    }
+
+    @Override
+    public boolean isSecure() {
+        return false;
+    }
+
+    @Override
+    public void removeAttribute(String arg0) {
+    }
+
+    @Override
+    public void setAttribute(String arg0, Object arg1) {
+    }
+
+    @Override
+    public void setCharacterEncoding(String arg0)
+            throws UnsupportedEncodingException {
+    }
+
+    @Override
+    public String getAuthType() {
+        return null;
+    }
+
+    @Override
+    public String getContextPath() {
+        return "";
+    }
+
+    @Override
+    public Cookie[] getCookies() {
+        return null;
+    }
+
+    @Override
+    public long getDateHeader(String arg0) {
+        return 0;
+    }
+
+    @Override
+    public String getHeader(String arg0) {
+        return null;
+    }
+
+    @Override
+    public Enumeration<?> getHeaderNames() {
+        return new Vector<String>().elements();
+    }
+
+    @Override
+    public Enumeration<?> getHeaders(String arg0) {
+        return new Vector<String>().elements();
+    }
+
+    @Override
+    public int getIntHeader(String arg0) {
+        return 0;
+    }
+
+    @Override
+    public String getMethod() {
+        return "GET";
+    }
+
+    @Override
+    public String getPathInfo() {
+        return path;
+    }
+
+    @Override
+    public String getPathTranslated() {
+        return path;
+    }
+
+    @Override
+    public String getQueryString() {
+        return "";
+    }
+
+    @Override
+    public String getRemoteUser() {
+        return "remoteuser";
+    }
+
+    @Override
+    public String getRequestURI() {
+        return "http://localhost" + path;
+    }
+
+    @Override
+    public StringBuffer getRequestURL() {
+        return new StringBuffer(getRequestURI());
+    }
+
+    @Override
+    public String getRequestedSessionId() {
+        return "";
+    }
+
+    @Override
+    public String getServletPath() {
+        return "";
+    }
+
+    @Override
+    public HttpSession getSession() {
+        return null;
+    }
+
+    @Override
+    public HttpSession getSession(boolean arg0) {
+        return null;
+    }
+
+    @Override
+    public Principal getUserPrincipal() {
+        return null;
+    }
+
+    @Override
+    public boolean isRequestedSessionIdFromCookie() {
+        return false;
+    }
+
+    @Override
+    public boolean isRequestedSessionIdFromURL() {
+        return false;
+    }
+
+    @Override
+    public boolean isRequestedSessionIdFromUrl() {
+        return false;
+    }
+
+    @Override
+    public boolean isRequestedSessionIdValid() {
+        return false;
+    }
+
+    @Override
+    public boolean isUserInRole(String arg0) {
+        return false;
+    }
+}

Propchange: sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/InternalRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/InternalRequest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/InternalResponse.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/InternalResponse.java?rev=1497865&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/InternalResponse.java (added)
+++ sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/InternalResponse.java Fri Jun 28 18:11:06 2013
@@ -0,0 +1,185 @@
+/*
+ * 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 SF 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.sling.hc.sling.impl.rules;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Locale;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+public class InternalResponse implements HttpServletResponse {
+
+    private int status = 200;
+    
+    private static class DevNullOutputStream extends ServletOutputStream {
+        @Override
+        public void write(int b) {
+        }
+    }
+    
+    @Override
+    public void flushBuffer() throws IOException {
+    }
+
+    @Override
+    public int getBufferSize() {
+        return 0;
+    }
+
+    @Override
+    public String getCharacterEncoding() {
+        return "UTF-8";
+    }
+
+    @Override
+    public String getContentType() {
+        return "text/plain";
+    }
+
+    @Override
+    public Locale getLocale() {
+        return Locale.getDefault();
+    }
+
+    @Override
+    public ServletOutputStream getOutputStream() throws IOException {
+        return new DevNullOutputStream();
+    }
+
+    @Override
+    public PrintWriter getWriter() throws IOException {
+        return new PrintWriter(new DevNullOutputStream());
+    }
+
+    @Override
+    public boolean isCommitted() {
+        return false;
+    }
+
+    @Override
+    public void reset() {
+    }
+
+    @Override
+    public void resetBuffer() {
+    }
+
+    @Override
+    public void setBufferSize(int arg0) {
+    }
+
+    @Override
+    public void setCharacterEncoding(String arg0) {
+    }
+
+    @Override
+    public void setContentLength(int arg0) {
+    }
+
+    @Override
+    public void setContentType(String arg0) {
+    }
+
+    @Override
+    public void setLocale(Locale arg0) {
+    }
+
+    @Override
+    public void addCookie(Cookie arg0) {
+    }
+
+    @Override
+    public void addDateHeader(String arg0, long arg1) {
+    }
+
+    @Override
+    public void addHeader(String arg0, String arg1) {
+    }
+
+    @Override
+    public void addIntHeader(String arg0, int arg1) {
+    }
+
+    @Override
+    public boolean containsHeader(String arg0) {
+        return false;
+    }
+
+    @Override
+    public String encodeRedirectURL(String url) {
+        return url;
+    }
+
+    @Override
+    public String encodeRedirectUrl(String url) {
+        return url;
+    }
+
+    @Override
+    public String encodeURL(String url) {
+        return url;
+    }
+
+    @Override
+    public String encodeUrl(String url) {
+        return url;
+    }
+
+    @Override
+    public void sendError(int s, String arg1) throws IOException {
+        status = s;
+    }
+
+    @Override
+    public void sendError(int s) throws IOException {
+        status = s;
+    }
+
+    @Override
+    public void sendRedirect(String arg0) throws IOException {
+    }
+
+    @Override
+    public void setDateHeader(String arg0, long arg1) {
+    }
+
+    @Override
+    public void setHeader(String arg0, String arg1) {
+    }
+
+    @Override
+    public void setIntHeader(String arg0, int arg1) {
+    }
+
+    @Override
+    public void setStatus(int s, String arg1) {
+        status = s;
+    }
+
+    @Override
+    public void setStatus(int s) {
+        status = s;
+    }
+    
+    public int getStatus() {
+        return status;
+    }
+}

Propchange: sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/InternalResponse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/InternalResponse.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/RequestStatusRuleBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/RequestStatusRuleBuilder.java?rev=1497865&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/RequestStatusRuleBuilder.java (added)
+++ sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/RequestStatusRuleBuilder.java Fri Jun 28 18:11:06 2013
@@ -0,0 +1,121 @@
+/*
+ * 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 SF 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.sling.hc.sling.impl.rules;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.engine.SlingRequestProcessor;
+import org.apache.sling.hc.api.Rule;
+import org.apache.sling.hc.api.RuleBuilder;
+import org.apache.sling.hc.api.SystemAttribute;
+import org.slf4j.Logger;
+
+/** Creates {@link Rule} to check specified Sling URLs for an
+ *  ok (or other) status. Can be supplied with a comma-separated
+ *  list of paths (in the rule qualifier) and returns the highest
+ *  status in that case.
+ */
+@Component
+@Service(value=RuleBuilder.class)
+public class RequestStatusRuleBuilder implements RuleBuilder {
+
+    public static final String NAMESPACE = "sling";
+    public static final String RULE_NAME = "request.status";
+    
+    @Reference
+    private SlingRequestProcessor requestProcessor;
+    
+    @Reference
+    private ResourceResolverFactory resolverFactory; 
+    
+    private class RequestStatusSystemAttribute implements SystemAttribute {
+
+        private final List<String> paths;
+        
+        RequestStatusSystemAttribute(List<String> paths) {
+            this.paths = paths;
+        }
+        
+        @Override
+        public String toString() {
+            final StringBuilder sb = new StringBuilder();
+            sb.append(getClass().getSimpleName());
+            if(paths.size() <= 3) {
+                sb.append(", paths=").append(paths);
+            } else {
+                sb.append(", ").append(paths.size()).append(" paths to check");
+            }
+            return sb.toString();
+        }
+        
+        @Override
+        public Object getValue(Logger logger) {
+            ResourceResolver resolver = null;
+            int maxStatus = 0;
+            int checked = 0;
+            
+            try {
+                // TODO for new all requests are made as admin
+                resolver = resolverFactory.getAdministrativeResourceResolver(null);
+                for(String path : paths) {
+                    final HttpServletRequest request = new InternalRequest(path);
+                    final InternalResponse response = new InternalResponse();
+                    requestProcessor.processRequest(request, response, resolver);
+                    final int status = response.getStatus();
+                    logger.debug("{} returns status {}", path, status);
+                    checked++;
+                    maxStatus = Math.max(maxStatus, status);
+                }
+            } catch(Exception e) {
+                logger.error("Exception while executing request", e);
+            } finally {
+                if(resolver != null) {
+                    resolver.close();
+                }
+            }
+            
+            if(checked == 0) {
+                logger.error("No paths checked, empty paths list?");
+            }
+            
+            return maxStatus;
+        }
+    }
+    
+    @Override
+    public Rule buildRule(String namespace, String ruleName, String qualifier, String expression) {
+        if(!NAMESPACE.equals(namespace) || !RULE_NAME.equals(ruleName) || qualifier == null) {
+            return null;
+        }
+        
+        final List<String> pathList = new LinkedList<String>();
+        for(String p : qualifier.split(",")) {
+            pathList.add(p.trim());
+        }
+        
+        return new Rule(new RequestStatusSystemAttribute(pathList), expression);
+    }
+}

Propchange: sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/RequestStatusRuleBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/healthcheck/hc-sling/src/main/java/org/apache/sling/hc/sling/impl/rules/RequestStatusRuleBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/sling-requests-status.json
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/sling-requests-status.json?rev=1497865&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/sling-requests-status.json (added)
+++ sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/sling-requests-status.json Fri Jun 28 18:11:06 2013
@@ -0,0 +1,11 @@
+{
+  "expression": "200",
+  "ruleName": "request.status",
+  "sling:resourceType": "sling/healthcheck/rules",
+  "namespace": "sling",
+  "tags": [
+    "sling"
+  ],
+  "jcr:primaryType": "nt:unstructured",
+  "qualifier": "/index.html,/apps.json,/.explorer.html"
+}

Propchange: sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/sling-requests-status.json
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/healthcheck/sling-demo/src/main/resources/SLING-CONTENT/apps/hc/demo/sling-requests-status.json
------------------------------------------------------------------------------
    svn:executable = *