This is an automated email from the ASF dual-hosted git repository.
jbonofre pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/karaf.git
The following commit(s) were added to refs/heads/main by this push:
new 773f17a394 [KARAF-7392] Upgrade to Pax Web 8.0.2
new a35723813a This closes #1490
773f17a394 is described below
commit 773f17a39400219fa8eec55004137449edf3ea79
Author: Grzegorz Grzybek <[email protected]>
AuthorDate: Fri Feb 11 12:11:48 2022 +0100
[KARAF-7392] Upgrade to Pax Web 8.0.2
---
.../features/specs/src/main/feature/feature.xml | 2 +
.../spring-legacy/src/main/feature/feature.xml | 9 +-
.../features/spring/src/main/feature/feature.xml | 2 +-
.../features/standard/src/main/feature/feature.xml | 15 +-
.../karaf-servlet-example-annotation/pom.xml | 2 +-
.../karaf/http/command/ServletListCommand.java | 62 ----
.../org/apache/karaf/http/core/ServletInfo.java | 84 -----
.../org/apache/karaf/http/core/ServletService.java | 2 +
.../karaf/http/core/internal/HttpMBeanImpl.java | 15 +-
.../http/core/internal/ServletEventHandler.java | 47 ---
.../http/core/internal/ServletServiceImpl.java | 77 +----
.../karaf/http/core/internal/osgi/Activator.java | 41 +--
.../http/core/internal/HttpMBeanImplTest.java | 2 +-
.../java/org/apache/karaf/itests/HttpTest.java | 3 +-
.../test/java/org/apache/karaf/itests/WebTest.java | 13 +-
.../itests/examples/HttpResourceExampleTest.java | 11 +-
.../karaf/itests/examples/RestExampleTest.java | 9 +-
.../karaf/itests/examples/ServletExampleTest.java | 19 +-
.../karaf/itests/examples/WarExampleTest.java | 3 +-
.../itests/examples/WebSocketExampleTest.java | 8 +-
...venResolverRegisteredBeforeConfigAdminTest.java | 6 +-
manual/src/main/asciidoc/user-guide/console.adoc | 8 +-
manual/src/main/asciidoc/user-guide/http.adoc | 69 +++-
manual/src/main/asciidoc/user-guide/kar.adoc | 49 +--
.../src/main/asciidoc/user-guide/provisioning.adoc | 98 +++---
manual/src/main/asciidoc/user-guide/urls.adoc | 2 +-
.../src/main/asciidoc/user-guide/webcontainer.adoc | 361 +++++++++++++--------
pom.xml | 3 +-
.../org/apache/karaf/web/WebContainerService.java | 6 +-
.../java/org/apache/karaf/web/commands/List.java | 70 ----
.../web/internal/WebContainerServiceImpl.java | 231 +++++--------
.../apache/karaf/web/internal/WebEventHandler.java | 40 ---
.../apache/karaf/web/internal/osgi/Activator.java | 18 +-
.../web/management/internal/WebMBeanImpl.java | 72 +++-
.../apache/karaf/webconsole/http/Activator.java | 35 +-
.../apache/karaf/webconsole/http/HttpPlugin.java | 113 +++----
.../karaf/webconsole/http/ServletDetails.java | 27 +-
.../karaf/webconsole/http/ServletEventHandler.java | 72 ----
.../karaf/webconsole/http/WebEventHandler.java | 68 ----
.../src/main/resources/res/ui/http-contexts.js | 14 +-
40 files changed, 707 insertions(+), 1081 deletions(-)
diff --git a/assemblies/features/specs/src/main/feature/feature.xml
b/assemblies/features/specs/src/main/feature/feature.xml
index 4251fdf3ac..ef5382d6fc 100644
--- a/assemblies/features/specs/src/main/feature/feature.xml
+++ b/assemblies/features/specs/src/main/feature/feature.xml
@@ -124,6 +124,8 @@
<!-- converter -->
<feature name="converter" version="${felix.converter.version}">
+ <bundle
start-level="9">mvn:org.osgi/org.osgi.util.function/${org.osgi.util.function.version}</bundle>
+ <bundle
start-level="9">mvn:org.osgi/org.osgi.util.promise/${org.osgi.util.promise.version}</bundle>
<bundle>mvn:org.apache.felix/org.apache.felix.converter/${felix.converter.version}</bundle>
</feature>
diff --git a/assemblies/features/spring-legacy/src/main/feature/feature.xml
b/assemblies/features/spring-legacy/src/main/feature/feature.xml
index eb18156f13..0a8b56f378 100644
--- a/assemblies/features/spring-legacy/src/main/feature/feature.xml
+++ b/assemblies/features/spring-legacy/src/main/feature/feature.xml
@@ -44,7 +44,6 @@
<feature>spring-dm</feature>
<feature version="[2.5.6,4)">spring-web</feature>
<bundle
start-level="30">mvn:org.springframework.osgi/spring-osgi-web/${spring.osgi.version}</bundle>
-
<requirement>osgi.implementation;osgi.implementation="osgi.http";version:Version="1.1"</requirement>
</feature>
<!-- Spring 3.1.x support (required for spring-dm) -->
@@ -116,7 +115,6 @@
<bundle
dependency="true">mvn:javax.servlet/javax.servlet-api/3.1.0</bundle>
<bundle
start-level="30">mvn:org.springframework/spring-web/${spring31.version}</bundle>
<bundle
start-level="30">mvn:org.springframework/spring-webmvc/${spring31.version}</bundle>
-
<requirement>osgi.implementation;osgi.implementation="osgi.http";version:Version="1.1"</requirement>
</feature>
<feature name="spring-web-portlet" description="Spring 3.1.x Web Portlet
support" version="${spring31.version}">
@@ -193,7 +191,6 @@
<bundle
dependency="true">mvn:javax.servlet/javax.servlet-api/3.1.0</bundle>
<bundle
start-level="30">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.spring-web/${spring43.version}</bundle>
<bundle
start-level="30">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.spring-webmvc/${spring43.version}</bundle>
-
<requirement>osgi.implementation;osgi.implementation="osgi.http";version:Version="1.1"</requirement>
</feature>
<feature name="spring-web-portlet" description="Spring 4.3.x Web Portlet
support" version="${spring43.version}">
@@ -276,7 +273,6 @@
<bundle
dependency="true">mvn:javax.servlet/javax.servlet-api/3.1.0</bundle>
<bundle
start-level="30">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.spring-web/${spring52.version}</bundle>
<bundle
start-level="30">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.spring-webmvc/${spring52.version}</bundle>
-
<requirement>osgi.implementation;osgi.implementation="osgi.http";version:Version="1.1"</requirement>
</feature>
<feature name="spring-websocket" description="Spring 5.2.x WebSocket
support" version="${spring52.version}">
@@ -288,6 +284,7 @@
<!-- Spring Security support -->
<feature name="spring-security" description="Spring Security 3.1.x
support" version="${spring.security31.version}">
+ <feature>pax-web-jsp</feature>
<feature>pax-web-war</feature>
<feature version="[3,4)">spring-web</feature>
<bundle
dependency="true">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aspectj/${aspectj.bundle.version}</bundle>
@@ -299,6 +296,7 @@
</feature>
<feature name="spring-security" description="Spring Security 4.2.x
support" version="${spring.security42.version}">
+ <feature>pax-web-jsp</feature>
<feature>pax-web-war</feature>
<feature version="[4,5)">spring-web</feature>
<bundle
dependency="true">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aspectj/${aspectj.bundle.version}</bundle>
@@ -310,6 +308,7 @@
</feature>
<feature name="spring-security" description="Spring Security 5.3.x
support" version="${spring.security53.version}">
+ <feature>pax-web-jsp</feature>
<feature>pax-web-war</feature>
<feature version="[5.1,6)">spring-jdbc</feature>
<feature version="[5.1,6)">spring-tx</feature>
@@ -327,6 +326,7 @@
</feature>
<feature name="spring-security" description="Spring Security 5.4.x
support" version="${spring.security54.version}">
+ <feature>pax-web-jsp</feature>
<feature>pax-web-war</feature>
<feature version="[5.2,6)">spring-jdbc</feature>
<feature version="[5.2,6)">spring-tx</feature>
@@ -344,6 +344,7 @@
</feature>
<feature name="spring-security" description="Spring Security 5.5.x
support" version="${spring.security55.version}">
+ <feature>pax-web-jsp</feature>
<feature>pax-web-war</feature>
<feature version="[5.2,6)">spring-jdbc</feature>
<feature version="[5.2,6)">spring-tx</feature>
diff --git a/assemblies/features/spring/src/main/feature/feature.xml
b/assemblies/features/spring/src/main/feature/feature.xml
index a79e1f8ab8..88a5890419 100644
--- a/assemblies/features/spring/src/main/feature/feature.xml
+++ b/assemblies/features/spring/src/main/feature/feature.xml
@@ -89,7 +89,6 @@
<bundle
dependency="true">mvn:javax.servlet/javax.servlet-api/3.1.0</bundle>
<bundle
start-level="30">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.spring-web/${spring53.version}</bundle>
<bundle
start-level="30">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.spring-webmvc/${spring53.version}</bundle>
-
<requirement>osgi.implementation;osgi.implementation="osgi.http";version:Version="1.1"</requirement>
</feature>
<feature name="spring-websocket" description="Spring 5.3.x WebSocket
support" version="${spring53.version}">
@@ -101,6 +100,7 @@
<!-- Spring Security -->
<feature name="spring-security" description="Spring Security 5.6.x
support" version="${spring.security56.version}">
+ <feature>pax-web-jsp</feature>
<feature>pax-web-war</feature>
<feature version="[5.2,6)">spring-jdbc</feature>
<feature version="[5.2,6)">spring-tx</feature>
diff --git a/assemblies/features/standard/src/main/feature/feature.xml
b/assemblies/features/standard/src/main/feature/feature.xml
index e819e5aafd..d3ecf1c52a 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -867,7 +867,7 @@ org.osgi.service.http.port=8181
</feature>
<feature name="pax-web-http" description="Pax Web OSGi HTTP Service"
version="${pax.web.version}">
- <feature>pax-http</feature>
+ <feature>pax-web-http-jetty</feature>
<bundle
start-level="30">mvn:org.apache.karaf.http/org.apache.karaf.http.core/${project.version}</bundle>
<capability>http-service;provider:=pax-http</capability>
<conditional>
@@ -881,23 +881,26 @@ org.osgi.service.http.port=8181
<feature name="pax-web-http-whiteboard" description="Pax Web OSGi HTTP
Whiteboard support" version="${pax.web.version}">
<feature>pax-web-http</feature>
- <feature>pax-http-whiteboard</feature>
+ <feature>pax-web-whiteboard</feature>
+ <feature>pax-web-websockets</feature>
</feature>
<feature name="http-whiteboard" description="Transition feature for
backward compatibility" version="${pax.web.version}">
<feature>pax-web-http-whiteboard</feature>
</feature>
- <feature name="pax-web-war" description="Turn Karaf as a full
WebContainer" version="${project.version}">
+ <feature name="pax-web-http-war" description="Turn Karaf as a full
WebContainer" version="${project.version}">
<feature>pax-web-http</feature>
- <feature>pax-war</feature>
+ <feature>pax-web-war</feature>
+ <feature>pax-web-jsp</feature>
+ <feature>pax-web-websockets</feature>
<bundle
start-level="30">mvn:org.apache.karaf.web/org.apache.karaf.web.core/${project.version}</bundle>
</feature>
<feature name="war" description="Transition feature for backward
compatibility" version="${project.version}">
- <feature>pax-web-war</feature>
+ <feature>pax-web-http-war</feature>
</feature>
<feature name="jetty" description="Transition feature for backward
compatibility" version="9.4.43.v20210629">
- <feature>pax-jetty</feature>
+ <feature>pax-web-jetty</feature>
</feature>
<feature name="kar" description="Provide KAR (KARaf archive) support"
version="${project.version}">
diff --git
a/examples/karaf-servlet-example/karaf-servlet-example-annotation/pom.xml
b/examples/karaf-servlet-example/karaf-servlet-example-annotation/pom.xml
index 32dc06bde2..1bc23a0e8e 100644
--- a/examples/karaf-servlet-example/karaf-servlet-example-annotation/pom.xml
+++ b/examples/karaf-servlet-example/karaf-servlet-example-annotation/pom.xml
@@ -49,7 +49,7 @@
<configuration>
<instructions>
<_wab>src/main/webapp/</_wab>
- <Web-ContextPath>servlet-example</Web-ContextPath>
+ <Web-ContextPath>/servlet-example</Web-ContextPath>
<Export-Package>!*</Export-Package>
<Import-Package>
*
diff --git
a/http/src/main/java/org/apache/karaf/http/command/ServletListCommand.java
b/http/src/main/java/org/apache/karaf/http/command/ServletListCommand.java
deleted file mode 100644
index afbe003abb..0000000000
--- a/http/src/main/java/org/apache/karaf/http/command/ServletListCommand.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.http.command;
-
-import java.util.Arrays;
-
-import org.apache.karaf.http.core.ServletInfo;
-import org.apache.karaf.http.core.ServletService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.Col;
-import org.apache.karaf.shell.support.table.ShellTable;
-
-@Command(scope = "http", name = "list", description = "Lists details for
servlets.")
-@Service
-public class ServletListCommand implements Action {
-
- @Option(name = "--no-format", description = "Disable table rendered
output", required = false, multiValued = false)
- boolean noFormat;
-
- @Reference
- private ServletService servletService;
-
- @Override
- public Object execute() throws Exception {
- ShellTable table = new ShellTable();
- table.column(new Col("ID"));
- table.column(new Col("Servlet"));
- table.column(new Col("Servlet-Name"));
- table.column(new Col("State"));
- table.column(new Col("Alias"));
- table.column(new Col("Url"));
-
- for (ServletInfo info : servletService.getServlets()) {
- table.addRow().addContent(info.getBundleId(), info.getClassName(),
info.getName(),
- info.getStateString(), info.getAlias(),
Arrays.toString(info.getUrls()));
- }
- table.print(System.out, !noFormat);
- return null;
- }
-
- public void setServletService(ServletService servletService) {
- this.servletService = servletService;
- }
-}
diff --git a/http/src/main/java/org/apache/karaf/http/core/ServletInfo.java
b/http/src/main/java/org/apache/karaf/http/core/ServletInfo.java
deleted file mode 100644
index 515eb3613d..0000000000
--- a/http/src/main/java/org/apache/karaf/http/core/ServletInfo.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.http.core;
-
-import org.ops4j.pax.web.service.spi.WebEvent;
-
-public class ServletInfo {
- private String name;
- private long bundleId;
- private String className;
- private String alias;
- private int state;
- private String[] urls;
-
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public long getBundleId() {
- return bundleId;
- }
- public void setBundleId(long bundleId) {
- this.bundleId = bundleId;
- }
- public String getClassName() {
- return className;
- }
- public void setClassName(String className) {
- this.className = className;
- }
- public int getState() {
- return state;
- }
- public void setState(int state) {
- this.state = state;
- }
- public String getAlias() {
- return alias;
- }
- public void setAlias(String alias) {
- this.alias = alias;
- }
- public String[] getUrls() {
- return urls;
- }
- public void setUrls(String[] urls) {
- this.urls = urls;
- }
-
- public String getStateString() {
- switch (state) {
- case WebEvent.DEPLOYING:
- return "Deploying ";
- case WebEvent.DEPLOYED:
- return "Deployed ";
- case WebEvent.UNDEPLOYING:
- return "Undeploying";
- case WebEvent.UNDEPLOYED:
- return "Undeployed ";
- case WebEvent.FAILED:
- return "Failed ";
- case WebEvent.WAITING:
- return "Waiting ";
- default:
- return "Failed ";
- }
- }
-}
diff --git a/http/src/main/java/org/apache/karaf/http/core/ServletService.java
b/http/src/main/java/org/apache/karaf/http/core/ServletService.java
index fd9b24aa5b..a6296bda8c 100644
--- a/http/src/main/java/org/apache/karaf/http/core/ServletService.java
+++ b/http/src/main/java/org/apache/karaf/http/core/ServletService.java
@@ -18,6 +18,8 @@ package org.apache.karaf.http.core;
import java.util.List;
+import org.ops4j.pax.web.service.spi.model.info.ServletInfo;
+
public interface ServletService {
List<ServletInfo> getServlets();
diff --git
a/http/src/main/java/org/apache/karaf/http/core/internal/HttpMBeanImpl.java
b/http/src/main/java/org/apache/karaf/http/core/internal/HttpMBeanImpl.java
index 3d359c86aa..c5c7582e82 100644
--- a/http/src/main/java/org/apache/karaf/http/core/internal/HttpMBeanImpl.java
+++ b/http/src/main/java/org/apache/karaf/http/core/internal/HttpMBeanImpl.java
@@ -34,14 +34,15 @@ import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
import org.apache.karaf.http.core.*;
+import org.ops4j.pax.web.service.spi.model.info.ServletInfo;
/**
* Implementation of the HTTP MBean.
*/
public class HttpMBeanImpl extends StandardMBean implements HttpMBean {
- private ServletService servletService;
- private ProxyService proxyService;
+ private final ServletService servletService;
+ private final ProxyService proxyService;
public HttpMBeanImpl(ServletService servletService, ProxyService
proxyService) throws NotCompliantMBeanException {
super(HttpMBean.class);
@@ -53,16 +54,16 @@ public class HttpMBeanImpl extends StandardMBean implements
HttpMBean {
public TabularData getServlets() throws MBeanException {
try {
CompositeType servletType = new CompositeType("Servlet", "HTTP
Servlet",
- new String[]{"Bundle-ID", "Servlet", "Servlet Name", "State",
"Alias", "URL"},
- new String[]{"ID of the bundle that registered the servlet",
"Class name of the servlet", "Servlet Name", "Current state of the servlet",
"Aliases of the servlet", "URL of the servlet"},
+ new String[]{"Bundle-ID", "Servlet", "Servlet Name", "Context
Path", "Type", "URL"},
+ new String[]{"ID of the bundle that registered the servlet",
"Class name of the servlet", "Servlet Name", "Contexts of the servlet", "Type
of the servlet", "URLs of the servlet"},
new OpenType[]{SimpleType.LONG, SimpleType.STRING,
SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING});
- TabularType tableType = new TabularType("Servlets", "Table of all
HTTP servlets", servletType, new String[]{"Bundle-ID", "Servlet Name",
"State"});
+ TabularType tableType = new TabularType("Servlets", "Table of all
HTTP servlets", servletType, new String[]{"Bundle-ID", "Servlet Name", "Type"});
TabularData table = new TabularDataSupport(tableType);
List<ServletInfo> servletInfos = servletService.getServlets();
for (ServletInfo info : servletInfos) {
CompositeData data = new CompositeDataSupport(servletType,
- new String[]{"Bundle-ID", "Servlet", "Servlet Name",
"State", "Alias", "URL"},
- new Object[]{info.getBundleId(), info.getClassName(),
info.getName(), info.getStateString(), info.getAlias(),
Arrays.toString(info.getUrls())});
+ new String[]{"Bundle-ID", "Servlet", "Servlet Name",
"Context Path", "Type", "URL"},
+ new Object[]{info.getBundle().getBundleId(),
info.getServletClass(), info.getServletName(),
Arrays.toString(info.getContexts()), info.getType(),
Arrays.toString(info.getMapping())});
table.put(data);
}
return table;
diff --git
a/http/src/main/java/org/apache/karaf/http/core/internal/ServletEventHandler.java
b/http/src/main/java/org/apache/karaf/http/core/internal/ServletEventHandler.java
deleted file mode 100644
index de3bafb8d8..0000000000
---
a/http/src/main/java/org/apache/karaf/http/core/internal/ServletEventHandler.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.http.core.internal;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.ops4j.pax.web.service.spi.ServletEvent;
-import org.ops4j.pax.web.service.spi.ServletListener;
-import org.osgi.framework.Bundle;
-
-public class ServletEventHandler implements ServletListener {
-
- Map<String, ServletEvent> servletEvents = new HashMap<>();
-
- public synchronized void servletEvent(ServletEvent event) {
- servletEvents.put(event.getServletName(), event);
- }
-
- /**
- * @return the servletEvents
- */
- public synchronized List<ServletEvent> getServletEvents() {
- return new ArrayList<>(servletEvents.values());
- }
-
- public synchronized void removeEventsForBundle(Bundle bundle) {
- servletEvents.entrySet().removeIf(entry ->
entry.getValue().getBundle() == bundle);
- }
-
-}
diff --git
a/http/src/main/java/org/apache/karaf/http/core/internal/ServletServiceImpl.java
b/http/src/main/java/org/apache/karaf/http/core/internal/ServletServiceImpl.java
index 6b85f335fe..1a218a24bc 100644
---
a/http/src/main/java/org/apache/karaf/http/core/internal/ServletServiceImpl.java
+++
b/http/src/main/java/org/apache/karaf/http/core/internal/ServletServiceImpl.java
@@ -17,77 +17,34 @@
package org.apache.karaf.http.core.internal;
import java.util.ArrayList;
-import java.util.Comparator;
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
-import javax.servlet.Servlet;
-
-import org.apache.karaf.http.core.ServletInfo;
import org.apache.karaf.http.core.ServletService;
-import org.ops4j.pax.web.service.spi.ServletEvent;
+import org.ops4j.pax.web.service.WebContainer;
+import org.ops4j.pax.web.service.spi.model.info.ServletInfo;
+import org.ops4j.pax.web.service.spi.model.views.ReportWebContainerView;
public class ServletServiceImpl implements ServletService {
- private ServletEventHandler servletEventHandler;
+ private final WebContainer webContainer;
- public ServletServiceImpl(ServletEventHandler servletEventHandler) {
- this.servletEventHandler = servletEventHandler;
+ public ServletServiceImpl(WebContainer webContainer) {
+ this.webContainer = webContainer;
}
@Override
public List<ServletInfo> getServlets() {
- List<ServletInfo> servletInfos = new ArrayList<>();
- List<ServletEvent> events = servletEventHandler.getServletEvents();
- events.sort(Comparator.<ServletEvent>comparingLong(s ->
s.getBundle().getBundleId())
- .thenComparing(ServletEvent::getServletName));
- for (ServletEvent event : events) {
- Servlet servlet = event.getServlet();
- String servletClassName = " ";
- if (servlet != null) {
- servletClassName = servlet.getClass().getName();
- servletClassName =
servletClassName.substring(servletClassName.lastIndexOf(".") + 1);
- }
- String servletName = event.getServletName() != null ?
event.getServletName() : " ";
- if (servletName.contains(".")) {
- servletName =
servletName.substring(servletName.lastIndexOf(".") + 1);
- }
-
- String alias = event.getAlias();
- String[] urls = event.getUrlParameter();
-
- String contextPath =
event.getBundle().getHeaders().get("Web-ContextPath");
- if (contextPath == null) {
- contextPath =
event.getBundle().getHeaders().get("Webapp-Context"); // this one used by
pax-web but is deprecated
- }
- if (contextPath != null) {
- contextPath = contextPath.trim();
- if (!contextPath.startsWith("/")) {
- contextPath = "/" + contextPath;
- }
- if (alias != null) {
- alias = contextPath + alias;
- }
- if (urls != null) {
- urls = urls.clone();
- for (int i = 0; i < urls.length; i++) {
- if (urls[i].startsWith("/")) {
- urls[i] = contextPath + urls[i];
- } else {
- urls[i] = contextPath + "/" + urls[i];
- }
- }
- }
- }
-
- ServletInfo info = new ServletInfo();
- info.setBundleId(event.getBundle().getBundleId());
- info.setName(servletName);
- info.setClassName(servletClassName);
- info.setState(event.getType());
- info.setAlias(alias != null ? alias : " ");
- info.setUrls(urls != null ? urls : new String[] {""});
- servletInfos.add(info);
+ if (webContainer == null) {
+ return Collections.emptyList();
+ }
+ ReportWebContainerView view =
webContainer.adapt(ReportWebContainerView.class);
+ if (view == null) {
+ return Collections.emptyList();
}
- return servletInfos;
+
+ Set<ServletInfo> servletInfos = view.listServlets();
+ return new ArrayList<>(servletInfos);
}
}
diff --git
a/http/src/main/java/org/apache/karaf/http/core/internal/osgi/Activator.java
b/http/src/main/java/org/apache/karaf/http/core/internal/osgi/Activator.java
index e1a2b37a88..cfbc874f32 100644
--- a/http/src/main/java/org/apache/karaf/http/core/internal/osgi/Activator.java
+++ b/http/src/main/java/org/apache/karaf/http/core/internal/osgi/Activator.java
@@ -21,7 +21,6 @@ import org.apache.karaf.http.core.ProxyService;
import org.apache.karaf.http.core.ServletService;
import org.apache.karaf.http.core.internal.HttpMBeanImpl;
import org.apache.karaf.http.core.internal.ProxyServiceImpl;
-import org.apache.karaf.http.core.internal.ServletEventHandler;
import org.apache.karaf.http.core.internal.ServletServiceImpl;
import org.apache.karaf.http.core.internal.proxy.RandomBalancingPolicy;
import org.apache.karaf.http.core.internal.proxy.RoundRobinBalancingPolicy;
@@ -30,9 +29,7 @@ import org.apache.karaf.util.tracker.annotation.Managed;
import org.apache.karaf.util.tracker.annotation.ProvideService;
import org.apache.karaf.util.tracker.annotation.RequireService;
import org.apache.karaf.util.tracker.annotation.Services;
-import org.ops4j.pax.web.service.spi.ServletListener;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleListener;
+import org.ops4j.pax.web.service.WebContainer;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.cm.ManagedService;
import org.osgi.service.http.HttpService;
@@ -43,6 +40,7 @@ import java.util.Hashtable;
@Services(
requires = {
@RequireService(HttpService.class),
+ @RequireService(WebContainer.class),
@RequireService(ConfigurationAdmin.class)
},
provides = {
@@ -53,8 +51,6 @@ import java.util.Hashtable;
@Managed("org.apache.karaf.http")
public class Activator extends BaseActivator implements ManagedService {
- private BundleListener listener;
-
private ProxyService proxyService;
@Override
@@ -69,20 +65,12 @@ public class Activator extends BaseActivator implements
ManagedService {
return;
}
- final ServletEventHandler servletEventHandler = new
ServletEventHandler();
- register(ServletListener.class, servletEventHandler);
-
- ServletServiceImpl servletService = new
ServletServiceImpl(servletEventHandler);
- register(ServletService.class, servletService);
-
- listener = event -> {
- if (event.getType() == BundleEvent.UNINSTALLED
- || event.getType() == BundleEvent.UNRESOLVED
- || event.getType() == BundleEvent.STOPPED) {
- servletEventHandler.removeEventsForBundle(event.getBundle());
- }
- };
- bundleContext.addBundleListener(listener);
+ WebContainer webContainer = getTrackedService(WebContainer.class);
+ ServletServiceImpl servletService = null;
+ if (webContainer != null) {
+ servletService = new ServletServiceImpl(webContainer);
+ register(ServletService.class, servletService);
+ }
RandomBalancingPolicy randomBalancingPolicy = new
RandomBalancingPolicy();
Hashtable<String, String> randomBalancingPolicyProperties = new
Hashtable<>();
@@ -97,17 +85,10 @@ public class Activator extends BaseActivator implements
ManagedService {
proxyService = new ProxyServiceImpl(httpService, configurationAdmin,
bundleContext);
register(ProxyService.class, proxyService);
- HttpMBeanImpl httpMBean = new HttpMBeanImpl(servletService,
proxyService);
- registerMBean(httpMBean, "type=http");
- }
-
- @Override
- protected void doStop() {
- if (listener != null) {
- bundleContext.removeBundleListener(listener);
- listener = null;
+ if (servletService != null) {
+ HttpMBeanImpl httpMBean = new HttpMBeanImpl(servletService,
proxyService);
+ registerMBean(httpMBean, "type=http");
}
- super.doStop();
}
@Override
diff --git
a/http/src/test/java/org/apache/karaf/http/core/internal/HttpMBeanImplTest.java
b/http/src/test/java/org/apache/karaf/http/core/internal/HttpMBeanImplTest.java
index 994eb7025f..960db02bf1 100644
---
a/http/src/test/java/org/apache/karaf/http/core/internal/HttpMBeanImplTest.java
+++
b/http/src/test/java/org/apache/karaf/http/core/internal/HttpMBeanImplTest.java
@@ -28,7 +28,7 @@ public class HttpMBeanImplTest {
@Test
public void testRegisterMBean() throws Exception {
- HttpMBeanImpl httpMBean = new HttpMBeanImpl(new ServletServiceImpl(new
ServletEventHandler()), new ProxyServiceImpl(null, null, null));
+ HttpMBeanImpl httpMBean = new HttpMBeanImpl(new
ServletServiceImpl(null), new ProxyServiceImpl(null, null, null));
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
mbeanServer.registerMBean(httpMBean, new
ObjectName("org.apache.karaf:type=http,name=root"));
diff --git a/itests/test/src/test/java/org/apache/karaf/itests/HttpTest.java
b/itests/test/src/test/java/org/apache/karaf/itests/HttpTest.java
index 02e1a47fa0..3374b681e6 100644
--- a/itests/test/src/test/java/org/apache/karaf/itests/HttpTest.java
+++ b/itests/test/src/test/java/org/apache/karaf/itests/HttpTest.java
@@ -38,13 +38,14 @@ public class HttpTest extends BaseTest {
@Before
public void installHttpFeature() throws Exception {
installAndAssertFeature("http");
+ installAndAssertFeature("pax-web-karaf");
installAndAssertFeature("webconsole");
}
@Test
public void list() throws Exception {
waitForService("(objectClass=javax.servlet.ServletContext)", 5000);
- assertContains("/system/console", executeCommand("http:list"));
+ assertContains("/system/console", executeCommand("web:servlet-list"));
}
@Test
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 3d1d09b9cb..6fb77c74dc 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
@@ -40,11 +40,12 @@ public class WebTest extends BaseTest {
@Before
public void installWarFeature() throws Exception {
installAndAssertFeature("war");
+ installAndAssertFeature("pax-web-karaf");
}
@Test
public void listCommand() throws Exception {
- String listOutput = executeCommand("web:list");
+ String listOutput = executeCommand("web:wab-list");
System.out.println(listOutput);
assertFalse(listOutput.isEmpty());
}
@@ -60,12 +61,12 @@ public class WebTest extends BaseTest {
@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");
+ String listOutput = executeCommand("web:wab-list");
System.out.println(listOutput);
assertContains("/test", listOutput);
while (!listOutput.contains("Deployed")) {
Thread.sleep(500);
- listOutput = executeCommand("web:list");
+ listOutput = executeCommand("web:wab-list");
}
URL url = new URL("http://localhost:" + getHttpPort() + "/test");
HttpURLConnection connection = (HttpURLConnection)
url.openConnection();
@@ -84,11 +85,11 @@ public class WebTest extends BaseTest {
String name =
"mvn_org.apache.karaf.examples_karaf-war-example-webapp_" +
System.getProperty("karaf.version") + "_war";
String bundleId = executeCommand("bundle:id " + name);
System.out.println(executeCommand("web:uninstall " + bundleId));
- listOutput = executeCommand("web:list");
+ listOutput = executeCommand("web:wab-list");
System.out.println(listOutput);
while (listOutput.contains("/test")) {
Thread.sleep(500);
- listOutput = executeCommand("web:list");
+ listOutput = executeCommand("web:wab-list");
}
assertContainsNot("/test", listOutput);
}
@@ -98,10 +99,10 @@ public class WebTest extends BaseTest {
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() });
+ Thread.sleep(2000);
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();
diff --git
a/itests/test/src/test/java/org/apache/karaf/itests/examples/HttpResourceExampleTest.java
b/itests/test/src/test/java/org/apache/karaf/itests/examples/HttpResourceExampleTest.java
index 3ed7a11df1..5cc2b009dd 100644
---
a/itests/test/src/test/java/org/apache/karaf/itests/examples/HttpResourceExampleTest.java
+++
b/itests/test/src/test/java/org/apache/karaf/itests/examples/HttpResourceExampleTest.java
@@ -32,19 +32,20 @@ import java.net.URL;
@ExamReactorStrategy(PerClass.class)
public class HttpResourceExampleTest extends BaseTest {
- @Test(timeout = 60000L)
+ @Test(timeout = 600000L)
public void test() throws Exception {
addFeaturesRepository("mvn:org.apache.karaf.examples/karaf-http-resource-example-features/"
+ System.getProperty("karaf.version") + "/xml");
+ installAndAssertFeature("pax-web-karaf");
installAndAssertFeature("karaf-http-resource-example-whiteboard");
- String command = executeCommand("http:list");
- while (!command.contains("Deployed")) {
+ String command = executeCommand("web:servlet-list");
+ while (!command.contains("/example/*")) {
Thread.sleep(200);
- command = executeCommand("http:list");
+ command = executeCommand("web:servlet-list");
}
assertContains("ResourceServlet", command);
- assertContains("Deployed", command);
+ assertContains("Whiteboard", command);
URL url = new URL("http://localhost:" + getHttpPort() +
"/example/index.html");
HttpURLConnection connection = (HttpURLConnection)
url.openConnection();
diff --git
a/itests/test/src/test/java/org/apache/karaf/itests/examples/RestExampleTest.java
b/itests/test/src/test/java/org/apache/karaf/itests/examples/RestExampleTest.java
index 9d1e94cb0e..fbe4d25366 100644
---
a/itests/test/src/test/java/org/apache/karaf/itests/examples/RestExampleTest.java
+++
b/itests/test/src/test/java/org/apache/karaf/itests/examples/RestExampleTest.java
@@ -38,6 +38,7 @@ public class RestExampleTest extends BaseTest {
addFeaturesRepository("mvn:org.apache.karaf.examples/karaf-rest-example-features/"
+ System.getProperty("karaf.version") + "/xml");
installAndAssertFeature("http");
installAndAssertFeature("http-whiteboard");
+ installAndAssertFeature("pax-web-karaf");
}
private void verify() throws Exception {
@@ -118,12 +119,14 @@ public class RestExampleTest extends BaseTest {
public void testWhiteboard() throws Exception {
setup();
+ installAndAssertFeature("activation");
+ installAndAssertFeature("scr");
installAndAssertFeature("karaf-rest-example-whiteboard");
- String output = executeCommand("http:list");
- while (!output.contains("Deployed")) {
+ String output = executeCommand("web:servlet-list");
+ while (!output.contains("cxf-servlet")) {
Thread.sleep(500);
- output = executeCommand("http:list");
+ output = executeCommand("web:servlet-list");
}
System.out.println(output);
diff --git
a/itests/test/src/test/java/org/apache/karaf/itests/examples/ServletExampleTest.java
b/itests/test/src/test/java/org/apache/karaf/itests/examples/ServletExampleTest.java
index 0a91655098..29cb5c4db2 100644
---
a/itests/test/src/test/java/org/apache/karaf/itests/examples/ServletExampleTest.java
+++
b/itests/test/src/test/java/org/apache/karaf/itests/examples/ServletExampleTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.karaf.itests.examples;
+import org.apache.karaf.features.FeaturesService;
import org.apache.karaf.itests.BaseTest;
import org.junit.Assert;
import org.junit.Test;
@@ -34,6 +35,7 @@ import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.util.EnumSet;
@RunWith(PaxExam.class)
@ExamReactorStrategy(PerMethod.class)
@@ -43,13 +45,16 @@ public class ServletExampleTest extends BaseTest {
addFeaturesRepository("mvn:org.apache.karaf.examples/karaf-servlet-example-features/"
+ System.getProperty("karaf.version") + "/xml");
installAndAssertFeature("http");
installAndAssertFeature("http-whiteboard");
+ installAndAssertFeature("pax-web-karaf");
+ featureService.installFeature("pax-web-jsp",
EnumSet.noneOf(FeaturesService.Option.class));
+ installAndAssertFeature("pax-web-jsp");
}
private void verify() throws Exception {
- String command = executeCommand("http:list");
+ String command = executeCommand("web:servlet-list");
while (!command.contains("servlet-example")) {
Thread.sleep(200);
- command = executeCommand("http:list");
+ command = executeCommand("web:servlet-list");
}
System.out.println(command);
@@ -85,10 +90,10 @@ public class ServletExampleTest extends BaseTest {
installAndAssertFeature("karaf-servlet-example-annotation");
- String command = executeCommand("http:list");
- while (!command.contains("servlet-example/multipart")) {
+ String command = executeCommand("web:servlet-list");
+ while (!command.contains("/multipart")) {
Thread.sleep(200);
- command = executeCommand("http:list");
+ command = executeCommand("web:servlet-list");
}
verify();
@@ -118,10 +123,10 @@ public class ServletExampleTest extends BaseTest {
installAndAssertFeature("karaf-servlet-example-upload");
- String command = executeCommand("http:list");
+ String command = executeCommand("web:servlet-list");
while (!command.contains("upload-example")) {
Thread.sleep(200);
- command = executeCommand("http:list");
+ command = executeCommand("web:servlet-list");
}
System.out.println(command);
diff --git
a/itests/test/src/test/java/org/apache/karaf/itests/examples/WarExampleTest.java
b/itests/test/src/test/java/org/apache/karaf/itests/examples/WarExampleTest.java
index 967d270eaf..fa13328f92 100644
---
a/itests/test/src/test/java/org/apache/karaf/itests/examples/WarExampleTest.java
+++
b/itests/test/src/test/java/org/apache/karaf/itests/examples/WarExampleTest.java
@@ -35,12 +35,13 @@ public class WarExampleTest extends BaseTest {
@Test
public void test() throws Exception {
addFeaturesRepository("mvn:org.apache.karaf.examples/karaf-war-example-features/"
+ System.getProperty("karaf.version") + "/xml");
+ installAndAssertFeature("pax-web-karaf");
installAndAssertFeature("karaf-war-example");
// give time to the webapp to deploy
Thread.sleep(2000);
- String output = executeCommand("web:list");
+ String output = executeCommand("web:wab-list");
System.out.println(output);
assertContains("example", output);
diff --git
a/itests/test/src/test/java/org/apache/karaf/itests/examples/WebSocketExampleTest.java
b/itests/test/src/test/java/org/apache/karaf/itests/examples/WebSocketExampleTest.java
index 7ddacd13e7..8f36ca012e 100644
---
a/itests/test/src/test/java/org/apache/karaf/itests/examples/WebSocketExampleTest.java
+++
b/itests/test/src/test/java/org/apache/karaf/itests/examples/WebSocketExampleTest.java
@@ -49,14 +49,16 @@ public class WebSocketExampleTest extends BaseTest {
public void test() throws Exception {
featureService.installFeature("scr");
featureService.installFeature("http");
+ featureService.installFeature("pax-web-karaf");
+ featureService.installFeature("pax-web-jetty-websockets");
Bundle bundle =
bundleContext.installBundle("mvn:org.apache.karaf.examples/karaf-websocket-example/"
+ System.getProperty("karaf.version"));
bundle.start();
- String httpList = executeCommand("http:list");
- while (!httpList.contains("Deployed")) {
+ String httpList = executeCommand("web:servlet-list");
+ while (!httpList.contains("/example-websocket/*")) {
Thread.sleep(1000);
- httpList = executeCommand("http:list");
+ httpList = executeCommand("web:servlet-list");
}
System.out.println(httpList);
diff --git
a/itests/test/src/test/java/org/apache/karaf/itests/mavenresolver/MavenResolverRegisteredBeforeConfigAdminTest.java
b/itests/test/src/test/java/org/apache/karaf/itests/mavenresolver/MavenResolverRegisteredBeforeConfigAdminTest.java
index 67fe43d6c9..7de267ed53 100644
---
a/itests/test/src/test/java/org/apache/karaf/itests/mavenresolver/MavenResolverRegisteredBeforeConfigAdminTest.java
+++
b/itests/test/src/test/java/org/apache/karaf/itests/mavenresolver/MavenResolverRegisteredBeforeConfigAdminTest.java
@@ -18,6 +18,7 @@ package org.apache.karaf.itests.mavenresolver;
import static org.junit.Assert.assertEquals;
import static org.ops4j.pax.exam.CoreOptions.composite;
+import static
org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
import static
org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
import static
org.ops4j.pax.exam.karaf.options.KarafDistributionOption.replaceConfigurationFile;
@@ -49,7 +50,10 @@ public class MavenResolverRegisteredBeforeConfigAdminTest
extends KarafMinimalMo
composite(super.baseConfig()),
composite(editConfigurationFilePut("etc/org.apache.karaf.features.cfg", new
File("target/test-classes/etc/org.apache.karaf.features.cfg"))),
// etc/config.properties which doesn't have
org.ops4j.pax.url.mvn.requireConfigAdminConfig=true
- replaceConfigurationFile("etc/config.properties", new
File("target/test-classes/etc/config.properties"))
+ replaceConfigurationFile("etc/config.properties", new
File("target/test-classes/etc/config.properties")),
+ // threaded=false, so we don't get:
+ // java.io.IOException: Cannot bind to URL [rmi://:1099/karaf-root]:
javax.naming.ServiceUnavailableException
+ editConfigurationFilePut("etc/org.apache.karaf.management.cfg",
"threaded", "false")
};
}
diff --git a/manual/src/main/asciidoc/user-guide/console.adoc
b/manual/src/main/asciidoc/user-guide/console.adoc
index 08fe392ced..22e1a9cd6d 100644
--- a/manual/src/main/asciidoc/user-guide/console.adoc
+++ b/manual/src/main/asciidoc/user-guide/console.adoc
@@ -288,11 +288,9 @@ Like on most Unix environments, the Karaf console supports
some key bindings:
You can pipe the output of one command as input to another one. It's a pipe,
using the | character:
----
-karaf@root()> feature:list |grep -i war
-pax-war | 4.1.4 | |
Uninstalled | org.ops4j.pax.web-4.1.4 | Provide support of a full WebContainer
-pax-war-tomcat | 4.1.4 | |
Uninstalled | org.ops4j.pax.web-4.1.4 |
-war | 4.0.0 | |
Uninstalled | standard-4.0.0 | Turn Karaf as a full WebContainer
-blueprint-web | 4.0.0 | |
Uninstalled | standard-4.0.0 | Provides an OSGI-aware Servlet
ContextListener fo
+karaf@root()> feature:list | grep -i felix
+felix-httplite │ 0.1.6 │ │ Uninstalled
│ standard-4.4.0 │ Felix Httplite HTTP Service
+felix-http │ 4.1.12 │ │ Uninstalled
│ standard-4.4.0 │ Felix HTTP Service
----
===== Grep, more, find, ...
diff --git a/manual/src/main/asciidoc/user-guide/http.adoc
b/manual/src/main/asciidoc/user-guide/http.adoc
index d48b4f87c7..50de4699a8 100644
--- a/manual/src/main/asciidoc/user-guide/http.adoc
+++ b/manual/src/main/asciidoc/user-guide/http.adoc
@@ -14,22 +14,26 @@
==== Http Service
-Apache Karaf supports several Http Services:
+_Http Service_ should mean an implementation of OSGi CMPN Chapter 102 "Http
Service" specification.
-* `http` feature installs Http Service powered by Pax Web
-* `felix-http` feature installs Http Service powered by Apache Felix HTTP
+Apache Karaf supports several Http Service implementations:
+
+* `http` feature installs Http Service implementation powered by Pax Web
+* `felix-http` feature installs Http Service implementation powered by Apache
Felix HTTP
+
+NOTE: Felix HTTP implementation is also an implementation of OSGi CMPN Chapter
140 "Whiteboard Service" specification.
+
+NOTE: Pax Web also contains implementations of OSGi CMPN Chapter 140
"Whiteboard Service" and OSGi CMPN Chapter 128 "Web Applications"
specification, but these are installed using additional features.
===== Installing the Http Service
-If you want to use Pax Web Http Service, you have to install the `http`
feature:
+If you want to use Pax Web Http Service implementation, you have to install
the `http` feature:
----
root@karaf()> feature:install http
----
-NB: the HTTP service will be actually bound only when at least one web
application will use it.
-
-If you want to use Apache Felix Http Service, you have to install `felix-http`
feature:
+If you want to use Apache Felix Http Service implementation, you have to
install `felix-http` feature:
----
root@karaf()> feature:install felix-http
@@ -43,6 +47,57 @@ root@karaf()> feature:install webconsole
Then, you can test the HTTP service by accessing the Apache Karaf WebConsole
pointing your browser to [http://localhost:8181/system/console].
+====== More information about Pax Web implementation
+
+Pax Web 8 itself contains properly defined and tested Karaf features. However
Karaf was always providing own web-related features in
`org.apache.karaf.features/standard` feature repository.
+
+For completeness, here's a full list of features provided by Pax Web:
+
+.Core features
+
+* `pax-web-specs` - several API related bundles that can be used (or can be
treated as reference) when the runtime (like Karaf) doesn't provide necessary
APIs (servlet API, EL API, Annotation API)
+* `pax-web-core` - fundamental Pax Web API/SPI bundles which don't register
any OSGi services
+
+.Runtime features
+
+Pax Web in all versions (and in particular in version 8) was always aiming to
provide support for all major web container technologies. That's why there are
3 sets of features for Jetty, Tomcat and Undertow support. These features only
install relevant web container bundles without any bundles specific to OSGi
CMPN specifications.
+
+* Jetty
+** `pax-web-jetty` - required `org.eclipse.jetty` bundles with Servlet API
bundle
+** `pax-web-jetty-websockets` - required `org.eclipse.jetty.websocket` bundles
with WebSocket API bundle
+** `pax-web-jetty-http2` - required `org.eclipse.jetty.http2` bundles
+** `pax-web-jetty-http2-jdk8` - optional Jetty ALPN bundles when running on
JDK8
+** `pax-web-jetty-http2-jdk9` - optional Jetty ALPN bundles when running on
JDK9+
+* Tomcat
+** `pax-web-tomcat` - required Tomcat bundles (repackaged `org.apache.tomcat`
libraries), including HTTP/2 support
+** `pax-web-tomcat-websockets` required Tomcat bundles for WebSocket support
(repackaged `org.apache.tomcat` libraries)
+* Undertow
+** `pax-web-undertow` - required Undertow bundles, including HTTP/2 support
+** `pax-web-undertow-websockets` - required Undertow bundles for WebSocket
support
+
+.OSGi CMPN Http Service features
+
+* `pax-web-http-jetty` - implementation of OSGi CMPN Chapter 102 "Http
Service" specification based on Jetty 9.4
+* `pax-web-http-tomcat` - implementation of OSGi CMPN Chapter 102 "Http
Service" specification based on Tomcat 9.0
+* `pax-web-http-undertow` - implementation of OSGi CMPN Chapter 102 "Http
Service" specification based on Undertow 2.2
+
+.Additional features
+
+* `pax-web-jsp` - support for Java Server Pages (not mentioned in OSGi CMPN
specifications)
+* `pax-web-whiteboard` - support for OSGi CMPN Chapter 140 "Whiteboard
Service" specification
+* `pax-web-war` - support for OSGi CMPN Chapter 128 "Web Applications"
specification (WABs and WARs)
+* `pax-web-karaf` - Karaf commands implemented by Pax Web itself
+
+====== Additional features that include Pax Web features
+
+Karaf itself provides more features than just `felix-http` and `http`. Simply
because there are many Pax Web features, there's support for more web
containers and there are more technologies to cover (like websockets and JSPs),
but also because of some kind of backward compatibility, here's a list of Pax
Web related features defined in Karaf:
+
+* `http` - the _main_ feature mentioned at the start of this chapter. This
feature only includes `pax-web-http` feature, also defined in Karaf
+* `pax-web-http` - includes `pax-web-http-jetty` feature from Pax Web and also
Http JMX and WebConsole bundles from Karaf
+* `pax-web-http-whiteboard` and `http-whiteboard` (its alias) - include
`pax-web-http-jetty`, `pax-web-whiteboard` and `pax-web-websockets` features
from Pax Web
+* `pax-web-http-war` and `war` (its alias) - include `pax-web-http-jetty`,
`pax-web-war`, `pax-web-jsp` and `pax-web-websockets` features from Pax Web
+* `jetty` - includes `pax-web-jetty`, so it's only used to install Jetty
bundles. This feature is used as feature-dependency of many CXF and Camel
features.
+
===== Configuring the HTTPService
By default the HTTPService listens on port 8181 you can change the port by
creating a file `etc/org.ops4j.pax.web.cfg` (if you use the Pax Web Http
Service) with the following content:
diff --git a/manual/src/main/asciidoc/user-guide/kar.adoc
b/manual/src/main/asciidoc/user-guide/kar.adoc
index 3d40718f6c..cebfcd9e3d 100644
--- a/manual/src/main/asciidoc/user-guide/kar.adoc
+++ b/manual/src/main/asciidoc/user-guide/kar.adoc
@@ -173,26 +173,36 @@ The `feature:repo-list` command gives you the list of
registered features reposi
karaf@root()> feature:repo-list
Repository | URL
-------------------------------------------------------------------------------------------------------
-standard-4.0.0 |
mvn:org.apache.karaf.features/standard/4.0.0/xml/features
-enterprise-4.0.0 |
mvn:org.apache.karaf.features/enterprise/4.0.0/xml/features
-spring-4.0.0 |
mvn:org.apache.karaf.features/spring/4.0.0/xml/features
-org.ops4j.pax.web-4.1.4 |
mvn:org.ops4j.pax.web/pax-web-features/4.1.4/xml/features
+standard-4.4.0 |
mvn:org.apache.karaf.features/standard/4.4.0/xml/features
+enterprise-4.4.0 |
mvn:org.apache.karaf.features/enterprise/4.4.0/xml/features
+spring-4.4.0 |
mvn:org.apache.karaf.features/spring/4.4.0/xml/features
+org.ops4j.pax.web-8.0.2 |
mvn:org.ops4j.pax.web/pax-web-features/8.0.2/xml/features
----
You can use one of these features repositories to create the kar file:
----
-karaf@root()> kar:create org.ops4j.pax.web-4.1.4
-Adding feature pax-jetty
-Adding feature pax-http-whiteboard
-Adding feature pax-war
-Adding feature pax-http-tomcat
-Adding feature pax-war-tomcat
-Adding feature pax-http
-Adding feature pax-http-jetty
-Adding feature pax-jsf-support
-Adding feature pax-jetty-spdy
-Kar file created :
/home/jbonofre/Downloads/apache-karaf-4.0.0/data/kar/org.ops4j.pax.web-4.1.4.kar
+karaf@root()> kar:create org.ops4j.pax.web-8.0.2
+Adding feature pax-web-karaf
+Adding feature pax-web-core
+Adding feature pax-web-http-tomcat
+Adding feature pax-web-websockets
+Adding feature pax-web-jetty
+Adding feature pax-web-undertow
+Adding feature pax-web-jetty-http2
+Adding feature pax-web-http-undertow
+Adding feature pax-web-whiteboard
+Adding feature pax-web-tomcat-websockets
+Adding feature pax-web-jsp
+Adding feature pax-web-undertow-websockets
+Adding feature pax-web-war
+Adding feature pax-web-jetty-websockets
+Adding feature pax-web-tomcat
+Adding feature pax-web-jetty-http2-jdk8
+Adding feature pax-web-http-jetty
+Adding feature pax-web-jetty-http2-jdk9
+Adding feature pax-web-specs
+Kar file created :
/data/servers/apache-karaf-4.4.0-SNAPSHOT/data/kar/org.ops4j.pax.web-8.0.2.kar
----
You can see that the KAR file has been created in the `KARAF_DATA/kar` folder.
@@ -202,10 +212,11 @@ By default, the `kar:create` command creates a KAR file,
packaging all features
You can provide the list of features that you want to package into the KAR
file:
----
-karaf@root()> kar:create org.ops4j.pax.web-4.1.4 pax-jetty pax-tomcat
-Adding feature pax-jetty
-Adding feature pax-tomcat
-Kar file created : /opt/apache-karaf-4.1.4/data/kar/org.ops4j.pax.web-4.1.4.kar
+karaf@root()> kar:create org.ops4j.pax.web-8.0.2 pax-web-http-jetty
pax-web-jetty
+Adding feature pax-web-core
+Adding feature pax-web-jetty
+Adding feature pax-web-http-jetty
+Kar file created :
/data/servers/apache-karaf-4.4.0-SNAPSHOT/data/kar/org.ops4j.pax.web-8.0.2.kar
----
===== `kar:install`
diff --git a/manual/src/main/asciidoc/user-guide/provisioning.adoc
b/manual/src/main/asciidoc/user-guide/provisioning.adoc
index c5a30cb392..3c781d8dda 100644
--- a/manual/src/main/asciidoc/user-guide/provisioning.adoc
+++ b/manual/src/main/asciidoc/user-guide/provisioning.adoc
@@ -508,13 +508,21 @@ The `feature:repo-list` command lists all registered
feature repositories:
----
karaf@root()> feature:repo-list
-Repository | URL
+Repository | URL
--------------------------------------------------------------------------------------
-org.ops4j.pax.cdi-0.12.0 |
mvn:org.ops4j.pax.cdi/pax-cdi-features/0.12.0/xml/features
-org.ops4j.pax.web-4.1.4 |
mvn:org.ops4j.pax.web/pax-web-features/4.1.4/xml/features
-standard-4.0.0 |
mvn:org.apache.karaf.features/standard/4.0.0/xml/features
-enterprise-4.0.0 |
mvn:org.apache.karaf.features/enterprise/4.0.0/xml/features
-spring-4.0.0 |
mvn:org.apache.karaf.features/spring/4.0.0/xml/features
+pax-jms-1.1.0 │
mvn:org.ops4j.pax.jms/pax-jms-features/1.1.0/xml/features
+standard-4.4.0 │
mvn:org.apache.karaf.features/standard/4.4.0/xml/features
+org.ops4j.pax.jdbc-1.5.0 │
mvn:org.ops4j.pax.jdbc/pax-jdbc-features/1.5.0/xml/features
+aries-jpa-2.7.3 │
mvn:org.apache.aries.jpa/jpa-features/2.7.3/xml/features
+framework-4.4.0 │
mvn:org.apache.karaf.features/framework/4.4.0/xml/features
+org.ops4j.pax.web-8.0.2 │
mvn:org.ops4j.pax.web/pax-web-features/8.0.2/xml/features
+pax-transx-0.5.0 │
mvn:org.ops4j.pax.transx/pax-transx-features/0.5.0/xml/features
+openjpa-3.2.0 │
mvn:org.apache.openjpa/openjpa-features/3.2.0/xml/features
+specs-4.4.0 │
mvn:org.apache.karaf.features/specs/4.4.0/xml/features
+hibernate-validator-osgi-features │
mvn:org.hibernate.validator/hibernate-validator-osgi-karaf-features/7.0.1.Final/xml/features
+spring-4.4.0 │
mvn:org.apache.karaf.features/spring/4.4.0/xml/features
+enterprise-4.4.0 │
mvn:org.apache.karaf.features/enterprise/4.4.0/xml/features
+org.ops4j.pax.cdi-1.1.4 │
mvn:org.ops4j.pax.cdi/pax-cdi-features/1.1.4/xml/features
----
Each repository has a name and the URL to the features XML.
@@ -527,13 +535,21 @@ so update the features definition), you can use the `-r`
option:
karaf@root()> feature:repo-list -r
Reloading all repositories from their urls
-Repository | URL
+Repository | URL
--------------------------------------------------------------------------------------
-org.ops4j.pax.cdi-0.12.0 |
mvn:org.ops4j.pax.cdi/pax-cdi-features/0.12.0/xml/features
-org.ops4j.pax.web-4.1.4 |
mvn:org.ops4j.pax.web/pax-web-features/4.1.4/xml/features
-standard-4.0.0 |
mvn:org.apache.karaf.features/standard/4.0.0/xml/features
-enterprise-4.0.0 |
mvn:org.apache.karaf.features/enterprise/4.0.0/xml/features
-spring-4.0.0 |
mvn:org.apache.karaf.features/spring/4.0.0/xml/features
+pax-jms-1.1.0 │
mvn:org.ops4j.pax.jms/pax-jms-features/1.1.0/xml/features
+standard-4.4.0 │
mvn:org.apache.karaf.features/standard/4.4.0/xml/features
+org.ops4j.pax.jdbc-1.5.0 │
mvn:org.ops4j.pax.jdbc/pax-jdbc-features/1.5.0/xml/features
+aries-jpa-2.7.3 │
mvn:org.apache.aries.jpa/jpa-features/2.7.3/xml/features
+framework-4.4.0 │
mvn:org.apache.karaf.features/framework/4.4.0/xml/features
+org.ops4j.pax.web-8.0.2 │
mvn:org.ops4j.pax.web/pax-web-features/8.0.2/xml/features
+pax-transx-0.5.0 │
mvn:org.ops4j.pax.transx/pax-transx-features/0.5.0/xml/features
+openjpa-3.2.0 │
mvn:org.apache.openjpa/openjpa-features/3.2.0/xml/features
+specs-4.4.0 │
mvn:org.apache.karaf.features/specs/4.4.0/xml/features
+hibernate-validator-osgi-features │
mvn:org.hibernate.validator/hibernate-validator-osgi-karaf-features/7.0.1.Final/xml/features
+spring-4.4.0 │
mvn:org.apache.karaf.features/spring/4.4.0/xml/features
+enterprise-4.4.0 │
mvn:org.apache.karaf.features/enterprise/4.4.0/xml/features
+org.ops4j.pax.cdi-1.1.4 │
mvn:org.ops4j.pax.cdi/pax-cdi-features/1.1.4/xml/features
----
===== `feature:repo-add`
@@ -639,18 +655,18 @@ Without argument, the command refreshes all features
repository:
----
karaf@root()> feature:repo-refresh
Refreshing feature url
mvn:org.ops4j.pax.cdi/pax-cdi-features/0.12.0/xml/features
-Refreshing feature url
mvn:org.ops4j.pax.web/pax-web-features/4.1.4/xml/features
-Refreshing feature url
mvn:org.apache.karaf.features/standard/4.0.0/xml/features
-Refreshing feature url
mvn:org.apache.karaf.features/enterprise/4.0.0/xml/features
-Refreshing feature url mvn:org.apache.karaf.features/spring/4.0.0/xml/features
+Refreshing feature url
mvn:org.ops4j.pax.web/pax-web-features/8.0.2/xml/features
+Refreshing feature url
mvn:org.apache.karaf.features/standard/4.4.0/xml/features
+Refreshing feature url
mvn:org.apache.karaf.features/enterprise/4.4.0/xml/features
+Refreshing feature url mvn:org.apache.karaf.features/spring/4.4.0/xml/features
----
Instead of refreshing all features repositories, you can specify the features
repository to refresh, by providing the URL
or the features repository name (and optionally version):
----
-karaf@root()> feature:repo-refresh
mvn:org.apache.karaf.features/standard/4.0.0/xml/features
-Refreshing feature url
mvn:org.apache.karaf.features/standard/4.0.0/xml/features
+karaf@root()> feature:repo-refresh
mvn:org.apache.karaf.features/standard/4.4.0/xml/features
+Refreshing feature url
mvn:org.apache.karaf.features/standard/4.4.0/xml/features
----
----
@@ -730,25 +746,25 @@ Using the `-i` option displays only installed features:
karaf@root()> feature:list -i
Name | Version | Required | State | Repository | Description
-------------------------------------------------------------------------------------------------------------------
-aries-proxy | 4.0.0 | | Started | standard-4.0.0 | Aries Proxy
-aries-blueprint | 4.0.0 | x | Started | standard-4.0.0 | Aries
Blueprint
-feature | 4.0.0 | x | Started | standard-4.0.0 | Features
Support
-shell | 4.0.0 | x | Started | standard-4.0.0 | Karaf Shell
-shell-compat | 4.0.0 | x | Started | standard-4.0.0 | Karaf Shell
Compatibility
-deployer | 4.0.0 | x | Started | standard-4.0.0 | Karaf
Deployer
-bundle | 4.0.0 | x | Started | standard-4.0.0 | Provide
Bundle support
-config | 4.0.0 | x | Started | standard-4.0.0 | Provide OSGi
ConfigAdmin support
-diagnostic | 4.0.0 | x | Started | standard-4.0.0 | Provide
Diagnostic support
-instance | 4.0.0 | x | Started | standard-4.0.0 | Provide
Instance support
-jaas | 4.0.0 | x | Started | standard-4.0.0 | Provide JAAS
support
-log | 4.0.0 | x | Started | standard-4.0.0 | Provide Log
support
-package | 4.0.0 | x | Started | standard-4.0.0 | Package
commands and mbeans
-service | 4.0.0 | x | Started | standard-4.0.0 | Provide
Service support
-system | 4.0.0 | x | Started | standard-4.0.0 | Provide
System support
-kar | 4.0.0 | x | Started | standard-4.0.0 | Provide KAR
(KARaf archive) support
-ssh | 4.0.0 | x | Started | standard-4.0.0 | Provide a
SSHd server on Karaf
-management | 4.0.0 | x | Started | standard-4.0.0 | Provide a
JMX MBeanServer and a set of MBeans in
-wrap | 0.0.0 | x | Started | standard-4.0.0 | Wrap URL
handler
+aries-proxy | 4.4.0 | | Started | standard-4.4.0 | Aries Proxy
+aries-blueprint | 4.4.0 | x | Started | standard-4.4.0 | Aries
Blueprint
+feature | 4.4.0 | x | Started | standard-4.4.0 | Features
Support
+shell | 4.4.0 | x | Started | standard-4.4.0 | Karaf Shell
+shell-compat | 4.4.0 | x | Started | standard-4.4.0 | Karaf Shell
Compatibility
+deployer | 4.4.0 | x | Started | standard-4.4.0 | Karaf
Deployer
+bundle | 4.4.0 | x | Started | standard-4.4.0 | Provide
Bundle support
+config | 4.4.0 | x | Started | standard-4.4.0 | Provide OSGi
ConfigAdmin support
+diagnostic | 4.4.0 | x | Started | standard-4.4.0 | Provide
Diagnostic support
+instance | 4.4.0 | x | Started | standard-4.4.0 | Provide
Instance support
+jaas | 4.4.0 | x | Started | standard-4.4.0 | Provide JAAS
support
+log | 4.4.0 | x | Started | standard-4.4.0 | Provide Log
support
+package | 4.4.0 | x | Started | standard-4.4.0 | Package
commands and mbeans
+service | 4.4.0 | x | Started | standard-4.4.0 | Provide
Service support
+system | 4.4.0 | x | Started | standard-4.4.0 | Provide
System support
+kar | 4.4.0 | x | Started | standard-4.4.0 | Provide KAR
(KARaf archive) support
+ssh | 4.4.0 | x | Started | standard-4.4.0 | Provide a
SSHd server on Karaf
+management | 4.4.0 | x | Started | standard-4.4.0 | Provide a
JMX MBeanServer and a set of MBeans in
+wrap | 0.0.0 | x | Started | standard-4.4.0 | Wrap URL
handler
----
===== `feature:install`
@@ -766,7 +782,7 @@ We can simulate an installation using `-t` or `--simulate`
option: it just displ
----
karaf@root()> feature:install -t -v eventadmin
-Adding features: eventadmin/[4.0.0,4.0.0]
+Adding features: eventadmin/[4.4.0,4.4.0]
No deployment change.
Managing bundle:
org.apache.felix.metatype / 1.0.12
@@ -775,7 +791,7 @@ No deployment change.
You can specify a feature version to install:
----
-karaf@root()> feature:install eventadmin/4.0.0
+karaf@root()> feature:install eventadmin/4.4.0
----
By default, the `feature:install` command is not verbose. If you want to have
some details about actions performed by the `feature:install`
@@ -783,7 +799,7 @@ command, you can use the `-v` option:
----
karaf@root()> feature:install -v eventadmin
-Adding features: eventadmin/[4.0.0,4.0.0]
+Adding features: eventadmin/[4.4.0,4.4.0]
No deployment change.
Done.
----
@@ -794,7 +810,7 @@ bundles, you can use the `-r` option:
----
karaf@root()> feature:install -v -r eventadmin
-Adding features: eventadmin/[4.0.0,4.0.0]
+Adding features: eventadmin/[4.4.0,4.4.0]
No deployment change.
Done.
----
diff --git a/manual/src/main/asciidoc/user-guide/urls.adoc
b/manual/src/main/asciidoc/user-guide/urls.adoc
index 347f68333f..611908b138 100644
--- a/manual/src/main/asciidoc/user-guide/urls.adoc
+++ b/manual/src/main/asciidoc/user-guide/urls.adoc
@@ -47,7 +47,7 @@ The equivalent of the above bundle would be:
In addition to being less verbose, the Maven url handlers can also resolve
snapshots and can use a local copy of the jar if one is available in your Maven
local repository.
The `org.ops4j.pax.url.mvn` bundle resolves `mvn` URLs. It can be configured
using the file `etc/org.ops4j.pax.url.mvn.cfg`.
-Full reference of `org.ops4j.pax.url.mvn` PID configuration can be found on
https://ops4j1.jira.com/wiki/display/paxurl/Aether+Configuration[the pax-web
Wiki page].
+Full reference of `org.ops4j.pax.url.mvn` PID configuration can be found on
https://ops4j1.jira.com/wiki/display/paxurl/Aether+Configuration[the pax-url
Wiki page].
The most important property is:
diff --git a/manual/src/main/asciidoc/user-guide/webcontainer.adoc
b/manual/src/main/asciidoc/user-guide/webcontainer.adoc
index aebdb3fc6a..b58c70614e 100644
--- a/manual/src/main/asciidoc/user-guide/webcontainer.adoc
+++ b/manual/src/main/asciidoc/user-guide/webcontainer.adoc
@@ -14,7 +14,7 @@
==== WebContainer (JSP/Servlet)
-Apache Karaf can act as a complete WebContainer, fully supporting the
JSP/Servlet specifications.
+Apache Karaf can act as a complete WebContainer, fully supporting the
JSP/Servlet/WebSockets specifications.
Apache Karaf WebContainer supports both:
@@ -27,6 +27,13 @@ To enable the Apache Karaf WebContainer, you just have to
install the `war` feat
karaf@root()> feature:install war
----
+However, `war` feature is just an alias for `pax-web-http-war` which itself
contains these Pax Web specific features:
+
+* pax-web-http-jetty - OSGi CMPN Http Service implementation using Jetty web
container
+* pax-web-war - OSGi CMPN Web Applications implementation (web container
agnostic)
+* pax-web-jsp - JSP support (no related OSGi CMPN specification)
+* pax-web-websockets - WebSockets support (no related OSGi CMPN specification)
+
[NOTE]
====
The installation of the `webconsole` feature automatically installs the `war`
feature.
@@ -40,8 +47,7 @@ The `war` feature provides:
===== Configuration
-The default port used by the WebContainer is 8181. Note: the connector is
actually bound only when at least a servlet or webapplication is using it.
-It means that just installing the `http` or `war` feature doesn't bind the
connector.
+The default port used by the WebContainer is 8181. In Pax Web 8, due to
internal refactoring, installation of this feature will automatically start the
web container without any web applications available.
By default, Karaf creates an internal Jetty connector that you can configure
via `etc/org.ops4j.pax.web.cfg`:
@@ -88,100 +94,130 @@ The default Apache Karaf WebContainer `etc/jetty.xml`
contains:
----
<?xml version="1.0"?>
<!--
- 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.
+
+ Copyright 2021 OPS4J.
+
+ Licensed 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.
+
-->
-<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//
-DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
-
-<Configure class="org.eclipse.jetty.server.Server">
-
- <!-- =========================================================== -->
- <!-- Set connectors -->
- <!-- =========================================================== -->
- <!-- One of each type! -->
- <!-- =========================================================== -->
-
- <!-- Use this connector for many frequently idle connections and for
- threadless continuations. -->
- <Call name="addConnector">
- <Arg>
- <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
- <Set name="host">
- <Property name="jetty.host" />
- </Set>
- <Set name="port">
- <Property name="jetty.port" default="8181" />
- </Set>
- <Set name="maxIdleTime">300000</Set>
- <Set name="Acceptors">2</Set>
- <Set name="statsOn">false</Set>
- <Set name="confidentialPort">8443</Set>
- <Set name="lowResourcesConnections">20000</Set>
- <Set name="lowResourcesMaxIdleTime">5000</Set>
- </New>
- </Arg>
- </Call>
-
- <!-- =========================================================== -->
- <!-- Configure Authentication Realms -->
- <!-- Realms may be configured for the entire server here, or -->
- <!-- they can be configured for a specific web app in a context -->
- <!-- configuration (see $(jetty.home)/contexts/test.xml for an -->
- <!-- example). -->
- <!-- =========================================================== -->
- <Call name="addBean">
- <Arg>
- <New class="org.eclipse.jetty.plus.jaas.JAASLoginService">
- <Set name="name">karaf</Set>
- <Set name="loginModuleName">karaf</Set>
- <Set name="roleClassNames">
- <Array type="java.lang.String">
-
<Item>org.apache.karaf.jaas.boot.principal.RolePrincipal
- </Item>
- </Array>
- </Set>
- </New>
- </Arg>
- </Call>
- <Call name="addBean">
- <Arg>
- <New class="org.eclipse.jetty.plus.jaas.JAASLoginService">
- <Set name="name">default</Set>
- <Set name="loginModuleName">karaf</Set>
- <Set name="roleClassNames">
- <Array type="java.lang.String">
-
<Item>org.apache.karaf.jaas.boot.principal.RolePrincipal
- </Item>
- </Array>
- </Set>
- </New>
- </Arg>
- </Call>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
"http://www.eclipse.org/jetty/configure_9_3.dtd">
+
+<!-- Object named "Server" of org.eclipse.jetty.server.Server class is
configured by pax-web-jetty -->
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+
+ <!-- =========================================================== -->
+ <!-- Set connectors -->
+ <!-- =========================================================== -->
+ <!-- One of each type! -->
+ <!-- =========================================================== -->
+
+ <!-- Use this connector for many frequently idle connections and for
+ threadless continuations. -->
+ <!-- <New id="httpConfig"
class="org.eclipse.jetty.server.HttpConfiguration">-->
+ <!-- <Set name="secureScheme">https</Set>-->
+ <!-- <Set name="securePort">-->
+ <!-- <Property name="jetty.secure.port"
default="8443" />-->
+ <!-- </Set>-->
+ <!-- <Set name="outputBufferSize">32768</Set>-->
+ <!-- <Set name="requestHeaderSize">8192</Set>-->
+ <!-- <Set name="responseHeaderSize">8192</Set>-->
+ <!-- <Set name="sendServerVersion">true</Set>-->
+ <!-- <Set name="sendDateHeader">false</Set>-->
+ <!-- <Set name="headerCacheSize">512</Set>-->
+ <!-- </New>-->
+
+ <!-- =========================================================== -->
+ <!-- Special server connectors -->
+ <!-- =========================================================== -->
+ <!-- This is a sample for alternative connectors, enable if needed -->
+ <!-- =========================================================== -->
+ <!--
+ <Call name="addConnector">
+ <Arg>
+ <New class="org.eclipse.jetty.server.ServerConnector">
+ <Arg name="server">
+ <Ref refid="Server" />
+ </Arg>
+ <Arg name="factories">
+ <Array
type="org.eclipse.jetty.server.ConnectionFactory">
+ <Item>
+ <New
class="org.eclipse.jetty.server.HttpConnectionFactory">
+ <Arg
name="config">
+ <Ref
refid="httpConfig" />
+ </Arg>
+ </New>
+ </Item>
+ </Array>
+ </Arg>
+ <Set name="host">
+ <Property name="jetty.host"
default="localhost" />
+ </Set>
+ <Set name="port">
+ <Property name="jetty.port"
default="8282" />
+ </Set>
+ <Set name="idleTimeout">
+ <Property name="http.timeout"
default="30000" />
+ </Set>
+ <Set name="name">jettyConn1</Set>
+ </New>
+ </Arg>
+ </Call>
+ -->
+
+ <!-- =========================================================== -->
+ <!-- Configure Authentication Realms -->
+ <!-- Realms may be configured for the entire server here, or -->
+ <!-- they can be configured for a specific web app in a context -->
+ <!-- configuration (see $(jetty.home)/contexts/test.xml for an -->
+ <!-- example). -->
+ <!-- =========================================================== -->
+ <!--
+ <Call name="addBean">
+ <Arg>
+ <New class="org.eclipse.jetty.jaas.JAASLoginService">
+ <Set name="name">karaf</Set>
+ <Set name="loginModuleName">karaf</Set>
+ <Set name="roleClassNames">
+ <Array type="java.lang.String">
+
<Item>org.apache.karaf.jaas.boot.principal.RolePrincipal</Item>
+ </Array>
+ </Set>
+ </New>
+ </Arg>
+ </Call>
+ <Call name="addBean">
+ <Arg>
+ <New class="org.eclipse.jetty.jaas.JAASLoginService">
+ <Set name="name">default</Set>
+ <Set name="loginModuleName">karaf</Set>
+ <Set name="roleClassNames">
+ <Array type="java.lang.String">
+
<Item>org.apache.karaf.jaas.boot.principal.RolePrincipal</Item>
+ </Array>
+ </Set>
+ </New>
+ </Arg>
+ </Call>
+ -->
</Configure>
----
-The `SelectChannelConnector` defines the default connector of the WebContainer.
+Pax Web 8 reads `org.ops4j.pax.web` PID configuration which ensures that the
default (and secure - if enabled) connetors are running even if there's no
specific connector defined in `etc/jetty.xml`.
-This connector defines the 8181 port number for the HTTP protocol (`port`
property), and the 8443 port number for the
-HTTPS protocol (`confidentialPort` property).
+The above XML configuration contains (disabled by default) `<Call
name="addConnector">` element which shows how to configure additional connector.
-By default, Apache Karaf bind these ports on all network interfaces
(`0.0.0.0`). You can config the `host` property
+By default, Apache Karaf bind these ports on all network interfaces
(`0.0.0.0`). You can config the `jetty.host` property
to bind on a specific network interface (with a given IP address).
The following resources give you details about advanced `etc/jetty.xml`
configurations:
@@ -204,7 +240,7 @@ A WAB is a standard WAR or JAR archive containing at least
the following propert
* `Bundle-ManifestVersion: 2` defines that the bundle follows the rules of R4
specification.
* `Bundle-SymbolicName` specifies a unique, non-localizable name for the
bundle. This name should be based on the
reverse domain name convention.
-* `Web-ContextPath` specifies the location of the web application.
+* `Web-ContextPath` specifies the context path (must start with `/`) of the
web application.
WAB can be deployed directly in Apache Karaf, for instance, by dropping the
archive in the `deploy` folder, or using the
`bundle:install` command.
@@ -212,7 +248,58 @@ WAB can be deployed directly in Apache Karaf, for
instance, by dropping the arch
For instance, the Apache Karaf manual (documentation) is available as a WAB
that you can deploy directly in a running instance:
----
-karaf@root()> bundle:install -s mvn:org.apache.karaf/manual/4.0.0/war
+karaf@root()> bundle:install -s mvn:org.apache.karaf/manual/4.4.0
+----
+
+When `pax-web-karaf` feature is installed, there are new commands available
and we can already investigate the details about just installed WAB. For
example we can see high-level overview of the deployed WABs - together with
context path and base URL (which is calculated based on actual information from
`org.ops4j.pax.web` PID).
+
+[source,options="nowrap"]
+----
+karaf@root()> web:wab-list
+Context Path │ Bundle ID │ Symbolic Name │ State │ Base URL
+───────────────┼───────────┼─────────────────────────┼──────────┼────────────────────────────────────
+/documentation │ 72 │ org.apache.karaf.manual │ Deployed │
http://127.0.0.1:8181/documentation
+----
+
+We can see the details about selected WAB:
+
+[source,options="nowrap"]
+----
+karaf@root()> web:wab-info 72
+
+Apache Karaf :: Manual (72)
+---------------------------
+Context Path: /documentation
+Deployment State: Deployed
+WAB ClassPath:
+ - bundle://57d1482b-7ade-42b4-950a-f81d26159dda_72.0:0/
+ServletContainerInitializers:
+ - org.ops4j.pax.web.jsp.JasperInitializer
+Container web fragments (reachable bundles without /META-INF/web-fragment.xml):
+ - (70) org.ops4j.pax.web.pax-web-jsp/8.0.2
+----
+
+`web:context-list` shows information of the web contexts (those created for
web applications, but also the ones related to HttpService and Whiteboard web
elements):
+
+[source,options="nowrap"]
+----
+karaf@root()> web:context-list
+Bundle ID │ Symbolic Name │ Context Path │ Context Name │ Rank │
Service ID │ Type │ Scope │ Registration Properties
+──────────┼─────────────────────────┼────────────────┼────────────────┼──────┼────────────┼──────┼─────────┼─────────────────────────────────────────────────
+72 │ org.apache.karaf.manual │ /documentation │ /documentation │ MAX │
0 │ WAB │ static* │ osgi.http.whiteboard.context.path=/documentation
+
+*) This context is using ServletContextHelper/HttpContext without resolving an
org.osgi.framework.ServiceReference.
+----
+
+Finally, `web:servlet-list` shows all the servlets for all deployed web
applications:
+
+[source,options="nowrap"]
+----
+karaf@root()> web:servlet-list
+Bundle ID │ Name │ Class
│ Context Path(s) │ URLs │ Type │ Context Filter
+──────────┼─────────┼─────────────────────────────────────────────────────────────────────┼─────────────────┼───────────────┼──────┼───────────────
+72 │ default │
org.ops4j.pax.web.service.tomcat.internal.web.TomcatResourceServlet │
/documentation │ / │ WAB │ -
+72 │ jsp │ org.ops4j.pax.web.jsp.JspServlet
│ /documentation │ *.jspx, *.jsp │ WAB │ -
----
====== WAR (WebApplication aRchive)
@@ -223,8 +310,27 @@ Using the `webbundle` prefix and providing headers
directly on the URL, Apache K
For instance, you can deploy the Apache Tomcat sample non-OSGi "classical" WAR
with the following command:
+[source,options="nowrap"]
----
-karaf@root()> bundle:install -s
"webbundle:http://tomcat.apache.org/tomcat-7.0-doc/appdev/sample/sample.war?Bundle-SymbolicName=tomcat-sample&Web-ContextPath=/sample"
+karaf@root()> bundle:install -s
"webbundle:https://tomcat.apache.org/tomcat-9.0-doc/appdev/sample/sample.war?Bundle-SymbolicName=tomcat-sample&Web-ContextPath=/tomcat-docs"
+Bundle ID: 76
+karaf@root()> web:wab-list
+Context Path │ Bundle ID │ Symbolic Name │ State │ Base URL
+───────────────┼───────────┼─────────────────────────┼──────────┼────────────────────────────────────
+/documentation │ 72 │ org.apache.karaf.manual │ Deployed │
http://127.0.0.1:8181/documentation
+/tomcat-docs │ 76 │ tomcat-sample │ Deployed │
http://127.0.0.1:8181/tomcat-docs
+karaf@root()> web:wab-info 76
+
+tomcat-sample (76)
+------------------
+Context Path: /tomcat-docs
+Deployment State: Deployed
+WAB ClassPath:
+ - bundle://57d1482b-7ade-42b4-950a-f81d26159dda_76.0:0/WEB-INF/classes/
+ServletContainerInitializers:
+ - org.ops4j.pax.web.jsp.JasperInitializer
+Container web fragments (reachable bundles without /META-INF/web-fragment.xml):
+ - (70) org.ops4j.pax.web.pax-web-jsp/8.0.2
----
You can note the `webbundle` prefix, and the `Bundle-SymbolicName` and
`Web-ContextPath` headers on the URL.
@@ -238,61 +344,52 @@ You can use the Karaf `ProxyService` programmatically, or
via the corresponding
===== Commands
-====== `http:list`
+NOTE: This part of documentation is new for Karaf 4.4.0 with Pax Web 8.
-The `http:list` lists the available Servlets deployed in the WebContainer.
+====== `web:servlet-list`
+
+The `web:servlet-list` (previously `http:list`) lists the available Servlets
deployed in the WebContainer.
For instance, if you have installed the Apache Karaf WebConsole, you can see
the WebConsole Servlets:
+[source,options="nowrap"]
----
-karaf@root()> http:list
-ID | Servlet | Servlet-Name | State | Alias |
Url
------------------------------------------------------------------------------------------------------
-113 | ResourceServlet | /res | Deployed | /system/console/res |
[/system/console/res/*]
-113 | KarafOsgiManager | ServletModel-2 | Undeployed | /system/console |
[/system/console/*]
-113 | KarafOsgiManager | ServletModel-5 | Deployed | /system/console |
[/system/console/*]
+karaf@root()> web:servlet-list
+Bundle ID │ Name │
Class │ Context
Path(s) │ URLs │ Type │ Context Filter
+──────────┼───────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────┼─────────────────┼───────────────────────┼─────────────┼───────────────
+93 │ default-d975426d-f19e-4b5a-a889-80603beb34c9 │
org.ops4j.pax.web.service.jetty.internal.web.JettyResourceServlet │ /
│ /system/console/res/* │ HttpService │ -
+93 │ org.apache.felix.webconsole.internal.servlet.KarafOsgiManager │
org.apache.felix.webconsole.internal.servlet.KarafOsgiManager │ /
│ /system/console/* │ HttpService │ -
----
-The `ID` is the ID of the bundle which provides the servlet (`113` here).
-
-The `State` is the current state of the Servlet (`Deployed` or `Undeployed`).
+The `Bundle ID` is the ID of the bundle which provides the servlet (`93` here).
-The `Url` is the URL where the Servlet is available.
+The `Name` and `Class` show name and FQCN of the servlet.
-====== `web:list`
+The `Context Path(s)` column shows the main context path that hosts the
servlet.
-The `web:list` command lists the WebApplication Bundles ("native" WAB or
"wrapped WAR") deployed in the WebContainer.
+The `URLs` shows the mapping URI patterns defined for the Servlet.
-For instance, if you installed the Apache Karaf manual WAR file as described
previously, you can see it with `web:list`:
+`Type` column shows the source of servlet registration (can be `WAB`,
`HttpService` or `Whiteboard`).
-----
-karaf@root()> web:list
-ID | State | Web-State | Level | Web-ContextPath | Name
----------------------------------------------------------------------------------------------------
-111 | Active | Deployed | 80 | /karaf-doc | Apache Karaf ::
Manual (4.0.0)
-----
+Finally `Context Filter` shows the Whiteboard context selection filter for the
servlet.
-====== `web:stop`
+====== `web:wab-list`
-The `web:stop` command stops a web application in the WebContainer. The
`web:stop` command expects a `id` argument
-corresponding to the bundle ID (as displayed by the `web:list` command).
+The `web:wab-list` (previously `web:list`) command lists the WebApplication
Bundles ("native" WAB or "wrapped WAR") deployed in the WebContainer.
-For instance, to stop the Apache Karaf manual web application:
+For instance, if you installed the Apache Karaf manual WAR file as described
previously, you can see it with `web:wab-list`:
+[source,options="nowrap"]
----
-karaf@root()> web:stop 111
+karaf@root()> web:wab-list
+Context Path │ Bundle ID │ Symbolic Name │ State │ Base URL
+───────────────┼───────────┼─────────────────────────┼──────────┼────────────────────────────────────
+/documentation │ 72 │ org.apache.karaf.manual │ Deployed │
http://127.0.0.1:8181/documentation
----
-====== `web:start`
+====== `web:start` and `web:stop`
-The `web:start` command starts a web application in the WebContainer. The
`web:start` command expects a `id` argument
-corresponding to the bundle ID (as displayed by the `web:list` command).
-
-For instance, to start the Apache Karaf manual web application:
-
-----
-karaf@root()> web:start 111
-----
+These two commands were removed from Karaf 4.4 because Pax Web 8 conforms
fully to OSGi CMPN Web Applications specification. A WAB associated with bundle
has a lifecycle tied to the lifecycle of the bundle. To stop a web application,
one has to stop the bundle.
====== `http:proxy-list`
@@ -360,11 +457,12 @@ The ObjectName to use is
`org.apache.karaf:type=http,name=*`.
The `Servlets` attribute provides a tabular data providing the list of
deployed Servlets including:
-* `Alias` is the Servlet URL alias.
* `Bundle-ID` is the ID of the bundle which provides this Servlet.
+* `Context-Path` is the context path(s) of the target web application.
* `Servlet` is the class name of the Servlet.
-* `State` is the current Servlet state (`Deployed` or `Undeployed`).
-* `URL` is the URL of the Servlet (the Servlet context path).
+* `Servlet Name` is the name of the Servlet.
+* `Type` is the Servlet type indicating its origin (HttpService, Whiteboard or
WAB)
+* `URL` is the list of URL mappings of the Servlet.
The `Proxies` attribute provides a tabular data providing the list of HTTP
proxies including:
@@ -389,6 +487,7 @@ The ObjectName to use is `org.apache.karaf:type=web,name=*`.
The `WebBundles` attribute provides a tabular data providing the list of
deployed Web Applications including:
+* `Context Name` is the name of the web context used by the Web Application.
* `ID` is the ID of the bundle providing the Web Application.
* `Level` is the bundle start level.
* `Name` is the bundle symbolic name providing the Web Application.
diff --git a/pom.xml b/pom.xml
index fb385c4bfd..a4423deab5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -300,6 +300,7 @@
<org.osgi.service.metatype.version>1.4.1</org.osgi.service.metatype.version>
<org.osgi.service.namespace.version>1.0.0</org.osgi.service.namespace.version>
<org.osgi.service.repository.version>1.1.0</org.osgi.service.repository.version>
+ <org.osgi.util.function.version>1.2.0</org.osgi.util.function.version>
<org.osgi.util.promise.version>1.2.0</org.osgi.util.promise.version>
<pax.cdi.version>1.1.4</pax.cdi.version>
@@ -308,7 +309,7 @@
<pax.base.version>1.5.1</pax.base.version>
<pax.swissbox.version>1.8.5</pax.swissbox.version>
<pax.url.version>2.6.10</pax.url.version>
- <pax.web.version>7.3.23</pax.web.version>
+ <pax.web.version>8.0.2</pax.web.version>
<pax.tinybundle.version>3.0.0</pax.tinybundle.version>
<pax.jdbc.version>1.5.3</pax.jdbc.version>
<pax.jms.version>1.1.0</pax.jms.version>
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 3a599263cb..04db023ce2 100644
--- a/web/src/main/java/org/apache/karaf/web/WebContainerService.java
+++ b/web/src/main/java/org/apache/karaf/web/WebContainerService.java
@@ -18,6 +18,8 @@ package org.apache.karaf.web;
import java.util.List;
+import org.ops4j.pax.web.service.spi.model.info.WebApplicationInfo;
+
/**
* Describe the WebContainer service.
*/
@@ -29,7 +31,7 @@ public interface WebContainerService {
* @return the list of web bundles.
* @throws Exception in case of listing failure.
*/
- List<WebBundle> list() throws Exception;
+ List<WebApplicationInfo> list() throws Exception;
/**
* Helper method to create a webbundle location and install the bundle.
@@ -80,6 +82,6 @@ public interface WebContainerService {
* @param id The ID of the bundle.
* @return The web context associated with the given bundle.
*/
- String getWebContextPath(Long id);
+ String getWebContextPath(Long id) throws Exception;
}
diff --git a/web/src/main/java/org/apache/karaf/web/commands/List.java
b/web/src/main/java/org/apache/karaf/web/commands/List.java
deleted file mode 100644
index a862a4515e..0000000000
--- a/web/src/main/java/org/apache/karaf/web/commands/List.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.Col;
-import org.apache.karaf.shell.support.table.ShellTable;
-import org.apache.karaf.web.WebBundle;
-import org.apache.karaf.web.WebContainerService;
-
-@Command(scope = "web", name = "list", description = "Lists details for war
bundles.")
-@Service
-public class List implements Action {
-
- @Option(name = "--no-format", description = "Disable table rendered
output", required = false, multiValued = false)
- boolean noFormat;
-
- @Reference
- private WebContainerService webContainerService;
-
- public void setWebContainerService(WebContainerService
webContainerService) {
- this.webContainerService = webContainerService;
- }
-
- @Override
- public Object execute() throws Exception {
- ShellTable table = new ShellTable();
- table.column(new Col("ID"));
- table.column(new Col("State"));
- table.column(new Col("Web-State"));
- table.column(new Col("Level"));
- table.column(new Col("Web-ContextPath"));
- table.column(new Col("Name"));
-
- java.util.List<WebBundle> webBundles = webContainerService.list();
- if (webBundles != null && !webBundles.isEmpty()) {
- for (WebBundle webBundle : webBundles) {
- table.addRow().addContent(
- webBundle.getBundleId(),
- webBundle.getState(),
- webBundle.getWebState(),
- webBundle.getLevel(),
- webBundle.getContextPath(),
- webBundle.getName());
- }
-
- }
- table.print(System.out, !noFormat);
- return null;
- }
-
-}
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 b0d06b570a..1fe16ed6de 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
@@ -16,102 +16,52 @@
*/
package org.apache.karaf.web.internal;
-import org.apache.karaf.web.WebBundle;
import org.apache.karaf.web.WebContainerService;
-import org.ops4j.pax.web.service.spi.WarManager;
-import org.ops4j.pax.web.service.spi.WebEvent;
+import org.ops4j.pax.web.service.WebContainer;
+import org.ops4j.pax.web.service.spi.model.info.WebApplicationInfo;
+import org.ops4j.pax.web.service.spi.model.views.ReportWebContainerView;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleListener;
-import org.osgi.framework.Constants;
-import org.osgi.framework.startlevel.BundleStartLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Implementation of the WebContainer service.
*/
-public class WebContainerServiceImpl implements WebContainerService,
BundleListener {
+public class WebContainerServiceImpl implements WebContainerService {
private BundleContext bundleContext;
- private WebEventHandler webEventHandler;
- private WarManager warManager;
-
+ private WebContainer webContainer;
+
private static final Logger LOGGER =
LoggerFactory.getLogger(WebContainerServiceImpl.class);
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
-
- public void setWebEventHandler(WebEventHandler webEventHandler) {
- this.webEventHandler = webEventHandler;
- }
- public void setWarManager(WarManager warManager) {
- this.warManager = warManager;
+ public void setWebContainer(WebContainer webContainer) {
+ this.webContainer = webContainer;
}
@Override
- public void bundleChanged(BundleEvent bundleEvent) {
- if (bundleEvent.getType() == BundleEvent.UNINSTALLED
- || bundleEvent.getType() == BundleEvent.UNRESOLVED
- || bundleEvent.getType() == BundleEvent.STOPPED) {
-
webEventHandler.getBundleEvents().remove(bundleEvent.getBundle().getBundleId());
+ public List<WebApplicationInfo> list() throws Exception {
+ if (webContainer == null) {
+ return Collections.emptyList();
}
- }
-
- @Override
- public List<WebBundle> list() throws Exception {
- Bundle[] bundles = bundleContext.getBundles();
- Map<Long, WebEvent> bundleEvents = webEventHandler.getBundleEvents();
- List<WebBundle> webBundles = new ArrayList<>();
- if (bundles != null) {
- for (Bundle bundle : bundles) {
- // first check if the bundle is a web bundle
- String contextPath =
bundle.getHeaders().get("Web-ContextPath");
- if (contextPath == null) {
- contextPath = bundle.getHeaders().get("Webapp-Context");
// this one used by pax-web but is deprecated
- }
- if (contextPath == null) {
- // the bundle is not a web bundle
- continue;
- }
-
- WebBundle webBundle = new WebBundle();
- contextPath = contextPath.trim();
-
- // get the bundle name
- String name = bundle.getHeaders().get(Constants.BUNDLE_NAME);
- // if there is no name, then default to symbolic name
- name = (name == null) ? bundle.getSymbolicName() : name;
- // if there is no symbolic name, resort to location
- name = (name == null) ? bundle.getLocation() : name;
- // get the bundle version
- String version =
bundle.getHeaders().get(Constants.BUNDLE_VERSION);
- name = ((version != null)) ? name + " (" + version + ")" :
name;
- long bundleId = bundle.getBundleId();
- int level =
bundle.adapt(BundleStartLevel.class).getStartLevel();
- if (!contextPath.startsWith("/")) {
- contextPath = "/" + contextPath;
- }
-
- webBundle.setBundleId(bundleId);
- webBundle.setName(name);
- webBundle.setContextPath(contextPath);
- webBundle.setLevel(level);
- webBundle.setState(getStateString(bundle));
- webBundle.setWebState(state(bundle.getBundleId()));
-
- webBundles.add(webBundle);
- }
+ ReportWebContainerView view =
webContainer.adapt(ReportWebContainerView.class);
+ if (view == null) {
+ return Collections.emptyList();
}
-
- return webBundles;
+
+ Set<WebApplicationInfo> webBundles = view.listWebApplications();
+ return new ArrayList<>(webBundles);
}
@Override
@@ -123,17 +73,20 @@ public class WebContainerServiceImpl implements
WebContainerService, BundleListe
@Override
public void uninstall(List<Long> bundleIds) throws Exception {
+ List<WebApplicationInfo> apps = list();
+ Map<Long, Bundle> mapping = new HashMap<>();
+ for (WebApplicationInfo app : apps) {
+ mapping.put(app.getBundle().getBundleId(), app.getBundle());
+ }
+
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);
- }
+ Bundle bundle = mapping.get(bundleId);
+ if (bundle != null) {
+ bundle.uninstall();
+ } else {
+ System.out.println("Bundle ID " + bundleId + " is
invalid");
+ LOGGER.warn("Bundle ID {} is invalid", bundleId);
}
}
}
@@ -142,17 +95,21 @@ public class WebContainerServiceImpl implements
WebContainerService, BundleListe
@Override
public void start(List<Long> bundleIds) throws Exception {
if (bundleIds != null && !bundleIds.isEmpty()) {
+ List<WebApplicationInfo> apps = list();
+ Map<Long, Bundle> mapping = new HashMap<>();
+ for (WebApplicationInfo app : apps) {
+ mapping.put(app.getBundle().getBundleId(), app.getBundle());
+ }
for (long bundleId : bundleIds) {
- if (webEventHandler.getBundleEvents().containsKey(bundleId)) {
- WebEvent webEvent =
webEventHandler.getBundleEvents().get(bundleId);
- Bundle bundle = webEvent.getBundle();
- if (bundle != null) {
- // deploy
- warManager.start(bundleId, null);
- } else {
- System.out.println("Bundle ID " + bundleId + " is
invalid");
- LOGGER.warn("Bundle ID {} is invalid", bundleId);
- }
+ Bundle bundle = mapping.get(bundleId);
+ if (bundle != null) {
+ // deploy
+ // TOCHECK: Pax Web has no "War Manager", so WAB == Bundle
and we can't have started Bundle without
+ // started WAB
+ bundle.start();
+ } else {
+ System.out.println("Bundle ID " + bundleId + " is
invalid");
+ LOGGER.warn("Bundle ID {} is invalid", bundleId);
}
}
}
@@ -161,52 +118,34 @@ public class WebContainerServiceImpl implements
WebContainerService, BundleListe
@Override
public void stop(List<Long> bundleIds) throws Exception {
if (bundleIds != null && !bundleIds.isEmpty()) {
+ List<WebApplicationInfo> apps = list();
+ Map<Long, Bundle> mapping = new HashMap<>();
+ for (WebApplicationInfo app : apps) {
+ mapping.put(app.getBundle().getBundleId(), app.getBundle());
+ }
for (long bundleId : bundleIds) {
- if (webEventHandler.getBundleEvents().containsKey(bundleId)) {
- WebEvent webEvent =
webEventHandler.getBundleEvents().get(bundleId);
- Bundle bundle = webEvent.getBundle();
- if (bundle != null) {
- // deploy
- warManager.stop(bundleId);
- } else {
- System.out.println("Bundle ID " + bundleId + " is
invalid");
- LOGGER.warn("Bundle ID {} is invalid", bundleId);
- }
+ Bundle bundle = mapping.get(bundleId);
+ if (bundle != null) {
+ // undeploy
+ // TOCHECK: Pax Web has no "War Manager", so WAB == Bundle
and we can't have started Bundle without
+ // started WAB
+ bundle.stop();
+ } else {
+ System.out.println("Bundle ID " + bundleId + " is
invalid");
+ LOGGER.warn("Bundle ID {} is invalid", bundleId);
}
}
}
}
@Override
- public String state(long bundleId) {
-
- Map<Long, WebEvent> bundleEvents = webEventHandler.getBundleEvents();
+ public String state(long bundleId) throws Exception {
+ List<WebApplicationInfo> apps = list();
+ Map<Long, Bundle> mapping = new HashMap<>();
StringBuilder topic = new StringBuilder("Unknown ");
-
- if (bundleEvents.containsKey(bundleId)) {
- WebEvent webEvent = bundleEvents.get(bundleId);
-
- switch(webEvent.getType()) {
- case WebEvent.DEPLOYING:
- topic = new StringBuilder("Deploying ");
- break;
- case WebEvent.DEPLOYED:
- topic = new StringBuilder("Deployed ");
- break;
- case WebEvent.UNDEPLOYING:
- topic = new StringBuilder("Undeploying");
- break;
- case WebEvent.UNDEPLOYED:
- topic = new StringBuilder("Undeployed ");
- break;
- case WebEvent.FAILED:
- topic = new StringBuilder("Failed ");
- break;
- case WebEvent.WAITING:
- topic = new StringBuilder("Waiting ");
- break;
- default:
- topic = new StringBuilder("Failed ");
+ for (WebApplicationInfo app : apps) {
+ if (bundleId == app.getBundle().getBundleId()) {
+ topic = new StringBuilder(app.getDeploymentState());
}
}
@@ -217,36 +156,16 @@ public class WebContainerServiceImpl implements
WebContainerService, BundleListe
return topic.toString();
}
- /**
- * Return a string representation of the bundle state.
- *
- * TODO use an util method provided by bundle core
- *
- * @param bundle the target bundle.
- * @return the string representation of the state
- */
- private String getStateString(Bundle bundle) {
- int state = bundle.getState();
- if (state == Bundle.ACTIVE) {
- return "Active ";
- } else if (state == Bundle.INSTALLED) {
- return "Installed ";
- } else if (state == Bundle.RESOLVED) {
- return "Resolved ";
- } else if (state == Bundle.STARTING) {
- return "Starting ";
- } else if (state == Bundle.STOPPING) {
- return "Stopping ";
- } else {
- return "Unknown ";
- }
- }
-
@Override
- public String getWebContextPath(Long id) {
- Map<Long, WebEvent> bundleEvents =
webEventHandler.getBundleEvents();
- WebEvent webEvent = bundleEvents.get(id);
- return webEvent.getContextPath();
+ public String getWebContextPath(Long id) throws Exception {
+ List<WebApplicationInfo> apps = list();
+ Map<Long, Bundle> mapping = new HashMap<>();
+ for (WebApplicationInfo app : apps) {
+ if (id == app.getBundle().getBundleId()) {
+ return app.getContextPath();
+ }
+ }
+ return "";
}
}
diff --git
a/web/src/main/java/org/apache/karaf/web/internal/WebEventHandler.java
b/web/src/main/java/org/apache/karaf/web/internal/WebEventHandler.java
deleted file mode 100644
index e91395cef1..0000000000
--- a/web/src/main/java/org/apache/karaf/web/internal/WebEventHandler.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.internal;
-
-import org.ops4j.pax.web.service.spi.WebEvent;
-import org.ops4j.pax.web.service.spi.WebListener;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Class implementing {@link WebListener} service to retrieve {@link WebEvent}.
- */
-public class WebEventHandler implements WebListener {
-
- private final Map<Long, WebEvent> bundleEvents = new HashMap<>();
-
- public Map<Long, WebEvent> getBundleEvents() {
- return bundleEvents;
- }
-
- public void webEvent(WebEvent event) {
- getBundleEvents().put(event.getBundle().getBundleId(), event);
- }
-
-}
diff --git
a/web/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java
b/web/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java
index db1ee64222..c31dc5923d 100644
--- a/web/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java
+++ b/web/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java
@@ -22,13 +22,11 @@ import
org.apache.karaf.util.tracker.annotation.RequireService;
import org.apache.karaf.util.tracker.annotation.Services;
import org.apache.karaf.web.WebContainerService;
import org.apache.karaf.web.internal.WebContainerServiceImpl;
-import org.apache.karaf.web.internal.WebEventHandler;
import org.apache.karaf.web.management.internal.WebMBeanImpl;
-import org.ops4j.pax.web.service.spi.WarManager;
-import org.ops4j.pax.web.service.spi.WebListener;
+import org.ops4j.pax.web.service.WebContainer;
@Services(
- requires = @RequireService(WarManager.class),
+ requires = @RequireService(WebContainer.class),
provides = @ProvideService(WebContainerService.class)
)
public class Activator extends BaseActivator {
@@ -37,19 +35,14 @@ public class Activator extends BaseActivator {
@Override
protected void doStart() throws Exception {
- WarManager warManager = getTrackedService(WarManager.class);
- if (warManager == null) {
+ WebContainer webContainer = getTrackedService(WebContainer.class);
+ if (webContainer == null) {
return;
}
- WebEventHandler webEventHandler = new WebEventHandler();
- register(WebListener.class, webEventHandler);
-
webContainerService = new WebContainerServiceImpl();
- bundleContext.addBundleListener(webContainerService);
webContainerService.setBundleContext(bundleContext);
- webContainerService.setWarManager(warManager);
- webContainerService.setWebEventHandler(webEventHandler);
+ webContainerService.setWebContainer(webContainer);
register(WebContainerService.class, webContainerService);
WebMBeanImpl webMBean = new WebMBeanImpl();
@@ -60,7 +53,6 @@ public class Activator extends BaseActivator {
@Override
protected void doStop() {
if (webContainerService != null) {
- bundleContext.removeBundleListener(webContainerService);
webContainerService = null;
}
super.doStop();
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 239e39be24..f27aa9799e 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
@@ -16,9 +16,12 @@
*/
package org.apache.karaf.web.management.internal;
-import org.apache.karaf.web.WebBundle;
import org.apache.karaf.web.WebContainerService;
import org.apache.karaf.web.management.WebMBean;
+import org.ops4j.pax.web.service.spi.model.info.WebApplicationInfo;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.startlevel.BundleStartLevel;
import javax.management.MBeanException;
import javax.management.NotCompliantMBeanException;
@@ -46,27 +49,47 @@ public class WebMBeanImpl extends StandardMBean implements
WebMBean {
public TabularData getWebBundles() throws MBeanException {
try {
CompositeType webType = new CompositeType("Web Bundle", "An OSGi
Web bundle",
- new String[]{"ID", "State", "Web-State", "Level",
"Web-ContextPath", "Name"},
+ new String[]{"ID", "Context Name", "State", "Web-State",
"Level", "Web-ContextPath", "Name"},
new String[]{"ID of the bundle",
+ "Name of the context",
"OSGi state of the bundle",
"Web state of the bundle",
"Start level of the bundle",
"Web context path",
"Name of the bundle"},
- new OpenType[]{SimpleType.LONG, SimpleType.STRING,
SimpleType.STRING, SimpleType.INTEGER, SimpleType.STRING, SimpleType.STRING});
+ new OpenType[]{SimpleType.LONG, SimpleType.STRING,
SimpleType.STRING, SimpleType.STRING, SimpleType.INTEGER, SimpleType.STRING,
SimpleType.STRING});
TabularType tableType = new TabularType("Web Bundles", "Table of
web bundles", webType,
- new String[]{"ID"});
+ new String[]{"ID", "Context Name"});
TabularData table = new TabularDataSupport(tableType);
- for (WebBundle webBundle : webContainerService.list()) {
+ for (WebApplicationInfo webBundle : webContainerService.list()) {
+ String contextPath = webBundle.getContextPath();
+ String contextName = webBundle.getName();
+
+ // get the bundle name
+ String name =
webBundle.getBundle().getHeaders().get(Constants.BUNDLE_NAME);
+ // if there is no name, then default to symbolic name
+ name = (name == null) ?
webBundle.getBundle().getSymbolicName() : name;
+ // if there is no symbolic name, resort to location
+ name = (name == null) ? webBundle.getBundle().getLocation() :
name;
+ // get the bundle version
+ String version =
webBundle.getBundle().getHeaders().get(Constants.BUNDLE_VERSION);
+ name = ((version != null)) ? name + " (" + version + ")" :
name;
+ long bundleId = webBundle.getBundle().getBundleId();
+ int level =
webBundle.getBundle().adapt(BundleStartLevel.class).getStartLevel();
+ if (!contextPath.startsWith("/")) {
+ contextPath = "/" + contextPath;
+ }
+
try {
CompositeData data = new CompositeDataSupport(webType,
- new String[]{"ID", "State", "Web-State", "Level",
"Web-ContextPath", "Name"},
- new Object[]{webBundle.getBundleId(),
- webBundle.getState(),
- webBundle.getWebState(),
- webBundle.getLevel(),
- webBundle.getContextPath(),
- webBundle.getName()});
+ new String[]{"ID", "Context Name", "State",
"Web-State", "Level", "Web-ContextPath", "Name"},
+ new Object[]{webBundle.getBundle().getBundleId(),
+ contextName,
+ getStateString(webBundle.getBundle()),
+ webBundle.getDeploymentState(),
+ level,
+ contextPath,
+ name});
table.put(data);
} catch (Exception e) {
e.printStackTrace();
@@ -147,4 +170,29 @@ public class WebMBeanImpl extends StandardMBean implements
WebMBean {
}
}
+ /**
+ * Return a string representation of the bundle state.
+ *
+ * TODO use an util method provided by bundle core
+ *
+ * @param bundle the target bundle.
+ * @return the string representation of the state
+ */
+ private String getStateString(Bundle bundle) {
+ int state = bundle.getState();
+ if (state == Bundle.ACTIVE) {
+ return "Active ";
+ } else if (state == Bundle.INSTALLED) {
+ return "Installed ";
+ } else if (state == Bundle.RESOLVED) {
+ return "Resolved ";
+ } else if (state == Bundle.STARTING) {
+ return "Starting ";
+ } else if (state == Bundle.STOPPING) {
+ return "Stopping ";
+ } else {
+ return "Unknown ";
+ }
+ }
+
}
diff --git
a/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/Activator.java
b/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/Activator.java
index e6a115e9dc..ac609021eb 100644
---
a/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/Activator.java
+++
b/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/Activator.java
@@ -24,15 +24,15 @@ import org.apache.karaf.http.core.ProxyService;
import org.apache.karaf.util.tracker.BaseActivator;
import org.apache.karaf.util.tracker.annotation.RequireService;
import org.apache.karaf.util.tracker.annotation.Services;
-import org.ops4j.pax.web.service.spi.ServletListener;
-import org.ops4j.pax.web.service.spi.WebListener;
+import org.ops4j.pax.web.service.WebContainer;
-@Services(requires = @RequireService(ProxyService.class))
+@Services(requires = {
+ @RequireService(WebContainer.class),
+ @RequireService(ProxyService.class)
+})
public class Activator extends BaseActivator {
private HttpPlugin httpPlugin;
- private ServletEventHandler eaHandler;
- private WebEventHandler webEaHandler;
@Override
protected void doStart() throws Exception {
@@ -40,21 +40,14 @@ public class Activator extends BaseActivator {
if (proxyService == null) {
return;
}
-
- eaHandler = new ServletEventHandler();
- eaHandler.setBundleContext(bundleContext);
- eaHandler.init();
- register(ServletListener.class, eaHandler);
-
- webEaHandler = new WebEventHandler();
- webEaHandler.setBundleContext(bundleContext);
- webEaHandler.init();
- register(WebListener.class, webEaHandler);
+ WebContainer webContainer = getTrackedService(WebContainer.class);
+ if (webContainer == null) {
+ return;
+ }
httpPlugin = new HttpPlugin();
httpPlugin.setBundleContext(bundleContext);
- httpPlugin.setServletEventHandler(eaHandler);
- httpPlugin.setWebEventHandler(webEaHandler);
+ httpPlugin.setWebContainer(webContainer);
httpPlugin.setProxyService(proxyService);
httpPlugin.start();
@@ -70,14 +63,6 @@ public class Activator extends BaseActivator {
httpPlugin.stop();
httpPlugin = null;
}
- if (eaHandler != null) {
- eaHandler.destroy();
- eaHandler = null;
- }
- if (webEaHandler != null) {
- webEaHandler.destroy();
- webEaHandler = null;
- }
}
}
diff --git
a/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/HttpPlugin.java
b/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/HttpPlugin.java
index bfb2504c5a..7156302473 100644
---
a/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/HttpPlugin.java
+++
b/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/HttpPlugin.java
@@ -21,13 +21,11 @@ import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import javax.servlet.Servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -36,14 +34,15 @@ import org.apache.felix.webconsole.AbstractWebConsolePlugin;
import org.apache.felix.webconsole.WebConsoleConstants;
import org.apache.karaf.http.core.Proxy;
import org.apache.karaf.http.core.ProxyService;
-import org.ops4j.pax.web.service.spi.ServletEvent;
-import org.ops4j.pax.web.service.spi.WebEvent;
+import org.ops4j.pax.web.service.WebContainer;
+import org.ops4j.pax.web.service.spi.model.info.ServletInfo;
+import org.ops4j.pax.web.service.spi.model.info.WebApplicationInfo;
+import org.ops4j.pax.web.service.spi.model.views.ReportWebContainerView;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
/**
* WebConsole plugin to use with HTTP service.
*/
@@ -54,9 +53,8 @@ public class HttpPlugin extends AbstractWebConsolePlugin {
public static final String NAME = "http";
public static final String LABEL = "Http";
private ClassLoader classLoader;
- private String featuresJs = "/http/res/ui/http-contexts.js";
- private ServletEventHandler servletEventHandler;
- private WebEventHandler webEventHandler;
+ private final String featuresJs = "/http/res/ui/http-contexts.js";
+ private WebContainer webContainer;
private BundleContext bundleContext;
private ProxyService proxyService;
@@ -116,7 +114,7 @@ public class HttpPlugin extends AbstractWebConsolePlugin {
protected URL getResource(String path) {
path = path.substring(NAME.length() + 1);
- if (path == null || path.isEmpty()) {
+ if (path.isEmpty()) {
return null;
}
URL url = this.classLoader.getResource(path);
@@ -149,7 +147,7 @@ public class HttpPlugin extends AbstractWebConsolePlugin {
final List<ServletDetails> servlets = this.getServletDetails();
final List<WebDetail> web = this.getWebDetails();
final Map<String, Proxy> proxies = proxyService.getProxies();
- final String statusLine = this.getStatusLine(servlets, web);
+ final String statusLine = this.getStatusLine(servlets);
final JSONWriter jw = new JSONWriter(pw);
jw.object();
@@ -167,16 +165,20 @@ public class HttpPlugin extends AbstractWebConsolePlugin {
jw.value(servlet.getServlet());
jw.key("servletName");
jw.value(servlet.getServletName());
- jw.key("state");
- jw.value(servlet.getState());
- jw.key("alias");
- jw.value(servlet.getAlias());
+ jw.key("type");
+ jw.value(servlet.getType());
jw.key("urls");
jw.array();
for (String url : servlet.getUrls()) {
jw.value(url);
}
jw.endArray();
+ jw.key("contexts");
+ jw.array();
+ for (String url : servlet.getContexts()) {
+ jw.value(url);
+ }
+ jw.endArray();
jw.endObject();
}
jw.endArray();
@@ -187,7 +189,7 @@ public class HttpPlugin extends AbstractWebConsolePlugin {
jw.object();
jw.key("id");
jw.value(webDetail.getBundleId());
- jw.key("bundlestate");
+ jw.key("bundleState");
jw.value(webDetail.getState());
jw.key("contextpath");
jw.value(webDetail.getContextPath());
@@ -215,49 +217,45 @@ public class HttpPlugin extends AbstractWebConsolePlugin {
}
protected List<ServletDetails> getServletDetails() {
+ List<ServletDetails> result = new ArrayList<>();
- Collection<ServletEvent> events =
servletEventHandler.getServletEvents();
- List<ServletDetails> result = new ArrayList<>(events.size());
+ ReportWebContainerView view =
webContainer.adapt(ReportWebContainerView.class);
- for (ServletEvent event : events) {
- Servlet servlet = event.getServlet();
- String servletClassName = " ";
- if (servlet != null) {
- servletClassName = servlet.getClass().getName();
- servletClassName =
servletClassName.substring(servletClassName.lastIndexOf(".") + 1);
- }
- String servletName = event.getServletName() != null ?
event.getServletName() : " ";
+ for (ServletInfo info : view.listServlets()) {
+ String servletClassName = info.getServletClass();
+ String servletName = info.getServletName();
if (servletName.contains(".")) {
servletName =
servletName.substring(servletName.lastIndexOf(".") + 1);
}
- String alias = event.getAlias() != null ? event.getAlias() : " ";
-
- String[] urls = event.getUrlParameter() != null ?
event.getUrlParameter() : new String[]{""};
+ String[] urls = info.getMapping() != null ? info.getMapping() :
new String[] { "" };
+ String[] contexts = info.getContexts() != null ?
info.getContexts() : new String[] { "" };
ServletDetails details = new ServletDetails();
- details.setId(event.getBundle().getBundleId());
- details.setAlias(alias);
+ details.setId(info.getBundle().getBundleId());
details.setServlet(servletClassName);
details.setServletName(servletName);
- details.setState(getStateString(event.getType()));
+ details.setType(info.getType());
details.setUrls(urls);
+ details.setContexts(contexts);
result.add(details);
}
return result;
}
protected List<WebDetail> getWebDetails() {
- Map<Long, WebEvent> bundleEvents = webEventHandler.getBundleEvents();
-
List<WebDetail> result = new ArrayList<>();
- for (WebEvent event : bundleEvents.values()) {
+ ReportWebContainerView view =
webContainer.adapt(ReportWebContainerView.class);
+ for (WebApplicationInfo info : view.listWebApplications()) {
+ if (!info.isWab()) {
+ continue;
+ }
WebDetail webDetail = new WebDetail();
- webDetail.setBundleId(event.getBundle().getBundleId());
-
webDetail.setContextPath(event.getContextPath().trim().concat("/"));
- int state =
bundleContext.getBundle(event.getBundle().getBundleId()).getState();
+ webDetail.setBundleId(info.getBundle().getBundleId());
+ webDetail.setContextPath(info.getContextPath().trim());
+ int state =
bundleContext.getBundle(info.getBundle().getBundleId()).getState();
String stateStr;
if (state == Bundle.ACTIVE) {
stateStr = "Active";
@@ -274,56 +272,33 @@ public class HttpPlugin extends AbstractWebConsolePlugin {
}
webDetail.setState(stateStr);
- webDetail.setWebState(getStateString(event.getType()));
+ webDetail.setWebState(info.getDeploymentState());
result.add(webDetail);
}
return result;
}
- public String getStatusLine(List<ServletDetails> servlets, List<WebDetail>
web) {
- Map<String, Integer> states = new HashMap<>();
+ public String getStatusLine(List<ServletDetails> servlets) {
+ Map<String, Integer> types = new HashMap<>();
for (ServletDetails servlet : servlets) {
- states.merge(servlet.getState(), 1, Integer::sum);
+ types.merge(servlet.getType(), 1, Integer::sum);
}
StringBuilder stateSummary = new StringBuilder();
boolean first = true;
- for (Entry<String, Integer> state : states.entrySet()) {
+ for (Entry<String, Integer> state : types.entrySet()) {
if (!first) {
stateSummary.append(", ");
}
first = false;
- stateSummary.append(state.getValue()).append("
").append(state.getKey());
+ stateSummary.append(state.getValue()).append(" from
").append(state.getKey());
}
- return "Http contexts: " + stateSummary.toString();
- }
-
- public String getStateString(int type) {
- switch (type) {
- case WebEvent.DEPLOYING:
- return "Deploying";
- case WebEvent.DEPLOYED:
- return "Deployed";
- case WebEvent.UNDEPLOYING:
- return "Undeploying";
- case WebEvent.UNDEPLOYED:
- return "Undeployed";
- case WebEvent.FAILED:
- return "Failed";
- case WebEvent.WAITING:
- return "Waiting";
- default:
- return "Failed";
- }
- }
-
- public void setServletEventHandler(ServletEventHandler eventHandler) {
- this.servletEventHandler = eventHandler;
+ return "Servlets: " + stateSummary;
}
- public void setWebEventHandler(WebEventHandler eventHandler) {
- this.webEventHandler = eventHandler;
+ public void setWebContainer(WebContainer webContainer) {
+ this.webContainer = webContainer;
}
public void setBundleContext(BundleContext bundleContext) {
diff --git
a/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/ServletDetails.java
b/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/ServletDetails.java
index bb869d7da2..4eeb19c143 100644
---
a/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/ServletDetails.java
+++
b/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/ServletDetails.java
@@ -20,17 +20,9 @@ public class ServletDetails {
private long id;
private String servlet;
private String servletName;
- private String state;
- private String alias;
+ private String type;
private String[] urls;
-
- public String getAlias() {
- return alias;
- }
-
- public void setAlias(String alias) {
- this.alias = alias;
- }
+ private String[] contexts;
public long getId() {
return id;
@@ -56,12 +48,12 @@ public class ServletDetails {
this.servletName = servletName;
}
- public String getState() {
- return state;
+ public String getType() {
+ return type;
}
- public void setState(String state) {
- this.state = state;
+ public void setType(String type) {
+ this.type = type;
}
public String[] getUrls() {
@@ -72,4 +64,11 @@ public class ServletDetails {
this.urls = urls;
}
+ public String[] getContexts() {
+ return contexts;
+ }
+
+ public void setContexts(String[] contexts) {
+ this.contexts = contexts;
+ }
}
diff --git
a/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/ServletEventHandler.java
b/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/ServletEventHandler.java
deleted file mode 100644
index f27dc0408c..0000000000
---
a/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/ServletEventHandler.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.webconsole.http;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.ops4j.pax.web.service.spi.ServletEvent;
-import org.ops4j.pax.web.service.spi.ServletListener;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleListener;
-
-public class ServletEventHandler implements ServletListener, BundleListener {
-
- BundleContext bundleContext;
- Map<String, ServletEvent> servletEvents = new HashMap<>();
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- public void init() {
- bundleContext.addBundleListener(this);
- }
-
- public void destroy() {
- bundleContext.removeBundleListener(this);
- }
-
- @Override
- public void bundleChanged(BundleEvent event) {
- if (event.getType() == BundleEvent.UNINSTALLED
- || event.getType() == BundleEvent.UNRESOLVED
- || event.getType() == BundleEvent.STOPPED) {
- removeEventsForBundle(event.getBundle());
- }
- }
-
- public synchronized void servletEvent(ServletEvent event) {
- servletEvents.put(event.getServletName(), event);
- }
-
- /**
- * @return the servletEvents
- */
- public synchronized Collection<ServletEvent> getServletEvents() {
- return new ArrayList<>(servletEvents.values());
- }
-
- public synchronized void removeEventsForBundle(Bundle bundle) {
- servletEvents.entrySet().removeIf(entry ->
entry.getValue().getBundle() == bundle);
- }
-
-}
diff --git
a/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/WebEventHandler.java
b/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/WebEventHandler.java
deleted file mode 100644
index adfcf40cc4..0000000000
---
a/webconsole/http/src/main/java/org/apache/karaf/webconsole/http/WebEventHandler.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright 2011 Achim.
- *
- * Licensed 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.webconsole.http;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.ops4j.pax.web.service.spi.WebEvent;
-import org.ops4j.pax.web.service.spi.WebListener;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleListener;
-
-public class WebEventHandler implements WebListener, BundleListener {
-
- BundleContext bundleContext;
- private final Map<Long, WebEvent> bundleEvents = new HashMap<>();
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- public void init() {
- bundleContext.addBundleListener(this);
- }
-
- public void destroy() {
- bundleContext.removeBundleListener(this);
- }
-
- @Override
- public void bundleChanged(BundleEvent event) {
- if (event.getType() == BundleEvent.UNINSTALLED
- || event.getType() == BundleEvent.UNRESOLVED
- || event.getType() == BundleEvent.STOPPED) {
- removeEventsForBundle(event.getBundle());
- }
- }
-
- @Override
- public synchronized void webEvent(WebEvent event) {
- bundleEvents.put(event.getBundle().getBundleId(), event);
- }
-
- public synchronized Map<Long, WebEvent> getBundleEvents() {
- return new HashMap<>(bundleEvents);
- }
-
- public synchronized void removeEventsForBundle(Bundle bundle) {
- bundleEvents.remove(bundle.getBundleId());
- }
-
-}
diff --git a/webconsole/http/src/main/resources/res/ui/http-contexts.js
b/webconsole/http/src/main/resources/res/ui/http-contexts.js
index d1eae05b86..71d505c26b 100644
--- a/webconsole/http/src/main/resources/res/ui/http-contexts.js
+++ b/webconsole/http/src/main/resources/res/ui/http-contexts.js
@@ -24,7 +24,7 @@ function renderFeatures( data ) {
function renderView() {
renderStatusLine();
- renderTable( "HTTP Contexts", "context_table", ["ID", "Servlet", "Name",
"State", "Alias", "urls"] );
+ renderTable( "HTTP Contexts", "context_table", ["ID", "Servlet", "Name",
"Type", "urls", "contexts"] );
renderTable( "Web Contexts", "webctxt_table", ["ID", "BundleState", "Web
Context", "State"] );
renderTable(" HTTP Proxies", "proxy_table", ["URL", "ProxyTo"]);
renderStatusLine();
@@ -106,15 +106,19 @@ function renderContextData( /* Element */ parent, /*
Object */ context ) {
parent.appendChild( td( null, null, [ text( context.id ) ] ) );
parent.appendChild( td( null, null, [ text( context.servlet ) ] ) );
parent.appendChild( td( null, null, [ text( context.servletName ) ] ) );
- parent.appendChild( td( null, null, [ text( context.state ) ] ) );
- parent.appendChild( td( null, null, [ text( context.alias ) ] ) );
-
+ parent.appendChild( td( null, null, [ text( context.type ) ] ) );
+
var urlBox = td( null, null );
for ( var idx in context.urls ) {
urlBox.appendChild( link( trimUrl(context.urls[idx]), context.urls[idx]
) );
}
-
parent.appendChild( urlBox );
+
+ var contextBox = td( null, null );
+ for ( var idx in context.contexts ) {
+ contextBox.appendChild( text( context.contexts[idx] ) );
+ }
+ parent.appendChild( contextBox );
}
function renderWebCtxtData( /* Element */ parent, /* Object */ webCtxt ) {