You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2012/09/14 16:18:09 UTC
svn commit: r1384795 - in
/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina:
./ routing/
Author: rmannibucau
Date: Fri Sep 14 14:18:09 2012
New Revision: 1384795
URL: http://svn.apache.org/viewvc?rev=1384795&view=rev
Log:
TOMEE-416 basic out of the box routing feature
Added:
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/Route.java
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouteFilter.java
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterException.java
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterInitializer.java
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterValve.java
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/SimpleRouter.java
Modified:
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/OpenEJBContextConfig.java
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
Modified: openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/OpenEJBContextConfig.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/OpenEJBContextConfig.java?rev=1384795&r1=1384794&r2=1384795&view=diff
==============================================================================
--- openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/OpenEJBContextConfig.java (original)
+++ openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/OpenEJBContextConfig.java Fri Sep 14 14:18:09 2012
@@ -25,6 +25,7 @@ import org.apache.openejb.assembler.clas
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
+import org.apache.tomee.catalina.routing.RouterInitializer;
import org.apache.xbean.finder.util.Classes;
import org.xml.sax.InputSource;
@@ -86,6 +87,10 @@ public class OpenEJBContextConfig extend
@Override
protected void webConfig() {
+ // routing config
+ context.addServletContainerInitializer(new RouterInitializer(), null); // first one
+
+ // read the real config
super.webConfig();
// add myfaces auto-initializer
Modified: openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java?rev=1384795&r1=1384794&r2=1384795&view=diff
==============================================================================
--- openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java (original)
+++ openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java Fri Sep 14 14:18:09 2012
@@ -89,6 +89,9 @@ import org.apache.tomcat.util.digester.D
import org.apache.tomee.catalina.cluster.ClusterObserver;
import org.apache.tomee.catalina.cluster.TomEEClusterListener;
import org.apache.tomee.catalina.event.AfterApplicationCreated;
+import org.apache.tomee.catalina.routing.RouteFilter;
+import org.apache.tomee.catalina.routing.RouterInitializer;
+import org.apache.tomee.catalina.routing.RouterValve;
import org.apache.tomee.common.LegacyAnnotationProcessor;
import org.apache.tomee.common.TomcatVersion;
import org.apache.tomee.common.UserTransactionFactory;
@@ -113,6 +116,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -217,6 +221,14 @@ public class TomcatWebAppBuilder impleme
if (service.getContainer() instanceof Engine) {
final Engine engine = (Engine) service.getContainer();
+ // add the global router if relevant
+ final URL globalRouterConf = RouterInitializer.serverRouterConfigurationURL();
+ if (globalRouterConf != null) {
+ final RouterValve routerValve = new RouterValve();
+ routerValve.setConfigurationPath(globalRouterConf);
+ engine.getPipeline().addValve(routerValve);
+ }
+
parentClassLoader = engine.getParentClassLoader();
manageCluster(engine.getCluster());
Added: openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/Route.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/Route.java?rev=1384795&view=auto
==============================================================================
--- openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/Route.java (added)
+++ openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/Route.java Fri Sep 14 14:18:09 2012
@@ -0,0 +1,94 @@
+/*
+ * 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.tomee.catalina.routing;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Route {
+ private static final String[] EMPTY_CONTEXT = new String[0];
+
+ private final ThreadLocal<Matcher> matcher = new ThreadLocal<Matcher>();
+
+ private Pattern originPattern;
+ private String origin;
+ private String destination;
+
+ public Route from(final String value) {
+ origin = value;
+ originPattern = Pattern.compile(value);
+ return this;
+ }
+
+ public Route to(final String value) {
+ destination = value;
+ return this;
+ }
+
+ public String cleanDestination() {
+ String destination = this.destination;
+
+ final Matcher matcher = this.matcher.get();
+ if (matcher != null) {
+ final String[] context = currentContext();
+ for (int i = 0; i < context.length; i++) {
+ destination = destination.replace("$" + (i + 1), context[i]);
+ }
+ }
+
+ this.matcher.remove(); // single call to this method
+
+ return destination;
+ }
+
+ public String getOrigin() {
+ return origin;
+ }
+
+ public boolean matches(final String uri) {
+ final Matcher matcher = originPattern.matcher(uri);
+ final boolean ok = matcher.matches();
+
+ if (ok) {
+ this.matcher.set(matcher);
+ }
+
+ return ok;
+ }
+
+ private String[] currentContext() {
+ if (matcher.get().groupCount() > 0) {
+ return buildContext(matcher.get());
+ } else {
+ return EMPTY_CONTEXT;
+ }
+ }
+
+ private String[] buildContext(final Matcher matcher) {
+ final Collection<String> values = new ArrayList<String>();
+ for (int i = 1; i < matcher.groupCount() + 1; i++) {
+ values.add(matcher.group(i));
+ }
+ return values.toArray(new String[values.size()]);
+ }
+
+ public String getRawDestination() {
+ return destination;
+ }
+}
Added: openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouteFilter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouteFilter.java?rev=1384795&view=auto
==============================================================================
--- openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouteFilter.java (added)
+++ openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouteFilter.java Fri Sep 14 14:18:09 2012
@@ -0,0 +1,62 @@
+/*
+ * 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.tomee.catalina.routing;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URL;
+
+public final class RouteFilter implements Filter {
+ private SimpleRouter router = new SimpleRouter();
+
+ @Override
+ public void init(final FilterConfig filterConfig) throws ServletException {
+ router.JMXOn(filterConfig.getServletContext().getContextPath());
+ }
+
+ @Override
+ public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
+ if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
+ chain.doFilter(request, response);
+ }
+
+ final String destination = router.route(((HttpServletRequest) request).getRequestURI());
+ if (destination == null) {
+ chain.doFilter(request, response);
+ return;
+ }
+
+ ((HttpServletResponse) response).sendRedirect(destination);
+ }
+
+ @Override
+ public void destroy() {
+ router.cleanUp();
+ }
+
+ public void initConfigurationPath(final String prefix, final URL configurationPath) {
+ router.setPrefix(prefix);
+ router.readConfiguration(configurationPath);
+ }
+}
Added: openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterException.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterException.java?rev=1384795&view=auto
==============================================================================
--- openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterException.java (added)
+++ openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterException.java Fri Sep 14 14:18:09 2012
@@ -0,0 +1,23 @@
+/*
+ * 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.tomee.catalina.routing;
+
+public class RouterException extends RuntimeException {
+ public RouterException(final String s) {
+ super(s);
+ }
+}
Added: openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterInitializer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterInitializer.java?rev=1384795&view=auto
==============================================================================
--- openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterInitializer.java (added)
+++ openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterInitializer.java Fri Sep 14 14:18:09 2012
@@ -0,0 +1,77 @@
+/*
+ * 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.tomee.catalina.routing;
+
+import org.apache.openejb.config.DeploymentLoader;
+import org.apache.openejb.loader.SystemInstance;
+
+import javax.servlet.ServletContainerInitializer;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Set;
+
+public class RouterInitializer implements ServletContainerInitializer {
+ public static final String ROUTER_CONF = "tomee-router.conf";
+ public static final String WEB_INF = "/WEB-INF/";
+
+ @Override
+ public void onStartup(final Set<Class<?>> classes, final ServletContext servletContext) throws ServletException {
+ final URL routerConfig = configurationURL(servletContext);
+ if (routerConfig != null) {
+ final RouteFilter filter = new RouteFilter();
+ filter.initConfigurationPath(servletContext.getContextPath(), routerConfig);
+ servletContext.addFilter("Routing Filter", filter).addMappingForUrlPatterns(null, false, "/*");
+ }
+ }
+
+ public static URL configurationURL(final ServletContext ctx) {
+ try {
+ return ctx.getResource(WEB_INF + routerConfigurationName());
+ } catch (MalformedURLException e) {
+ // let return null
+ }
+
+ return null;
+ }
+
+ public static String routerConfigurationName() {
+ final String conf = SystemInstance.get().getOptions().get(DeploymentLoader.OPENEJB_ALTDD_PREFIX, (String) null);
+ if (conf == null) {
+ return ROUTER_CONF;
+ } else {
+ return conf + "." + ROUTER_CONF;
+ }
+ }
+
+ public static URL serverRouterConfigurationURL() {
+ final File confDir = SystemInstance.get().getHome().getDirectory();
+ final File configFile = new File(confDir, "conf/" + routerConfigurationName());
+
+ if (configFile.exists()) {
+ try {
+ return configFile.toURI().toURL();
+ } catch (MalformedURLException e) {
+ // let return null
+ }
+ }
+
+ return null;
+ }
+}
Added: openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterValve.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterValve.java?rev=1384795&view=auto
==============================================================================
--- openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterValve.java (added)
+++ openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/RouterValve.java Fri Sep 14 14:18:09 2012
@@ -0,0 +1,41 @@
+package org.apache.tomee.catalina.routing;
+
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.valves.ValveBase;
+
+import javax.servlet.ServletException;
+import java.io.IOException;
+import java.net.URL;
+
+public class RouterValve extends ValveBase {
+ private SimpleRouter router = new SimpleRouter();
+
+ @Override
+ public void invoke(final Request request, final Response response) throws IOException, ServletException {
+ final String destination = router.route(request.getRequestURI());
+ if (destination == null) {
+ getNext().invoke(request, response);
+ return;
+ }
+
+ response.sendRedirect(destination);
+ }
+
+ public void setConfigurationPath(URL configurationPath) {
+ router.readConfiguration(configurationPath);
+ }
+
+ @Override
+ protected synchronized void startInternal() throws LifecycleException {
+ super.startInternal();
+ router.JMXOn("Router Valve " + System.identityHashCode(this));
+ }
+
+ @Override
+ protected synchronized void stopInternal() throws LifecycleException {
+ router.cleanUp();
+ super.stopInternal();
+ }
+}
Added: openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/SimpleRouter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/SimpleRouter.java?rev=1384795&view=auto
==============================================================================
--- openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/SimpleRouter.java (added)
+++ openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/routing/SimpleRouter.java Fri Sep 14 14:18:09 2012
@@ -0,0 +1,210 @@
+/*
+ * 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.tomee.catalina.routing;
+
+import org.apache.openejb.monitoring.DynamicMBeanWrapper;
+import org.apache.openejb.monitoring.LocalMBeanServer;
+import org.apache.openejb.monitoring.ObjectNameBuilder;
+
+import javax.management.ManagedAttribute;
+import javax.management.ManagedOperation;
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+import javax.servlet.ServletException;
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class SimpleRouter {
+ private static final Pattern PATTERN = Pattern.compile("(.*)->(.*)");
+
+ private String prefix = "";
+ private ObjectName objectName = null;
+ private Route[] routes = new Route[0];
+ private final Map<String, Route> cache = new ConcurrentHashMap<String, Route>();
+
+ public SimpleRouter readConfiguration(final URL url) {
+ if (url == null) {
+ return this;
+ }
+
+ try {
+ final InputStream is = new BufferedInputStream(url.openStream());
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+
+ String line;
+ while ((line = reader.readLine()) != null) {
+ line = line.trim();
+ if (!line.isEmpty() && !line.startsWith("#")) {
+ parseRoute(line);
+ }
+ }
+ } catch (IOException e) {
+ throw new RouterException("can't read " + url.toExternalForm());
+ }
+ return this;
+ }
+
+ private void parseRoute(final String line) {
+ final Matcher matcher = PATTERN.matcher(line);
+ if (matcher.matches()) {
+ final String from = prefix(matcher.group(1).trim());
+ final String to = prefix(matcher.group(2).trim());
+ addRoute(new Route().from(from).to(to));
+ }
+ }
+
+ public String route(final String uri) throws IOException, ServletException {
+ if (uri == null) {
+ return null;
+ }
+
+ final Route cachedRoute = cache.get(uri);
+ if (cachedRoute != null) {
+ cachedRoute.matches(uri);
+ return cachedRoute.cleanDestination();
+ }
+
+ for (Route route : routes) {
+ if (route.matches(uri)) {
+ if (route.getOrigin().equals(uri)) {
+ cache.put(uri, route);
+ }
+ return route.cleanDestination();
+ }
+ }
+
+ return null;
+ }
+
+ public synchronized void addRoute(final Route route) {
+ final Route[] newRoutes = new Route[routes.length + 1];
+ System.arraycopy(routes, 0, newRoutes, 0, routes.length);
+ newRoutes[routes.length] = route;
+ routes = newRoutes;
+ }
+
+ public void cleanUp() {
+ JMXOff();
+ routes = null;
+ cache.clear();
+ }
+
+ public void setPrefix(final String prefix) {
+ if (prefix == null || prefix.isEmpty() || prefix.equals("/")) {
+ this.prefix = "";
+ } else {
+ this.prefix = prefix;
+ }
+ }
+
+ private String prefix(final String value) {
+ if (prefix != null) {
+ return prefix + value;
+ }
+ return value;
+ }
+
+ public void JMXOn(final String name) {
+ final ObjectNameBuilder jmxName = new ObjectNameBuilder("openejb.management");
+ jmxName.set("J2EEServer", "Router");
+ jmxName.set("J2EEApplication", name);
+ jmxName.set("Type", "SimpleRouter");
+
+ objectName = jmxName.build();
+ try {
+ LocalMBeanServer.get().registerMBean(new DynamicMBeanWrapper(this), objectName);
+ } catch (Exception e) {
+ objectName = null;
+ }
+ }
+
+ public void JMXOff() {
+ if (objectName != null) {
+ try {
+ LocalMBeanServer.get().unregisterMBean(objectName);
+ } catch (Exception e) {
+ // no-op
+ }
+ }
+ }
+
+ @ManagedAttribute
+ public TabularData getActiveRoutes() {
+ if (routes.length == 0) {
+ return null;
+ }
+
+ final OpenType<?>[] types = new OpenType<?>[routes.length];
+ final String[] keys = new String[types.length];
+ final String[] values = new String[types.length];
+
+ for (int i = 0; i < types.length; i++) {
+ types[i] = SimpleType.STRING;
+ keys[i] = routes[i].getOrigin();
+ values[i] = routes[i].getRawDestination();
+ }
+
+ try {
+ final CompositeType ct = new CompositeType("routes", "routes", keys, keys, types);
+ final TabularType type = new TabularType("router", "routes", ct, keys);
+ TabularDataSupport data = new TabularDataSupport(type);
+
+ CompositeData line = new CompositeDataSupport(ct, keys, values);
+ data.put(line);
+ return data;
+ } catch (OpenDataException e) {
+ return null;
+ }
+ }
+
+ @ManagedOperation
+ public void addRoute(final String from, final String to) {
+ addRoute(new Route().from(prefix(from)).to(prefix(to)));
+ }
+
+ @ManagedOperation
+ public void removeRoute(final String from, final String to) {
+ if (routes.length == 0) {
+ return;
+ }
+
+ for (int i = 0; i < routes.length; i++) {
+ if (routes[i].getOrigin().equals(from) && routes[i].getRawDestination().endsWith(to)) {
+ final Route[] newRoutes = new Route[routes.length - 1];
+ System.arraycopy(routes, 0, newRoutes, 0, i);
+ System.arraycopy(routes, i + 1, newRoutes, i, routes.length - i - 1);
+ routes = newRoutes;
+ }
+ }
+ }
+}