diff --git a/http/src/main/java/org/apache/karaf/http/core/ProxyService.java b/http/src/main/java/org/apache/karaf/http/core/ProxyService.java index 63d03fe8586..c168a71c471 100644 --- a/http/src/main/java/org/apache/karaf/http/core/ProxyService.java +++ b/http/src/main/java/org/apache/karaf/http/core/ProxyService.java @@ -26,4 +26,6 @@ public interface ProxyService { void removeProxy(String url) throws Exception; + void initProxies(); + } diff --git a/http/src/main/java/org/apache/karaf/http/core/internal/ProxyServiceImpl.java b/http/src/main/java/org/apache/karaf/http/core/internal/ProxyServiceImpl.java index 16e481f04ab..0d4f061ca94 100644 --- a/http/src/main/java/org/apache/karaf/http/core/internal/ProxyServiceImpl.java +++ b/http/src/main/java/org/apache/karaf/http/core/internal/ProxyServiceImpl.java @@ -17,18 +17,31 @@ package org.apache.karaf.http.core.internal; import org.apache.karaf.http.core.ProxyService; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.http.HttpService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; import java.util.*; public class ProxyServiceImpl implements ProxyService { + private static Logger LOG = LoggerFactory.getLogger(ProxyServiceImpl.class.getName()); + + protected static final String CONFIGURATION_PID = "org.apache.karaf.http"; + protected static final String CONFIGURATION_KEY = "proxies"; + + private ConfigurationAdmin configurationAdmin; private HttpService httpService; private Map proxies; - public ProxyServiceImpl(HttpService httpService) { + public ProxyServiceImpl(HttpService httpService, ConfigurationAdmin configurationAdmin) { this.httpService = httpService; + this.configurationAdmin = configurationAdmin; this.proxies = new HashMap<>(); + initProxies(); } @Override @@ -38,15 +51,115 @@ public Map getProxies() { @Override public void addProxy(String url, String proxyTo) throws Exception { - ProxyServlet proxyServlet = new ProxyServlet(); - proxyServlet.setProxyTo(proxyTo); - httpService.registerServlet(url, proxyServlet, new Hashtable(), null); - proxies.put(url, proxyTo); + addProxyInternal(url, proxyTo); + updateConfiguration(); } @Override public void removeProxy(String url) throws Exception { + LOG.debug("removing proxy alias: " + url); httpService.unregister(url); proxies.remove(url); + updateConfiguration(); + } + + @Override + public void initProxies() { + LOG.debug("unregistering and registering all configured proxies"); + unregisterAllProxies(); + initProxiesInternal(); + } + + private void initProxiesInternal() { + try { + Configuration configuration = getConfiguration(); + Dictionary configurationProperties = configuration.getProperties(); + String[] proxiesArray = getConfiguredProxyArray(configurationProperties); + if (proxiesArray != null) { + for (String proxyPair : proxiesArray) { + String[] split = proxyPair.split(" ", 2); + if (split.length == 2) { + String from = split[0].trim(); + String to = split[1].trim(); + if (from.length() > 0 && to.length() > 0) { + addProxyInternal(from, to); + } + } + } + } + } catch (Exception e) { + LOG.error("unable to initialize proxies: " + e.getMessage()); + } + } + + private void addProxyInternal(String url, String proxyTo) { + LOG.debug("adding proxy alias: " + url + ", proxied to: " + proxyTo); + try { + ProxyServlet proxyServlet = new ProxyServlet(); + proxyServlet.setProxyTo(proxyTo); + httpService.registerServlet(url, proxyServlet, new Hashtable(), null); + proxies.put(url, proxyTo); + } catch (Exception e) { + LOG.error("could not add proxy alias: " + url + ", proxied to: " + proxyTo + ", reason: " + e.getMessage()); + } + } + + + private void updateConfiguration() { + + try { + Configuration configuration = getConfiguration(); + Dictionary configurationProperties = configuration.getProperties(); + if (configurationProperties == null) { + configurationProperties = new Hashtable(); + } + configurationProperties.put(CONFIGURATION_KEY, mapToProxyArray(this.proxies)); + configuration.update(configurationProperties); + } catch (Exception e) { + LOG.error("unable to update http proxy from configuration: " + e.getMessage()); + } + + } + + private Configuration getConfiguration() { + + try { + return configurationAdmin.getConfiguration(CONFIGURATION_PID, null); + } catch (IOException e) { + throw new RuntimeException("Error retrieving http proxy information from config admin", e); + } } + + private String[] mapToProxyArray(Map proxies) { + List proxyList = new ArrayList(); + Iterator> entries = proxies.entrySet().iterator(); + while (entries.hasNext()) { + Map.Entry entry = entries.next(); + proxyList.add(entry.getKey() + " " + entry.getValue()); + } + return proxyList.stream().toArray(String[]::new); + } + + private String[] getConfiguredProxyArray(Dictionary configurationProperties) { + Object val = null; + if (configurationProperties != null) { + val = configurationProperties.get(CONFIGURATION_KEY); + } + + if (val instanceof String[]) { + return (String[]) val; + } else { + return null; + } + } + + private void unregisterAllProxies() { + for (String url : proxies.keySet()) { + LOG.debug("removing proxy alias: " + url); + httpService.unregister(url); + } + proxies.clear(); + } + + } 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 8c68b03120f..05eb9c24c04 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 @@ -23,27 +23,36 @@ import org.apache.karaf.http.core.internal.ServletEventHandler; import org.apache.karaf.http.core.internal.ServletServiceImpl; import org.apache.karaf.util.tracker.BaseActivator; +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.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.cm.ManagedService; import org.osgi.service.http.HttpService; +import java.util.Dictionary; + @Services( requires = { - @RequireService(HttpService.class) + @RequireService(HttpService.class), + @RequireService(ConfigurationAdmin.class) }, provides = { @ProvideService(ServletService.class), @ProvideService(ProxyService.class) } ) -public class Activator extends BaseActivator { +@Managed("org.apache.karaf.http") +public class Activator extends BaseActivator implements ManagedService { private BundleListener listener; + private ProxyService proxyService; + @Override protected void doStart() throws Exception { HttpService httpService = getTrackedService(HttpService.class); @@ -51,6 +60,11 @@ protected void doStart() throws Exception { return; } + ConfigurationAdmin configurationAdmin = getTrackedService(ConfigurationAdmin.class); + if (configurationAdmin == null) { + return; + } + final ServletEventHandler servletEventHandler = new ServletEventHandler(); register(ServletListener.class, servletEventHandler); @@ -66,7 +80,7 @@ protected void doStart() throws Exception { }; bundleContext.addBundleListener(listener); - ProxyServiceImpl proxyService = new ProxyServiceImpl(httpService); + proxyService = new ProxyServiceImpl(httpService, configurationAdmin); register(ProxyService.class, proxyService); HttpMBeanImpl httpMBean = new HttpMBeanImpl(servletService, proxyService); @@ -81,4 +95,9 @@ protected void doStop() { } super.doStop(); } + + @Override + public void updated(Dictionary properties) { + proxyService.initProxies(); + } } 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 91d13f9585e..de33717702e 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)); + HttpMBeanImpl httpMBean = new HttpMBeanImpl(new ServletServiceImpl(new ServletEventHandler()), new ProxyServiceImpl(null, null)); MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); mbeanServer.registerMBean(httpMBean, new ObjectName("org.apache.karaf:type=http,name=root"));