You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2019/05/19 04:55:00 UTC

[karaf] branch karaf-4.2.x updated: [KARAF-6247] Add web:install & web:uninstall commands and corresponding WebMBean operations

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

jbonofre pushed a commit to branch karaf-4.2.x
in repository https://gitbox.apache.org/repos/asf/karaf.git


The following commit(s) were added to refs/heads/karaf-4.2.x by this push:
     new 574b36c  [KARAF-6247] Add web:install & web:uninstall commands and corresponding WebMBean operations
574b36c is described below

commit 574b36cc87874c2dcbf0385dd01832eebaf774c3
Author: Jean-Baptiste Onofré <jb...@apache.org>
AuthorDate: Fri May 17 17:38:56 2019 +0200

    [KARAF-6247] Add web:install & web:uninstall commands and corresponding WebMBean operations
---
 .../test/java/org/apache/karaf/itests/WebTest.java | 66 +++++++++++++++++++++-
 .../org/apache/karaf/web/WebContainerService.java  | 18 ++++++
 .../org/apache/karaf/web/commands/Install.java     | 45 +++++++++++++++
 .../org/apache/karaf/web/commands/Uninstall.java   | 42 ++++++++++++++
 .../web/internal/WebContainerServiceImpl.java      | 31 +++++++++-
 .../org/apache/karaf/web/management/WebMBean.java  | 25 ++++++++
 .../web/management/internal/WebMBeanImpl.java      | 34 +++++++++++
 7 files changed, 257 insertions(+), 4 deletions(-)

diff --git a/itests/test/src/test/java/org/apache/karaf/itests/WebTest.java b/itests/test/src/test/java/org/apache/karaf/itests/WebTest.java
index c295645..ce1bb29 100644
--- a/itests/test/src/test/java/org/apache/karaf/itests/WebTest.java
+++ b/itests/test/src/test/java/org/apache/karaf/itests/WebTest.java
@@ -13,11 +13,10 @@
  */
 package org.apache.karaf.itests;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.SimpleType;
 import javax.management.openmbean.TabularData;
 
 import org.junit.Before;
@@ -28,7 +27,13 @@ import org.ops4j.pax.exam.junit.PaxExam;
 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
 import org.ops4j.pax.exam.spi.reactors.PerClass;
 
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
 import java.lang.management.ManagementFactory;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import static org.junit.Assert.*;
 
 @RunWith(PaxExam.class)
 @ExamReactorStrategy(PerClass.class)
@@ -54,4 +59,59 @@ public class WebTest extends KarafTestSupport {
         assertEquals(0, webBundles.size());
     }
 
+    @Test
+    public void installUninstallCommands() throws Exception {
+        System.out.println(executeCommand("web:install mvn:org.apache.karaf.examples/karaf-war-example-webapp/" + System.getProperty("karaf.version") + "/war test"));
+        String listOutput = executeCommand("web:list");
+        System.out.println(listOutput);
+        assertContains("/test", listOutput);
+        while (!listOutput.contains("Deployed")) {
+            Thread.sleep(500);
+            listOutput = executeCommand("web:list");
+        }
+        URL url = new URL("http://localhost:" + getHttpPort() + "/test");
+        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+        connection.setDoInput(true);
+        connection.setRequestMethod("GET");
+        StringBuffer buffer = new StringBuffer();
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
+            String line = null;
+            while ((line = reader.readLine()) != null) {
+                buffer.append(line).append("\n");
+            }
+        }
+        System.out.println(buffer.toString());
+        assertContains("Hello World!", buffer.toString());
+
+        System.out.println(executeCommand("web:uninstall 126"));
+        listOutput = executeCommand("web:list");
+        System.out.println(listOutput);
+        assertContainsNot("/test", listOutput);
+    }
+
+    @Test
+    public void installViaMBean() throws Exception {
+        MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
+        ObjectName name = new ObjectName("org.apache.karaf:type=web,name=root");
+        mbeanServer.invoke(name, "install", new Object[]{ "mvn:org.apache.karaf.examples/karaf-war-example-webapp/" + System.getProperty("karaf.version") + "/war", "test" }, new String[]{ String.class.getName(), String.class.getName() });
+        TabularData webBundles = (TabularData) mbeanServer.getAttribute(name, "WebBundles");
+        assertEquals(1, webBundles.size());
+
+        Thread.sleep(2000);
+
+        URL url = new URL("http://localhost:" + getHttpPort() + "/test");
+        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+        connection.setDoInput(true);
+        connection.setRequestMethod("GET");
+        StringBuffer buffer = new StringBuffer();
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
+            String line = null;
+            while ((line = reader.readLine()) != null) {
+                buffer.append(line).append("\n");
+            }
+        }
+        System.out.println(buffer.toString());
+        assertContains("Hello World!", buffer.toString());
+    }
+
 }
diff --git a/web/src/main/java/org/apache/karaf/web/WebContainerService.java b/web/src/main/java/org/apache/karaf/web/WebContainerService.java
index 791230a..3a59926 100644
--- a/web/src/main/java/org/apache/karaf/web/WebContainerService.java
+++ b/web/src/main/java/org/apache/karaf/web/WebContainerService.java
@@ -32,6 +32,24 @@ public interface WebContainerService {
     List<WebBundle> list() throws Exception;
 
     /**
+     * Helper method to create a webbundle location and install the bundle.
+     * It's a user convenient method to avoid to have to type 'webbundle:...?Web-ContextPath=...' URI.
+     *
+     * @param location The base bundle location.
+     * @param contextPath The web context path.
+     * @throws Exception In case of installation failure.
+     */
+    void install(String location, String contextPath) throws Exception;
+
+    /**
+     * Convenient method to uninstall web bundles.
+     *
+     * @param bundleIds The list of bundle IDs (TODO use a BundleSelector service).
+     * @throws Exception in case of uninstall failure.
+     */
+    void uninstall(List<Long> bundleIds) throws Exception;
+
+    /**
      * Get a string representation of the web state of a bundle (identified by id).
      *
      * @param bundleId the bundle ID.
diff --git a/web/src/main/java/org/apache/karaf/web/commands/Install.java b/web/src/main/java/org/apache/karaf/web/commands/Install.java
new file mode 100644
index 0000000..627b48c
--- /dev/null
+++ b/web/src/main/java/org/apache/karaf/web/commands/Install.java
@@ -0,0 +1,45 @@
+/*
+ * 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.karaf.web.commands;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.web.WebContainerService;
+
+@Command(scope = "web", name = "install", description = "Install a web application")
+@Service
+public class Install implements Action {
+
+    @Argument(index = 0, name = "location", description = "The web application artifact location", required = true, multiValued = false)
+    String location;
+
+    @Argument(index = 1, name = "contextPath", description = "The web context path to bind the web application in the web container", required = true, multiValued = false)
+    String contextPath;
+
+    @Reference
+    private WebContainerService webContainerService;
+
+    @Override
+    public Object execute() throws Exception {
+        webContainerService.install(location, contextPath);
+        return null;
+    }
+
+}
diff --git a/web/src/main/java/org/apache/karaf/web/commands/Uninstall.java b/web/src/main/java/org/apache/karaf/web/commands/Uninstall.java
new file mode 100644
index 0000000..505f1d8
--- /dev/null
+++ b/web/src/main/java/org/apache/karaf/web/commands/Uninstall.java
@@ -0,0 +1,42 @@
+/*
+ * 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.karaf.web.commands;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.web.WebContainerService;
+
+@Command(scope = "web", name = "uninstall", description = "Uninstall a web application")
+@Service
+public class Uninstall implements Action {
+
+    @Argument(index = 0, name = "ids", description = "The list of bundle IDs separated by whitespaces", required = true, multiValued = true)
+    java.util.List<Long> ids;
+
+    @Reference
+    private WebContainerService webContainerService;
+
+    @Override
+    public Object execute() throws Exception {
+        webContainerService.uninstall(ids);
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git a/web/src/main/java/org/apache/karaf/web/internal/WebContainerServiceImpl.java b/web/src/main/java/org/apache/karaf/web/internal/WebContainerServiceImpl.java
index 77a47f5..2e4f4fb 100644
--- a/web/src/main/java/org/apache/karaf/web/internal/WebContainerServiceImpl.java
+++ b/web/src/main/java/org/apache/karaf/web/internal/WebContainerServiceImpl.java
@@ -65,6 +65,7 @@ public class WebContainerServiceImpl implements WebContainerService, BundleListe
         }
     }
 
+    @Override
     public List<WebBundle> list() throws Exception {
         Bundle[] bundles = bundleContext.getBundles();
         Map<Long, WebEvent> bundleEvents = webEventHandler.getBundleEvents();
@@ -112,7 +113,33 @@ public class WebContainerServiceImpl implements WebContainerService, BundleListe
         
         return webBundles;
     }
-    
+
+    @Override
+    public void install(String location, String contextPath) throws Exception {
+        String completeLocation = "webbundle:" + location + "?Web-ContextPath=" + contextPath;
+        Bundle bundle = bundleContext.installBundle(completeLocation);
+        bundle.start();
+    }
+
+    @Override
+    public void uninstall(List<Long> bundleIds) throws Exception {
+        if (bundleIds != null && !bundleIds.isEmpty()) {
+            for (long bundleId : bundleIds) {
+                if (webEventHandler.getBundleEvents().containsKey(bundleId)) {
+                    WebEvent webEvent = webEventHandler.getBundleEvents().get(bundleId);
+                    Bundle bundle = webEvent.getBundle();
+                    if (bundle != null) {
+                        bundle.uninstall();
+                    } else {
+                        System.out.println("Bundle ID " + bundleId + " is invalid");
+                        LOGGER.warn("Bundle ID {} is invalid", bundleId);
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
     public void start(List<Long> bundleIds) throws Exception {
         if (bundleIds != null && !bundleIds.isEmpty()) {
             for (long bundleId : bundleIds) {
@@ -131,6 +158,7 @@ public class WebContainerServiceImpl implements WebContainerService, BundleListe
         }
     }
 
+    @Override
     public void stop(List<Long> bundleIds) throws Exception {
         if (bundleIds != null && !bundleIds.isEmpty()) {
             for (long bundleId : bundleIds) {
@@ -149,6 +177,7 @@ public class WebContainerServiceImpl implements WebContainerService, BundleListe
         }
     }
 
+    @Override
     public String state(long bundleId) {
 
         Map<Long, WebEvent> bundleEvents = webEventHandler.getBundleEvents();
diff --git a/web/src/main/java/org/apache/karaf/web/management/WebMBean.java b/web/src/main/java/org/apache/karaf/web/management/WebMBean.java
index b9a0b5c..5016316 100644
--- a/web/src/main/java/org/apache/karaf/web/management/WebMBean.java
+++ b/web/src/main/java/org/apache/karaf/web/management/WebMBean.java
@@ -34,6 +34,31 @@ public interface WebMBean {
     TabularData getWebBundles() throws MBeanException;
 
     /**
+     * Install a web application artifact.
+     *
+     * @param location The location of the web application artifact.
+     * @param contextPath The web context path of the web application.
+     * @throws MBeanException In case of installation exception.
+     */
+    void install(String location, String contextPath) throws MBeanException;
+
+    /**
+     * Uninstall a web application.
+     *
+     * @param bundleId the bundle ID.
+     * @throws MBeanException in case of uninstall failure.
+     */
+    void uninstall(Long bundleId) throws MBeanException;
+
+    /**
+     * Uninstall web applications.
+     *
+     * @param bundleIds The list of bundle IDs (TODO use a BundleSelector service).
+     * @throws MBeanException in case of uninstall failure.
+     */
+    void uninstall(List<Long> bundleIds) throws MBeanException;
+
+    /**
      * Start web context of the given web bundle (identified by ID).
      *
      * @param bundleId the bundle ID.
diff --git a/web/src/main/java/org/apache/karaf/web/management/internal/WebMBeanImpl.java b/web/src/main/java/org/apache/karaf/web/management/internal/WebMBeanImpl.java
index 597f4e6..239e39b 100644
--- a/web/src/main/java/org/apache/karaf/web/management/internal/WebMBeanImpl.java
+++ b/web/src/main/java/org/apache/karaf/web/management/internal/WebMBeanImpl.java
@@ -42,6 +42,7 @@ public class WebMBeanImpl extends StandardMBean implements WebMBean {
         this.webContainerService = webContainerService;
     }
 
+    @Override
     public TabularData getWebBundles() throws MBeanException {
         try {
             CompositeType webType = new CompositeType("Web Bundle", "An OSGi Web bundle",
@@ -77,6 +78,36 @@ public class WebMBeanImpl extends StandardMBean implements WebMBean {
         }
     }
 
+    @Override
+    public void install(String location, String contextPath) throws MBeanException {
+        try {
+            webContainerService.install(location, contextPath);
+        } catch (Exception e) {
+            throw new MBeanException(null, e.toString());
+        }
+    }
+
+    @Override
+    public void uninstall(Long bundleId) throws MBeanException {
+        try {
+            List<Long> list = new ArrayList<>();
+            list.add(bundleId);
+            webContainerService.uninstall(list);
+        } catch (Exception e) {
+            throw new MBeanException(null, e.toString());
+        }
+    }
+
+    @Override
+    public void uninstall(List<Long> bundleIds) throws MBeanException {
+        try {
+            webContainerService.uninstall(bundleIds);
+        } catch (Exception e) {
+            throw new MBeanException(null, e.toString());
+        }
+    }
+
+    @Override
     public void start(Long bundleId) throws MBeanException {
         try {
             List<Long> list = new ArrayList<>();
@@ -87,6 +118,7 @@ public class WebMBeanImpl extends StandardMBean implements WebMBean {
         }
     }
 
+    @Override
     public void start(List<Long> bundleIds) throws MBeanException {
         try {
             webContainerService.start(bundleIds);
@@ -95,6 +127,7 @@ public class WebMBeanImpl extends StandardMBean implements WebMBean {
         }
     }
 
+    @Override
     public void stop(Long bundleId) throws MBeanException {
         try {
             List<Long> list = new ArrayList<>();
@@ -105,6 +138,7 @@ public class WebMBeanImpl extends StandardMBean implements WebMBean {
         }
     }
 
+    @Override
     public void stop(List<Long> bundleIds) throws MBeanException {
         try {
             webContainerService.stop(bundleIds);