ace-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ma...@apache.org
Subject svn commit: r1514721 - in /ace/trunk: org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/ org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/ org.apache.ace.repository.itest/ run-server-allinone/ run-server-allinone/conf/
Date Fri, 16 Aug 2013 14:16:57 GMT
Author: marrs
Date: Fri Aug 16 14:16:56 2013
New Revision: 1514721

URL: http://svn.apache.org/r1514721
Log:
ACE-342 Added initial server side code to fetch versions and bundles.

Added:
    ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/AgentDeploymentServlet.java
    ace/trunk/run-server-allinone/conf/org.apache.ace.deployment.servlet.agent.cfg
Modified:
    ace/trunk/org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/DeploymentIntegrationTest.java
    ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/Activator.java
    ace/trunk/org.apache.ace.repository.itest/bnd.bnd
    ace/trunk/run-server-allinone/server-allinone.bndrun

Modified: ace/trunk/org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/DeploymentIntegrationTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/DeploymentIntegrationTest.java?rev=1514721&r1=1514720&r2=1514721&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/DeploymentIntegrationTest.java
(original)
+++ ace/trunk/org.apache.ace.deployment.itest/src/org/apache/ace/it/deployment/DeploymentIntegrationTest.java
Fri Aug 16 14:16:56 2013
@@ -360,7 +360,7 @@ public class DeploymentIntegrationTest e
 
     private void configureServer() throws IOException {
         // configure data bundle
-        configure(org.apache.ace.deployment.servlet.Activator.PID, HttpConstants.ENDPOINT,
"/deployment", "authentication.enabled", "false");
+        configure(org.apache.ace.deployment.servlet.Activator.DEPLOYMENT_PID, HttpConstants.ENDPOINT,
"/deployment", "authentication.enabled", "false");
         // configure file based backend
         configure(org.apache.ace.deployment.provider.filebased.Activator.PID, "BaseDirectoryName",
m_tempDir.getAbsolutePath());
     }

Modified: ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/Activator.java?rev=1514721&r1=1514720&r2=1514721&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/Activator.java
(original)
+++ ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/Activator.java
Fri Aug 16 14:16:56 2013
@@ -20,6 +20,7 @@ package org.apache.ace.deployment.servle
 
 import javax.servlet.Servlet;
 
+import org.apache.ace.connectionfactory.ConnectionFactory;
 import org.apache.ace.deployment.processor.DeploymentProcessor;
 import org.apache.ace.deployment.provider.DeploymentProvider;
 import org.apache.ace.deployment.streamgenerator.StreamGenerator;
@@ -29,19 +30,27 @@ import org.osgi.framework.BundleContext;
 import org.osgi.service.log.LogService;
 
 public class Activator extends DependencyActivatorBase {
-    public static final String PID = "org.apache.ace.deployment.servlet";
+    public static final String DEPLOYMENT_PID = "org.apache.ace.deployment.servlet";
+    public static final String AGENT_PID = "org.apache.ace.deployment.servlet.agent";
 
     @Override
     public void init(BundleContext context, DependencyManager manager) throws Exception {
         manager.add(createComponent()
             .setInterface(Servlet.class.getName(), null)
             .setImplementation(DeploymentServlet.class)
-            .add(createConfigurationDependency().setPropagate(true).setPid(PID))
+            .add(createConfigurationDependency().setPropagate(true).setPid(DEPLOYMENT_PID))
             .add(createServiceDependency().setService(StreamGenerator.class).setRequired(true))
             .add(createServiceDependency().setService(DeploymentProvider.class).setRequired(true))
             .add(createServiceDependency().setService(DeploymentProcessor.class).setRequired(false).setCallbacks("addProcessor",
"removeProcessor"))
             .add(createServiceDependency().setService(LogService.class).setRequired(false))
         );
+        manager.add(createComponent()
+            .setInterface(Servlet.class.getName(), null)
+            .setImplementation(AgentDeploymentServlet.class)
+            .add(createConfigurationDependency().setPropagate(true).setPid(AGENT_PID))
+            .add(createServiceDependency().setService(ConnectionFactory.class).setRequired(true))
+            .add(createServiceDependency().setService(LogService.class).setRequired(false))
+        );
     }
 
     @Override

Added: ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/AgentDeploymentServlet.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/AgentDeploymentServlet.java?rev=1514721&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/AgentDeploymentServlet.java
(added)
+++ ace/trunk/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/AgentDeploymentServlet.java
Fri Aug 16 14:16:56 2013
@@ -0,0 +1,333 @@
+/*
+ * 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.ace.deployment.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.ace.authentication.api.AuthenticationService;
+import org.apache.ace.connectionfactory.ConnectionFactory;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.Version;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.log.LogService;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+public class AgentDeploymentServlet extends HttpServlet implements ManagedService {
+    private static final int BUFFER_SIZE = 1024 * 32;
+    /** A boolean denoting whether or not authentication is enabled. */
+    private static final String KEY_USE_AUTHENTICATION = "authentication.enabled";
+    /** URL to the OBR that is used for finding versions of the agent. */
+    private static final String KEY_OBR_URL = "obr.url";
+
+    public static final String VERSIONS = "versions";
+    public static final String BUNDLE_MIMETYPE = "application/octet-stream";
+    public static final String TEXT_MIMETYPE = "text/plain";
+    
+    // injected by Dependency Manager
+    private volatile DependencyManager m_dm; 
+    private volatile LogService m_log;
+    private volatile AuthenticationService m_authService;
+    private volatile ConnectionFactory m_connectionFactory;
+
+    private volatile boolean m_useAuth = false;
+    private static final String XPATH_QUERY = "/repository/resource[@uri]";
+    private final String m_repositoryXML = "repository.xml";
+    private URL m_obrURL;
+    
+
+    @Override
+    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
+        try {
+            String[] pathElements = verifyAndGetPathElements(request.getPathInfo());
+            String targetID = pathElements[1]; // in the future we might use this for per
target approval
+            String agentID = pathElements[2];
+            int numberOfElements = pathElements.length;
+            if (numberOfElements == 4) {
+                handleVersionsRequest(getVersions(agentID), response);
+            }
+            else {
+                handlePackageDelivery(agentID, new Version(pathElements[4]), request, response);
+            }
+        }
+        catch (AceRestException e) {
+            m_log.log(LogService.LOG_WARNING, e.getMessage(), e);
+            e.handleAsHttpError(response);
+        }
+    }
+    
+    private String[] verifyAndGetPathElements(String path) throws AceRestException {
+        if (path == null) {
+            throw new AceRestException(HttpServletResponse.SC_BAD_REQUEST, "Request URI is
invalid, no path specified.");
+        }
+        String[] elements = path.split("/");
+        int numberOfElements = elements.length;
+        if ((numberOfElements < 4) || (numberOfElements > 5) || !VERSIONS.equals(elements[3]))
{
+            throw new AceRestException(HttpServletResponse.SC_BAD_REQUEST, "Request URI elements
are invalid: " + path);
+        }
+        return elements;
+    }
+
+    private List<Version> getVersions(String agentID) throws AceRestException {
+        try {
+            return getVersionsFromOBR(m_obrURL, agentID);
+        }
+        catch (XPathExpressionException e) {
+            throw new AceRestException(HttpServletResponse.SC_NOT_FOUND, "Unknown agent ("
+ agentID + ")");
+        }
+        catch (IOException ioe) {
+            m_log.log(LogService.LOG_WARNING, "Error getting available versions.", ioe);
+            throw new AceRestException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error
getting available versions.");
+        }
+    }
+
+    private List<Version> getVersionsFromOBR(URL obrBaseUrl, String agentID) throws
XPathExpressionException, IOException {
+        InputStream input = null;
+        NodeList resources = getOBRNodeList(input);
+        List<Version> obrList = new ArrayList<Version>();
+        for (int nResource = 0; nResource < resources.getLength(); nResource++) {
+            Node resource = resources.item(nResource);
+            NamedNodeMap attr = resource.getAttributes();
+
+            String uri = getNamedItemText(attr, "uri");
+            if (uri == null || uri.equals("")) {
+                m_log.log(LogService.LOG_ERROR, "Skipping resource without uri from repository
" + obrBaseUrl);
+                continue;
+            }
+
+            String symbolicname = getNamedItemText(attr, "symbolicname");
+            if (agentID.equals(symbolicname)) {
+                Version version = new Version(getNamedItemText(attr, "version"));
+                obrList.add(version);
+            }
+        }
+        Collections.sort(obrList);
+        return obrList;
+    }
+    private InputStream getAgentFromOBR(URL obrBaseUrl, String agentID, Version version)
throws XPathExpressionException, IOException {
+        InputStream input = null;
+        NodeList resources = getOBRNodeList(input);
+        for (int nResource = 0; nResource < resources.getLength(); nResource++) {
+            Node resource = resources.item(nResource);
+            NamedNodeMap attr = resource.getAttributes();
+
+            String uri = getNamedItemText(attr, "uri");
+            if (uri == null || uri.equals("")) {
+                m_log.log(LogService.LOG_ERROR, "Skipping resource without uri from repository
" + obrBaseUrl);
+                continue;
+            }
+
+            String symbolicname = getNamedItemText(attr, "symbolicname");
+            Version bundleVersion = new Version(getNamedItemText(attr, "version"));
+            if (agentID.equals(symbolicname) && version.equals(bundleVersion)) {
+                URL url = new URL(obrBaseUrl, getNamedItemText(attr, "uri"));
+                URLConnection connection = openConnection(url);
+                return connection.getInputStream();
+            }
+        }
+        return null;
+    }
+
+    private NodeList getOBRNodeList(InputStream input) throws XPathExpressionException, IOException
{
+        NodeList resources;
+        try {
+            URLConnection connection = openConnection(createOBRURL());
+            // We always want the newest repository.xml file.
+            connection.setUseCaches(false);
+
+            input = connection.getInputStream();
+
+            try {
+                XPath xpath = XPathFactory.newInstance().newXPath();
+                // this XPath expressing will find all 'resource' elements which
+                // have an attribute 'uri'.
+                resources = (NodeList) xpath.evaluate(XPATH_QUERY, new InputSource(input),
XPathConstants.NODESET);
+            }
+            catch (XPathExpressionException e) {
+                m_log.log(LogService.LOG_ERROR, "Error evaluating XPath expression.", e);
+                throw e;
+            }
+        }
+        catch (IOException e) {
+            m_log.log(LogService.LOG_ERROR, "Error reading repository metadata.", e);
+            throw e;
+        }
+        finally {
+            if (input != null) {
+                try {
+                    input.close();
+                }
+                catch (IOException e) {
+                    // too bad, no worries.
+                }
+            }
+        }
+        return resources;
+    }
+
+    private URL createOBRURL() throws MalformedURLException {
+        try {
+            return new URL(m_obrURL, m_repositoryXML);
+        }
+        catch (MalformedURLException e) {
+            m_log.log(LogService.LOG_ERROR, "Error retrieving repository.xml from " + m_obrURL);
+            throw e;
+        }
+    }
+    protected URLConnection openConnection(URL url) throws IOException {
+        return m_connectionFactory.createConnection(url);
+    }
+    /**
+     * Gets the actual text from a named item contained in the given node map.
+     * 
+     * @param map the node map to get the named item from;
+     * @param name the name of the item to get.
+     * @return the text of the named item, can be <code>null</code> in case the
named item does not exist, or has no text.
+     */
+    private static String getNamedItemText(NamedNodeMap map, String name) {
+        Node namedItem = map.getNamedItem(name);
+        if (namedItem == null) {
+            return null;
+        }
+        else {
+            return namedItem.getTextContent();
+        }
+    }
+    
+    private void handleVersionsRequest(List<Version> versions, HttpServletResponse
response) throws AceRestException {
+        ServletOutputStream output = null;
+
+        response.setContentType(TEXT_MIMETYPE);
+        try {
+            output = response.getOutputStream();
+            for (Version version : versions) {
+                output.print(version.toString());
+                output.print("\n");
+            }
+        }
+        catch (IOException e) {
+            throw new AceRestException(HttpServletResponse.SC_BAD_REQUEST, "Request URI is
invalid");
+        }
+        finally {
+            tryClose(output);
+        }
+    }
+
+    private void handlePackageDelivery(final String agentID, final Version version, final
HttpServletRequest request, final HttpServletResponse response) throws AceRestException {
+        ServletOutputStream output = null;
+
+        try {
+            InputStream inputStream = null;
+            try {
+                inputStream = getAgentFromOBR(m_obrURL, agentID, version);
+                if (inputStream == null) {
+                    throw (AceRestException) new AceRestException(HttpServletResponse.SC_NOT_FOUND,
"Agent not found in OBR.");
+                }
+            }
+            catch (XPathExpressionException e) {
+                throw (AceRestException) new AceRestException(HttpServletResponse.SC_NOT_FOUND,
"Agent not found: error parsing OBR").initCause(e);
+            }
+            finally {
+                if (inputStream != null) {
+                    inputStream.close();
+                }
+            }
+            response.setContentType(BUNDLE_MIMETYPE);
+            output = response.getOutputStream();
+            byte[] buffer = new byte[BUFFER_SIZE];
+            int bytes;
+            while ((bytes = inputStream.read(buffer)) != -1) {
+                output.write(buffer, 0, bytes);
+            }
+        }
+        catch (IllegalArgumentException e) {
+            throw (AceRestException) new AceRestException(HttpServletResponse.SC_BAD_REQUEST,
"Request URI is invalid").initCause(e);
+        }
+        catch (IOException e) {
+            throw (AceRestException) new AceRestException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Could not deliver package").initCause(e);
+        }
+        finally {
+            tryClose(output);
+        }
+    }
+
+    private void tryClose(OutputStream output) {
+        try {
+            if (output != null) {
+                output.close();
+            }
+        }
+        catch (IOException e) {
+            m_log.log(LogService.LOG_WARNING, "Exception trying to close stream after request.
", e);
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void updated(Dictionary settings) throws ConfigurationException {
+        if (settings != null) {
+            String useAuthString = (String) settings.get(KEY_USE_AUTHENTICATION);
+            if (useAuthString == null
+                || !("true".equalsIgnoreCase(useAuthString) || "false".equalsIgnoreCase(useAuthString)))
{
+                throw new ConfigurationException(KEY_USE_AUTHENTICATION, "Missing or invalid
value!");
+            }
+            boolean useAuth = Boolean.parseBoolean(useAuthString);
+            m_useAuth = useAuth;
+            
+            String obrURL = (String) settings.get(KEY_OBR_URL);
+            try {
+                URL url = new URL(obrURL);
+                m_obrURL = url;
+            }
+            catch (MalformedURLException e) {
+                throw new ConfigurationException(KEY_OBR_URL, "Invalid value, not a URL.",
e);
+            }
+            if (obrURL == null) {
+                throw new ConfigurationException(KEY_OBR_URL, "Missing " +
+                		"value!");
+            }
+        }
+        else {
+            m_useAuth = false;
+            m_obrURL = null;
+        }
+    }
+}

Modified: ace/trunk/org.apache.ace.repository.itest/bnd.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.repository.itest/bnd.bnd?rev=1514721&r1=1514720&r2=1514721&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.repository.itest/bnd.bnd (original)
+++ ace/trunk/org.apache.ace.repository.itest/bnd.bnd Fri Aug 16 14:16:56 2013
@@ -11,8 +11,7 @@ Test-Cases: ${classes;CONCRETE;EXTENDS;o
 	org.apache.felix.dependencymanager		
 -runfw: org.apache.felix.framework;version='[4,5)'
 -runvm: -ea
--runbundles: \
-	osgi.cmpn,\
+-runbundles: osgi.cmpn,\
 	org.apache.felix.log,\
 	org.apache.felix.dependencymanager,\
 	org.apache.felix.configadmin,\
@@ -25,7 +24,11 @@ Test-Cases: ${classes;CONCRETE;EXTENDS;o
 	org.apache.ace.range.api;version=latest,\
 	org.apache.ace.repository.api;version=latest,\
 	org.apache.ace.repository.impl;version=latest,\
-	org.apache.ace.repository.servlet;version=latest
+	org.apache.ace.repository.servlet;version=latest,\
+	org.apache.felix.gogo.command,\
+	org.apache.felix.gogo.runtime,\
+	org.apache.felix.gogo.shell,\
+	org.apache.felix.dependencymanager.shell
 Private-Package: org.apache.ace.it.repository
 Bundle-Version: 1.0.0
 Bundle-Name: Apache ACE Repository itest

Added: ace/trunk/run-server-allinone/conf/org.apache.ace.deployment.servlet.agent.cfg
URL: http://svn.apache.org/viewvc/ace/trunk/run-server-allinone/conf/org.apache.ace.deployment.servlet.agent.cfg?rev=1514721&view=auto
==============================================================================
--- ace/trunk/run-server-allinone/conf/org.apache.ace.deployment.servlet.agent.cfg (added)
+++ ace/trunk/run-server-allinone/conf/org.apache.ace.deployment.servlet.agent.cfg Fri Aug
16 14:16:56 2013
@@ -0,0 +1,4 @@
+org.apache.ace.server.servlet.endpoint=/agent
+# OBR settings
+obr.url = http://localhost:${org.apache.ace.server.port}/obr/
+authentication.enabled = false

Modified: ace/trunk/run-server-allinone/server-allinone.bndrun
URL: http://svn.apache.org/viewvc/ace/trunk/run-server-allinone/server-allinone.bndrun?rev=1514721&r1=1514720&r2=1514721&view=diff
==============================================================================
--- ace/trunk/run-server-allinone/server-allinone.bndrun (original)
+++ ace/trunk/run-server-allinone/server-allinone.bndrun Fri Aug 16 14:16:56 2013
@@ -73,4 +73,4 @@
 	org.apache.felix.log.maxSize=1000,\
 	launch.keep=true,\
 	launch.storage.dir=bundle-cache
--runvm: -Xmx1G
\ No newline at end of file
+-runvm: -Xmx1G -agentpath:/Applications/YourKit_Java_Profiler_12.0.5.app/bin/mac/libyjpagent.jnilib
\ No newline at end of file



Mime
View raw message