You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by kw...@apache.org on 2019/12/20 17:14:21 UTC

[sling-org-apache-sling-installer-console] 01/01: SLING-8897 dedicated console for serializing configurations

This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch feature/config-serializer
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-console.git

commit 1e862c05d3169cc1f449f919c19b3050f46eecfe
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Fri Dec 20 18:14:05 2019 +0100

    SLING-8897 dedicated console for serializing configurations
    
    Update to parent 35
---
 pom.xml                                            |  71 ++++----
 .../ConfigurationSerializerWebConsolePlugin.java   | 195 +++++++++++++++++++++
 2 files changed, 236 insertions(+), 30 deletions(-)

diff --git a/pom.xml b/pom.xml
index 011c683..04b1435 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,35 +1,35 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
     Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
+    or more contributor license agreements. See the NOTICE file
     distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
+    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
-    
+    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
+    KIND, either express or implied. See the License for the
     specific language governing permissions and limitations
     under the License.
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.sling</groupId>
-        <artifactId>sling</artifactId>
-        <version>30</version>
-        <relativePath />
+        <artifactId>sling-bundle-parent</artifactId>
+        <version>35</version>
+        <relativePath/>
     </parent>
 
     <artifactId>org.apache.sling.installer.console</artifactId>
     <version>1.0.3-SNAPSHOT</version>
-    <packaging>bundle</packaging>
 
     <name>Apache Sling Installer WebConsole Plugin</name>
     <description> 
@@ -42,37 +42,48 @@
         <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-installer-console.git</url>
     </scm>
 
-	<build>
-		<plugins>
-			<plugin>
-				<groupId>org.apache.felix</groupId>
-				<artifactId>maven-bundle-plugin</artifactId>
-				<extensions>true</extensions>
-				<configuration>
-					<instructions>
-						<Private-Package>
-						    org.apache.sling.installer.core.impl.console
-						</Private-Package>
-					</instructions>
-				</configuration>
-			</plugin>
-		</plugins>
-	</build>
-
     <dependencies>
         <dependency>
             <groupId>org.osgi</groupId>
-            <artifactId>osgi.core</artifactId>
+            <artifactId>org.osgi.framework</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.component.annotations</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.cm</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.installer.core</artifactId>
-            <version>3.8.0</version>
+            <version>3.9.1-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.4</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.21.0</version>
+            <scope>provided</scope>
         </dependency>
     </dependencies>
 </project>
diff --git a/src/main/java/org/apache/sling/installer/core/impl/console/ConfigurationSerializerWebConsolePlugin.java b/src/main/java/org/apache/sling/installer/core/impl/console/ConfigurationSerializerWebConsolePlugin.java
new file mode 100644
index 0000000..2f8c9ee
--- /dev/null
+++ b/src/main/java/org/apache/sling/installer/core/impl/console/ConfigurationSerializerWebConsolePlugin.java
@@ -0,0 +1,195 @@
+/*
+ * 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.sling.installer.core.impl.console;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Dictionary;
+
+import javax.servlet.GenericServlet;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.request.ResponseUtil;
+import org.apache.sling.installer.api.serializer.ConfigurationSerializerFactory;
+import org.apache.sling.installer.api.serializer.ConfigurationSerializerFactory.Format;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(service=javax.servlet.Servlet.class,
+    property = {
+        Constants.SERVICE_VENDOR + "=The Apache Software Foundation",
+        Constants.SERVICE_DESCRIPTION + "=Apache Sling OSGi Installer Configuration Serializer Web Console Plugin",
+        "felix.webconsole.label=osgi-installer-config-printer",
+        "felix.webconsole.title=OSGi Installer Configuration Printer",
+        "felix.webconsole.category=OSGi"
+    })
+@SuppressWarnings("serial")
+public class ConfigurationSerializerWebConsolePlugin extends GenericServlet {
+
+    private static final String PARAMETER_PID = "pid";
+    private static final String PARAMETER_FORMAT = "format";
+    
+    /** The logger */
+    private final Logger LOGGER =  LoggerFactory.getLogger(ConfigurationSerializerWebConsolePlugin.class);
+
+    @Reference
+    ConfigurationAdmin configurationAdmin;
+
+    @Override
+    public void service(final ServletRequest request, final ServletResponse response)
+            throws IOException {
+        
+        final String pid = request.getParameter(PARAMETER_PID);
+        final String format = request.getParameter(PARAMETER_FORMAT);
+        ConfigurationSerializerFactory.Format serializationFormat = Format.JSON;
+        if (StringUtils.isNotBlank(format)) {
+            try {
+                serializationFormat = ConfigurationSerializerFactory.Format.valueOf(format);
+            } catch (IllegalArgumentException e) {
+                LOGGER.warn("Illegal parameter 'format' given", e);
+            }
+        }
+        final PrintWriter pw = response.getWriter();
+
+        pw.print("<form method='get'>");
+        pw.println("<table class='content' cellpadding='0' cellspacing='0' width='100%'>");
+
+        titleHtml(
+                pw,
+                "OSGi Installer Configuration Printer",
+                "To emit the current configuration for a specific OSGi service just enter its PID, select a serialization format and click 'Print'");
+
+        tr(pw);
+        tdLabel(pw, "PID");
+        tdContent(pw);
+
+        pw.print("<input type='text' name='");
+        pw.print(PARAMETER_PID);
+        pw.print("' value='");
+        if ( pid != null ) {
+            pw.print(ResponseUtil.escapeXml(pid));
+        }
+        
+        pw.println("' class='input' size='50'>");
+        closeTd(pw);
+        closeTr(pw);
+        closeTr(pw);
+
+        tr(pw);
+        tdLabel(pw, "Serialization Format");
+        tdContent(pw);
+        // TODO: select current value!
+        pw.print("<select name='");
+        pw.print(PARAMETER_FORMAT);
+        pw.println("'>");
+        pw.println("<option value='JSON'>OSGi Configurator JSON</option>");
+        pw.println("<option value='CONFIG'>Apache Felix Config</option>");
+        pw.println("<option value='PROPERTIES'>Java Properties</option>");
+        pw.println("<option value='PROPERTIES_XML'>Java Properties (XML)</option>");
+        pw.println("</select>");
+
+        pw.println("&nbsp;&nbsp;<input type='submit' value='Print' class='submit'>");
+
+        closeTd(pw);
+        closeTr(pw);
+
+        if (StringUtils.isNotBlank(pid)) {
+            tr(pw);
+            tdLabel(pw, "Serialized Configuration");
+            tdContent(pw);
+            
+            Configuration configuration = configurationAdmin.getConfiguration(pid);
+            Dictionary<String, Object> dictionary = configuration.getProperties();
+            if (dictionary == null) {
+                pw.println("No configuration for pid '" + pid + "' found!");
+            } else {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ConfigurationSerializerFactory.create(serializationFormat).serialize(dictionary, baos);
+                pw.println("<textarea rows=\"20\" cols=\"120\" readonly>");
+                pw.print(new String(baos.toByteArray(), StandardCharsets.UTF_8));
+                pw.println("</textarea>");
+            }
+            closeTd(pw);
+            closeTr(pw);
+        }
+
+        pw.println("</table>");
+        pw.print("</form>");
+    }
+
+
+    private void tdContent(final PrintWriter pw) {
+        pw.print("<td class='content' colspan='2'>");
+    }
+
+    private void closeTd(final PrintWriter pw) {
+        pw.print("</td>");
+    }
+
+    @SuppressWarnings("unused")
+    private URL getResource(final String path) {
+        if (path.startsWith("/servletresolver/res/ui")) {
+            return this.getClass().getResource(path.substring(16));
+        } else {
+            return null;
+        }
+    }
+
+    private void closeTr(final PrintWriter pw) {
+        pw.println("</tr>");
+    }
+
+    private void tdLabel(final PrintWriter pw, final String label) {
+        pw.print("<td class='content'>");
+        pw.print(ResponseUtil.escapeXml(label));
+        pw.println("</td>");
+    }
+
+    private void tr(final PrintWriter pw) {
+        pw.println("<tr class='content'>");
+    }
+
+    
+    private void titleHtml(final PrintWriter pw, final String title, final String description) {
+        tr(pw);
+        pw.print("<th colspan='3' class='content container'>");
+        pw.print(ResponseUtil.escapeXml(title));
+        pw.println("</th>");
+        closeTr(pw);
+
+        if (description != null) {
+            tr(pw);
+            pw.print("<td colspan='3' class='content'>");
+            pw.print(ResponseUtil.escapeXml(description));
+            pw.println("</th>");
+            closeTr(pw);
+        }
+    }
+
+}