Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[KARAF-5919] Be able to store Http Proxy list in order to keep configuration after restart #644

Merged
merged 1 commit into from
Nov 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ public interface ProxyService {

void removeProxy(String url) throws Exception;

void initProxies();

}
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, String> proxies;

public ProxyServiceImpl(HttpService httpService) {
public ProxyServiceImpl(HttpService httpService, ConfigurationAdmin configurationAdmin) {
this.httpService = httpService;
this.configurationAdmin = configurationAdmin;
this.proxies = new HashMap<>();
initProxies();
}

@Override
Expand All @@ -38,15 +51,115 @@ public Map<String, String> 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<String, Object> 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<String, Object> configurationProperties = configuration.getProperties();
if (configurationProperties == null) {
configurationProperties = new Hashtable<String, Object>();
}
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<String, String> proxies) {
List<String> proxyList = new ArrayList<String>();
Iterator<Map.Entry<String, String>> entries = proxies.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<String, String> entry = entries.next();
proxyList.add(entry.getKey() + " " + entry.getValue());
}
return proxyList.stream().toArray(String[]::new);
}

private String[] getConfiguredProxyArray(Dictionary<String, Object> 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();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,48 @@
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);
if (httpService == null) {
return;
}

ConfigurationAdmin configurationAdmin = getTrackedService(ConfigurationAdmin.class);
if (configurationAdmin == null) {
return;
}

final ServletEventHandler servletEventHandler = new ServletEventHandler();
register(ServletListener.class, servletEventHandler);

Expand All @@ -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);
Expand All @@ -81,4 +95,9 @@ protected void doStop() {
}
super.doStop();
}

@Override
public void updated(Dictionary<String, ?> properties) {
proxyService.initProxies();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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"));

Expand Down