diff --git a/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanContainer.java b/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanContainer.java index e5ef1a3318..b022a63950 100644 --- a/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanContainer.java +++ b/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanContainer.java @@ -14,24 +14,52 @@ package com.predic8.membrane.annot.beanregistry; +import com.predic8.membrane.annot.Grammar; +import com.predic8.membrane.annot.bean.BeanFactory; +import com.predic8.membrane.annot.yaml.GenericYamlParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.atomic.*; + public class BeanContainer { + private static final Logger log = LoggerFactory.getLogger(BeanContainer.class); + private final BeanDefinition definition; /** * Constructed bean after initialization. */ - private volatile Object singleton; + private final AtomicReference singleton = new AtomicReference<>(); + /** + * Creates a BeanDefinition where the bean has not yet been instantiated and initialized. + */ public BeanContainer(BeanDefinition definition) { this.definition = definition; } + /** + * Creates a BeanDefinition where the bean has already been instantiated and initialized. + */ + public BeanContainer(BeanDefinition definition, Object singleton) { + this.definition = definition; + this.singleton.set(singleton); + } - public Object getSingleton() { - return singleton; + /** + * Only to be used within this class. + * Use {@link #getOrCreate(BeanRegistryImplementation, Grammar)} instead. + */ + private Object getSingleton() { + return singleton.get(); } - public void setSingleton(Object singleton) { - this.singleton = singleton; + /** + * Only to be used within this class. + * Use {@link #getOrCreate(BeanRegistryImplementation, Grammar)} instead. + */ + private void setSingleton(Object singleton) { + this.singleton.set(singleton); } public BeanDefinition getDefinition() { @@ -40,6 +68,52 @@ public BeanDefinition getDefinition() { @Override public String toString() { - return "BeanContainer: %s of %s".formatted( definition.getName(),definition.getKind()); + return "BeanContainer: %s of %s singleton: %s".formatted( definition.getName(),definition.getKind(),singleton.get()); + } + + private synchronized Object define(BeanRegistryImplementation registry, Grammar grammar) { + log.debug("defining bean: {}", definition.getNode()); + try { + if ("bean".equals(definition.getKind())) { + return new BeanFactory(registry).create(definition.getNode().path("bean")); + } + return GenericYamlParser.readMembraneObject(definition.getKind(), + grammar, + definition.getNode(), + registry); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public Object getOrCreate(BeanRegistryImplementation registry, Grammar grammar) { + boolean prototype = isPrototypeScope(getDefinition()); + + // Prototypes are created anew every time. + if (prototype) { + return define(registry, grammar); + } + + // Singleton: ensure define() runs at most once per BeanContainer. + synchronized (this) { + Object existing = getSingleton(); + if (existing != null) { + return existing; + } + + Object created = define(registry, grammar); + setSingleton(created); + return created; + } + } + + private static boolean isPrototypeScope(BeanDefinition bd) { + if (!bd.isBean()) + return bd.isPrototype(); + + return "PROTOTYPE".equalsIgnoreCase( + bd.getNode().path("bean").path("scope").asText("SINGLETON") + ); } + } diff --git a/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanDefinition.java b/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanDefinition.java index eaaea4951b..5afa1fda62 100644 --- a/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanDefinition.java +++ b/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanDefinition.java @@ -16,6 +16,9 @@ import com.fasterxml.jackson.databind.*; import com.predic8.membrane.annot.yaml.*; +/** + * Immutable. + */ public class BeanDefinition { public static final String PROTOTYPE = "prototype"; @@ -76,6 +79,8 @@ public String getKind() { } public String getScope() { + if (node == null) + return null; JsonNode meta = node.get("metadata"); if (meta == null) return null; diff --git a/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanRegistry.java b/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanRegistry.java index 3c5390144e..d562b2ea33 100644 --- a/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanRegistry.java +++ b/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanRegistry.java @@ -16,6 +16,7 @@ import com.predic8.membrane.annot.*; import java.util.*; +import java.util.function.*; public interface BeanRegistry { @@ -44,4 +45,15 @@ public interface BeanRegistry { * @param bean instance to register (must not be null) */ void register(String beanName, Object bean); + + /** + * Registers a bean of the specified type with the given name if it is not already registered. + * If a bean with the given name is already present, the existing instance is returned. + * Otherwise, the supplier is used to create and register a new instance. + * @param type the class type of the bean + * @param supplier a supplier that provides a new instance of the bean if not already registered + * @param the generic type of the bean + * @return the existing or newly created and registered bean instance + */ + T registerIfAbsent(Class type, Supplier supplier); } diff --git a/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanRegistryImplementation.java b/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanRegistryImplementation.java index 4398ecb180..8ea53231a7 100644 --- a/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanRegistryImplementation.java +++ b/annot/src/main/java/com/predic8/membrane/annot/beanregistry/BeanRegistryImplementation.java @@ -13,17 +13,29 @@ limitations under the License. */ package com.predic8.membrane.annot.beanregistry; -import com.predic8.membrane.annot.Grammar; -import com.predic8.membrane.annot.bean.BeanFactory; -import com.predic8.membrane.annot.yaml.GenericYamlParser; -import com.predic8.membrane.annot.yaml.WatchAction; +import com.predic8.membrane.annot.*; +import com.predic8.membrane.annot.bean.*; +import com.predic8.membrane.annot.yaml.*; import org.jetbrains.annotations.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.slf4j.*; +import javax.annotation.concurrent.*; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - +import java.util.concurrent.*; +import java.util.function.*; + +/** + * TODO: + * - More Tests + * - Document + * - For TB Unclear: Lifecycle activation/resolve + * - oldbean + * - a.) Revert to second list (singletonBeans) + * - b.) Give proxies an unique id + *

+ * For K8S UUID and name is needed cause name is only unique within a namespace. + * + */ public class BeanRegistryImplementation implements BeanRegistry, BeanCollector { private static final Logger log = LoggerFactory.getLogger(BeanRegistryImplementation.class); @@ -36,9 +48,17 @@ public class BeanRegistryImplementation implements BeanRegistry, BeanCollector { // uid -> bean container private final Map bcs = new ConcurrentHashMap<>(); // Order is not critical. Order is determined by uidsToActivate + + @GuardedBy("uidsToActivate") private final Set uidsToActivate = Collections.synchronizedSet(new LinkedHashSet<>()); // keeps order - record UidAction(String uid, WatchAction action) {} + /** + * Protects the initialization of beans, which are unique per class. + */ + private final Object uniqueClassInitialization = new Object(); + + record UidAction(String uid, WatchAction action) { + } public BeanRegistryImplementation(BeanCacheObserver observer, BeanRegistryAware registryAware, Grammar grammar) { this.observer = observer; @@ -46,21 +66,6 @@ public BeanRegistryImplementation(BeanCacheObserver observer, BeanRegistryAware registryAware.setRegistry(this); } - private Object define(BeanDefinition bd) { - log.debug("defining bean: {}", bd.getNode()); - try { - if ("bean".equals(bd.getKind())) { - return new BeanFactory(this).create(bd.getNode().path("bean")); - } - return GenericYamlParser.readMembraneObject(bd.getKind(), - grammar, - bd.getNode(), - this); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - @Override public void start() { } @@ -89,10 +94,9 @@ private void activationRun() { for (UidAction uidAction : uidsToActivate) { BeanContainer bc = bcs.get(uidAction.uid); try { - Object bean = define(bc.getDefinition()); - bc.setSingleton(bean); + Object bean = bc.getOrCreate(this, grammar); - // e.g. inform router about new proxy + // e.g., inform router about a new ApiProxy or GlobalInterceptor observer.handleBeanEvent(new BeanDefinitionChanged(uidAction.action, bc.getDefinition()), bean, getOldBean(uidAction.action, bc.getDefinition())); if (uidAction.action.isAdded() || uidAction.action.isModified()) @@ -121,19 +125,7 @@ private void activationRun() { @Override public Object resolve(String url) { - BeanContainer bc = getFirstByName(url).orElseThrow(() -> new RuntimeException("Reference %s not found".formatted(url))); - - boolean prototype = isPrototypeScope(bc.getDefinition()); - - if (!prototype && bc.getSingleton() != null) - return bc.getSingleton(); - - Object instance = define(bc.getDefinition()); - - if (!prototype) - bc.setSingleton(instance); - - return instance; + return getFirstByName(url).orElseThrow(() -> new RuntimeException("Reference %s not found".formatted(url))).getOrCreate(this, grammar); } private @NotNull Optional getFirstByName(String url) { @@ -143,7 +135,7 @@ public Object resolve(String url) { @Override public List getBeans() { return bcs.values().stream().filter(bd -> !bd.getDefinition().isComponent()) - .map(BeanContainer::getSingleton) + .map(bc -> bc.getOrCreate(this, grammar)) .filter(Objects::nonNull) .toList(); } @@ -153,19 +145,10 @@ public Grammar getGrammar() { return grammar; } - private static boolean isPrototypeScope(BeanDefinition bd) { - if (!bd.isBean()) - return bd.isPrototype(); - - return "PROTOTYPE".equalsIgnoreCase( - bd.getNode().path("bean").path("scope").asText("SINGLETON") - ); - } - @Override public List getBeans(Class clazz) { return bcs.values().stream() - .map(BeanContainer::getSingleton) + .map(bc -> bc.getOrCreate(this, grammar)) .filter(Objects::nonNull) .filter(clazz::isInstance) .map(clazz::cast) @@ -175,7 +158,7 @@ public List getBeans(Class clazz) { public Optional getBean(Class clazz) { var beans = getBeans(clazz); if (beans.size() > 1) { - var msg = "One bean was asked. But found %d beans of %s".formatted(beans.size(),clazz); + var msg = "One bean was asked. But found %d beans of %s".formatted(beans.size(), clazz); log.error(msg); throw new RuntimeException(msg); } @@ -183,10 +166,36 @@ public Optional getBean(Class clazz) { } public void register(String beanName, Object bean) { + if (bean == null) + throw new IllegalArgumentException("bean must not be null"); + var uuid = UUID.randomUUID().toString(); - BeanContainer bc = new BeanContainer(new BeanDefinition("component", beanName,null, uuid, null)); - bc.setSingleton(bean); - singletonBeans.put(uuid,bean); - bcs.put(uuid, bc); + bcs.put(uuid, + new BeanContainer( + new BeanDefinition( + "component", + computeBeanName(beanName, uuid), + null, + uuid, + null), + bean)); + singletonBeans.put(uuid, bean); + // the return value of 'put' is ignored, since bean registration with + // random keys should not yield duplicates anyway. } + + public T registerIfAbsent(Class type, Supplier supplier) { + synchronized (uniqueClassInitialization) { + return getBean(type).orElseGet(() -> getBean(type).orElseGet(() -> { + T created = supplier.get(); + register(null, created); + return created; + })); + } + } + + private static @NotNull String computeBeanName(String beanName, String uuid) { + return beanName != null ? beanName : "#" + uuid; + } + } diff --git a/core/src/main/java/com/predic8/membrane/core/AbstractRouter.java b/core/src/main/java/com/predic8/membrane/core/AbstractRouter.java new file mode 100644 index 0000000000..f408f7db89 --- /dev/null +++ b/core/src/main/java/com/predic8/membrane/core/AbstractRouter.java @@ -0,0 +1,31 @@ +/* Copyright 2025 predic8 GmbH, www.predic8.com + + 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 com.predic8.membrane.core; + +import com.predic8.membrane.core.proxies.*; +import org.slf4j.*; + +public abstract class AbstractRouter implements Router, MainComponents { + + private static final Logger log = LoggerFactory.getLogger(DefaultRouter.class); + + protected void initProxies() { + log.debug("Initializing proxies."); + for (Proxy proxy : getRuleManager().getRules()) { + log.debug("Initializing proxy {}.", proxy.getName()); + proxy.init(this); + } + } +} diff --git a/core/src/main/java/com/predic8/membrane/core/Configuration.java b/core/src/main/java/com/predic8/membrane/core/Configuration.java index d1dab26928..aeca9ab180 100644 --- a/core/src/main/java/com/predic8/membrane/core/Configuration.java +++ b/core/src/main/java/com/predic8/membrane/core/Configuration.java @@ -37,7 +37,7 @@ public class Configuration { private boolean retryInit = false; - private String jmxRouterName; + private String jmxRouterName = "default"; private URIFactory uriFactory = new URIFactory(false); diff --git a/core/src/main/java/com/predic8/membrane/core/DefaultConfig.java b/core/src/main/java/com/predic8/membrane/core/DefaultConfig.java index 750063b175..8b3bf684d9 100644 --- a/core/src/main/java/com/predic8/membrane/core/DefaultConfig.java +++ b/core/src/main/java/com/predic8/membrane/core/DefaultConfig.java @@ -66,7 +66,7 @@ private void defineRouter(BeanDefinitionRegistry beanDefinitionRegistry) { if (!beanDefinitionRegistry.containsBeanDefinition("router")) { beanDefinitionRegistry.registerBeanDefinition( "router", - root().clazz(Router.class).addRef("transport", "transport").addRef("exchangeStore", "memoryExchangeStore").build()); + root().clazz(DefaultRouter.class).addRef("transport", "transport").addRef("exchangeStore", "memoryExchangeStore").build()); } } diff --git a/core/src/main/java/com/predic8/membrane/core/DefaultMainComponents.java b/core/src/main/java/com/predic8/membrane/core/DefaultMainComponents.java new file mode 100644 index 0000000000..5de49b9eb2 --- /dev/null +++ b/core/src/main/java/com/predic8/membrane/core/DefaultMainComponents.java @@ -0,0 +1,194 @@ +/* Copyright 2025 predic8 GmbH, www.predic8.com + + 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 com.predic8.membrane.core; + +import com.predic8.membrane.annot.*; +import com.predic8.membrane.annot.beanregistry.*; +import com.predic8.membrane.core.config.spring.*; +import com.predic8.membrane.core.exchangestore.*; +import com.predic8.membrane.core.interceptor.*; +import com.predic8.membrane.core.kubernetes.client.*; +import com.predic8.membrane.core.proxies.*; +import com.predic8.membrane.core.resolver.*; +import com.predic8.membrane.core.transport.*; +import com.predic8.membrane.core.transport.http.*; +import com.predic8.membrane.core.transport.http.client.*; +import com.predic8.membrane.core.util.*; +import org.slf4j.*; +import org.springframework.beans.*; +import org.springframework.context.*; + +import java.util.*; + +public class DefaultMainComponents implements MainComponents { + + private static final Logger log = LoggerFactory.getLogger(DefaultRouter.class); + + private DefaultRouter router; + + private ApplicationContext beanFactory; + + protected BeanRegistry registry; + + protected Transport transport; + + private final TimerManager timerManager = new TimerManager(); + private final HttpClientFactory httpClientFactory = new HttpClientFactory(timerManager); + private final KubernetesClientFactory kubernetesClientFactory = new KubernetesClientFactory(httpClientFactory); + protected ResolverMap resolverMap; + + protected final Statistics statistics = new Statistics(); + + + public DefaultMainComponents(DefaultRouter router) { + log.debug("Creating new router."); + this.router = router; + resolverMap = new ResolverMap(httpClientFactory, kubernetesClientFactory); + resolverMap.addRuleResolver(router); + } + + public void init() { + log.debug("Initializing."); + + if (registry == null) { + registry = new BeanRegistryImplementation(null, router, null); + } + + registry.registerIfAbsent(HttpClientConfiguration.class, () -> new HttpClientConfiguration()); + + registry.registerIfAbsent(ResolverMap.class, () -> { + ResolverMap rs = new ResolverMap(httpClientFactory, kubernetesClientFactory); + rs.addRuleResolver(router); + return rs; + }); + + registry.registerIfAbsent(ExchangeStore.class, LimitedMemoryExchangeStore::new); + registry.registerIfAbsent(RuleManager.class, () -> { + RuleManager rm = new RuleManager(); + rm.setRouter(router); + return rm; + }); + registry.registerIfAbsent(DNSCache.class, DNSCache::new); + + // Transport last + if (transport == null) { + transport = new HttpTransport(); + } + transport.init(router); + + } + + public void setRules(Collection proxies) { + getRuleManager().removeAllRules(); + for (Proxy proxy : proxies) + getRuleManager().addProxy(proxy, RuleManager.RuleDefinitionSource.SPRING); + } + + public RuleManager getRuleManager() { + return getRegistry().registerIfAbsent(RuleManager.class, () -> { + RuleManager rm = new RuleManager(); + rm.setRouter(router); + return rm; + }); + } + + public void setApplicationContext(ApplicationContext ctx) throws BeansException { + beanFactory = ctx; + if (ctx instanceof BaseLocationApplicationContext blac) + router.setBaseLocation(blac.getBaseLocation()); + } + + public void setRuleManager(RuleManager ruleManager) { + log.debug("Setting ruleManager."); + ruleManager.setRouter(router); + getRegistry().register("ruleManager", ruleManager); + } + + public ExchangeStore getExchangeStore() { + return getRegistry().getBean(ExchangeStore.class).orElseThrow(); + } + + public void setExchangeStore(ExchangeStore exchangeStore) { + getRegistry().register("exchangeStore", exchangeStore); + } + + @Override + public Transport getTransport() { + return transport; + } + + public void setTransport(Transport transport) { + this.transport = transport; + } + + public HttpClientConfiguration getHttpClientConfig() { + return getResolverMap().getHTTPSchemaResolver().getHttpClientConfig(); + } + + public void setHttpClientConfig(HttpClientConfiguration httpClientConfig) { + getResolverMap().getHTTPSchemaResolver().setHttpClientConfig(httpClientConfig); + } + + public DNSCache getDnsCache() { + return getRegistry().getBean(DNSCache.class).orElseThrow(); // TODO + } + + public ResolverMap getResolverMap() { + return resolverMap; + } + + public Statistics getStatistics() { + return statistics; + } + + public void setGlobalInterceptor(GlobalInterceptor globalInterceptor) { + getRegistry().register("globalInterceptor", globalInterceptor); + } + + public TimerManager getTimerManager() { + return timerManager; + } + + public KubernetesClientFactory getKubernetesClientFactory() { + return kubernetesClientFactory; + } + + public HttpClientFactory getHttpClientFactory() { + return httpClientFactory; + } + + public FlowController getFlowController() { + return getRegistry().registerIfAbsent(FlowController.class, () -> new FlowController(router)); + } + + public void setRegistry(BeanRegistry registry) { + this.registry = registry; + } + + public BeanRegistry getRegistry() { + if (registry == null) + registry = new BeanRegistryImplementation(null, router, null); + return registry; + } + + public URIFactory getUriFactory() { + throw new UnsupportedOperationException(); + } + + @Override + public ApplicationContext getBeanFactory() { + return beanFactory; + } +} diff --git a/core/src/main/java/com/predic8/membrane/core/DefaultRouter.java b/core/src/main/java/com/predic8/membrane/core/DefaultRouter.java new file mode 100644 index 0000000000..f63f1f8d27 --- /dev/null +++ b/core/src/main/java/com/predic8/membrane/core/DefaultRouter.java @@ -0,0 +1,520 @@ +/* Copyright 2009, 2012 predic8 GmbH, www.predic8.com + + 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 com.predic8.membrane.core; + +import com.predic8.membrane.annot.*; +import com.predic8.membrane.annot.beanregistry.*; +import com.predic8.membrane.core.RuleManager.*; +import com.predic8.membrane.core.config.spring.*; +import com.predic8.membrane.core.exchangestore.*; +import com.predic8.membrane.core.interceptor.*; +import com.predic8.membrane.core.interceptor.administration.*; +import com.predic8.membrane.core.jmx.*; +import com.predic8.membrane.core.kubernetes.*; +import com.predic8.membrane.core.kubernetes.client.*; +import com.predic8.membrane.core.openapi.*; +import com.predic8.membrane.core.openapi.serviceproxy.*; +import com.predic8.membrane.core.proxies.*; +import com.predic8.membrane.core.resolver.*; +import com.predic8.membrane.core.router.hotdeploy.*; +import com.predic8.membrane.core.transport.*; +import com.predic8.membrane.core.transport.http.*; +import com.predic8.membrane.core.transport.http.client.*; +import com.predic8.membrane.core.util.*; +import org.slf4j.*; +import org.springframework.beans.*; +import org.springframework.beans.factory.*; +import org.springframework.context.*; +import org.springframework.context.support.*; + +import javax.annotation.concurrent.*; +import java.io.*; +import java.util.*; + +import static com.predic8.membrane.core.RuleManager.RuleDefinitionSource.*; +import static com.predic8.membrane.core.jmx.JmxExporter.*; +import static com.predic8.membrane.core.util.DLPUtil.*; + +/* + Responsibilities: + - Start and stop Membrane + - Start, stop internal services + - Control lifecycle of proxies + + TODO: + - ADR: First start router than init and add proxies or first init proxies and add them later? + + ADR: + - The Router is responsible for the lifecycle of the proxies + - Ports are opened in start() + - init() + - does not open ports + - inits the proxies + - In sequence as added or reverse or not defined? + - new Router(), add(proxy) init() start() + - add(proxy) could be called any time + - If router is started port will be opened if needed by the proxy + - What if a proxy needs to make a call to another proxy during init(Tests: e.g. B2C) + - Delete addProxyAndOpenPortIfNew() from RuleManager + + HTTPRouter: + - Purpose? Test? + + - JMX + - Beans added after Router.start() should also be exported as JMS beans + + */ + +/** + * @description

+ * Membrane API Gateway's main object. + *

+ *

+ * The router is a Spring Lifecycle object: It is automatically started and stopped according to the + * Lifecycle of the Spring Context containing it. In Membrane's standard setup + * Membrane itself controls the creation of the Spring Context and its Lifecycle. + *

+ *

+ * In this case, the router is hot deployable: It can monitor proxies.xml, the Spring + * configuration file, for changes and reinitialize the Spring Context, when a change is detected. Note + * that, during the Spring Context restart, the router object itself along with almost all other Membrane + * objects (interceptors, etc.) will be recreated. + *

+ *

Router must be a singleton with just one instance. Membrane should never have more than one router.

+ * @topic 1. Proxies and Flow + */ +@MCMain( + outputPackage = "com.predic8.membrane.core.config.spring", + outputName = "router-conf.xsd", + targetNamespace = "http://membrane-soa.org/proxies/1/") +@MCElement(name = "router") +public class DefaultRouter extends AbstractRouter implements ApplicationContextAware, BeanRegistryAware, BeanNameAware, BeanCacheObserver { + + private static final Logger log = LoggerFactory.getLogger(DefaultRouter.class); + + protected DefaultMainComponents mainComponents; + + // + // Configuration + // + private String id; + private String baseLocation; + + private Configuration configuration = new Configuration(); + + private final Object lock = new Object(); + + @GuardedBy("lock") + private boolean running; + + @GuardedBy("lock") + private boolean initialized; + + /** + * HotDeployer for changes on the XML configuration file. Does not cover YAML. + * Not synchronized, since only modified during initialization + */ + private HotDeployer hotDeployer = new DefaultHotDeployer(); + + private RuleReinitializer reinitializer; + + public DefaultRouter() { + log.debug("Creating new router."); + mainComponents = new DefaultMainComponents(this); + } + + /** + * Initializes the {@code Router} + * - by setting up its associated components. + * - calling init() on each of its {@link Proxy} instances. + *

+ * This method ensures that the {@code Router} and its dependencies are prepared for operation. + * But it does not start the router itself. Use {@link #start()} to start the router. + * If start() is called a separate call to init() is not needed. + * The init() is useful for testing without the expensive start() call. + */ + public void init() { + log.debug("Initializing."); + + // TODO: Temporary guard, to check correct behaviour, remove later + synchronized (lock) { + if (initialized) + throw new IllegalStateException("Router already initialized."); + + mainComponents.init(); + + initProxies(); + + initialized = true; + reinitializer = new RuleReinitializer(this); // Bean + } + } + + /** + * Starts the main processing logic of the application. + * This method initializes essential components, validates the configuration, + * and starts background services required for the application's functionality. + * Key responsibilities: + * - Initializes the application if it hasn't been initialized yet. + * - Opens TCP ports + */ + @Override + public void start() { + log.debug("Starting."); + displayTraceWarning(); + + synchronized (lock) { + if (!initialized) + init(); + } + + try { + + getRegistry().getBean(KubernetesWatcher.class).ifPresent(KubernetesWatcher::start); + + startJmx(); + getRuleManager().openPorts(); + + hotDeployer.start(this); + + if (configuration.getRetryInitInterval() > 0) + reinitializer.start(); + } catch (DuplicatePathException e) { + handleDuplicateOpenAPIPaths(e); + } catch (OpenAPIParsingException e) { + handleOpenAPIParsingException(e); + } catch (Exception e) { + log.error("Could not start router.", e); + if (e instanceof RuntimeException) + throw (RuntimeException) e; + throw new RuntimeException(e); + } + + synchronized (lock) { + running = true; + } + } + + @MCChildElement(order = 3) + public void setRules(Collection proxies) { + getRuleManager().removeAllRules(); + for (Proxy proxy : proxies) + getRuleManager().addProxy(proxy, RuleDefinitionSource.SPRING); + } + + public Collection getRules() { + return getRuleManager().getRules(); + } + + @SuppressWarnings("NullableProblems") + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + mainComponents.setApplicationContext(applicationContext); + } + + public RuleManager getRuleManager() { + return mainComponents.getRuleManager(); + } + + public void setRuleManager(RuleManager ruleManager) { + mainComponents.setRuleManager(ruleManager); + } + + public ExchangeStore getExchangeStore() { + return mainComponents.getExchangeStore(); + } + + /** + * @description Spring Bean ID of an {@link ExchangeStore}. The exchange store will be used by this router's + * components ({@link AdminConsoleInterceptor}, {@link ExchangeStoreInterceptor}, etc.) by default, if + * no other exchange store is explicitly set to be used by them. + * @default create a {@link LimitedMemoryExchangeStore} limited to the size of 1 MB. + */ + @MCAttribute + public void setExchangeStore(ExchangeStore exchangeStore) { + mainComponents.setExchangeStore(exchangeStore); + } + + @Override + public Transport getTransport() { + return mainComponents.getTransport(); + } + + /** + * @description Used to override the default 'transport' chain. The transport chain is the one global + * interceptor chain called *for every* incoming HTTP Exchanges. The transport chain uses <userFeature/> + * to call 'down' to a specific <api/>, <serviceProxy/> or similar. The default transport chain + * is shown in proxies-full-sample.xml . + */ + @MCChildElement(order = 1, allowForeign = true) + public void setTransport(Transport transport) { + mainComponents.setTransport(transport); + } + + public HttpClientConfiguration getHttpClientConfig() { + return mainComponents.getHttpClientConfig(); + } + + /** + * @description A 'global' (per router) <httpClientConfig>. This instance is used everywhere + * a HTTP Client is used. In every specific place, you should still be able to configure a local + * <httpClientConfig> (with higher precedence compared to this global instance). + */ + @MCChildElement() + public void setHttpClientConfig(HttpClientConfiguration httpClientConfig) { + mainComponents.setHttpClientConfig(httpClientConfig); + } + + public DNSCache getDnsCache() { + return mainComponents.getDnsCache(); + } + + public ResolverMap getResolverMap() { + return mainComponents.getResolverMap(); + } + + /** + * Adds a proxy to the router and initializes it. + * Can be called at any time before or after start(). + * + * TODO: Should we sync running cause a different Thread might call add? + * + * @param proxy + * @throws IOException + */ + public void add(Proxy proxy) throws IOException { + log.debug("Adding proxy {}.", proxy.getName()); + RuleManager ruleManager = getRuleManager(); + + if (running && proxy instanceof SSLableProxy sp) { + sp.init(this); + ruleManager.addProxyAndOpenPortIfNew(sp); + } else { + ruleManager.addProxy(proxy, MANUAL); + } + + } + + private void startJmx() { + if (mainComponents.getBeanFactory() == null) { + log.info("No bean factory available, not starting JMX."); + return; + } + log.debug("Starting JMX."); + try { + JmxExporter exporter = mainComponents.getBeanFactory().getBean(JMX_EXPORTER_NAME, JmxExporter.class); + //exporter.removeBean(prefix + jmxRouterName); + exporter.addBean("io.membrane-api:00=routers, name=" + configuration.getJmx(), new JmxRouter(this, exporter)); + exporter.initAfterBeansAdded(); + } catch (NoSuchBeanDefinitionException ignored) { + // If bean is not available do not init jmx + } + } + + @Override + public void stop() { + getRegistry().getBean(KubernetesWatcher.class).ifPresent(KubernetesWatcher::stop); + hotDeployer.stop(); + + if (mainComponents.getTransport() != null) + mainComponents.getTransport().closeAll(); + mainComponents.getTimerManager().shutdown(); + + synchronized (lock) { + running = false; + lock.notifyAll(); + } + } + + @Override + public boolean isRunning() { + synchronized (lock) { + return running; + } + } + + public String getBaseLocation() { + return baseLocation; + } + + public void setBaseLocation(String baseLocation) { + this.baseLocation = baseLocation; + } + + public ApplicationContext getBeanFactory() { + return mainComponents.getBeanFactory(); + } + + public boolean isProduction() { + return configuration.isProduction(); + } + + public Statistics getStatistics() { + return mainComponents.getStatistics(); + } + + @SuppressWarnings("NullableProblems") + @Override + public void setBeanName(String s) { + this.id = s; + } + + /** + * @description Sets a global chain that applies to all requests and responses. + */ + @MCChildElement(order = 2) + public void setGlobalInterceptor(GlobalInterceptor globalInterceptor) { + mainComponents.setGlobalInterceptor(globalInterceptor); + } + + public String getId() { + return id; + } + + /** + * waits until the router has shut down + */ + public void waitFor() { + synchronized (lock) { + while (running) { + try { + lock.wait(); + } catch (InterruptedException ignored) { + } + } + } + } + + public TimerManager getTimerManager() { + return mainComponents.getTimerManager(); + } + + public KubernetesClientFactory getKubernetesClientFactory() { + return mainComponents.getKubernetesClientFactory(); + } + + public HttpClientFactory getHttpClientFactory() { + return mainComponents.getHttpClientFactory(); + } + + public FlowController getFlowController() { + return mainComponents.getFlowController(); + } + + public void handleAsynchronousInitializationResult(boolean success) { + log.debug("Asynchronous initialization finished."); + if (!success && !configuration.isRetryInit()) + System.exit(1); + ApiInfo.logInfosAboutStartedProxies(getRuleManager()); + } + + @Override + public void handleBeanEvent(BeanDefinitionChanged bdc, Object bean, Object oldBean) throws IOException { + log.debug("Bean changed: type={} instance={}", bean.getClass().getSimpleName(), bean); + if (!(bean instanceof Proxy newProxy)) { + // should not happen, as handleBeanEvent() is only called for beans passing isActivatable(). + throw new IllegalArgumentException("Bean must be a Proxy instance, but got: " + bean.getClass().getName()); + } + + if (newProxy.getName() == null) + newProxy.setName(bdc.bd().getName()); + + if (bdc.action().isAdded()) { + add(newProxy); + } else if (bdc.action().isDeleted()) + getRuleManager().removeRule((Proxy) oldBean); + else if (bdc.action().isModified()) { + getRuleManager().replaceRule((Proxy) oldBean, newProxy); + } + } + + @Override + public boolean isActivatable(BeanDefinition bd) { + return Proxy.class.isAssignableFrom(new GrammarAutoGenerated().getElement(bd.getKind())); + } + + public AbstractRefreshableApplicationContext getRef() { + if (mainComponents.getBeanFactory() instanceof AbstractRefreshableApplicationContext bf) + return bf; + throw new RuntimeException("ApplicationContext is not a AbstractRefreshableApplicationContext. Please set ."); + } + + @Override + public void setRegistry(BeanRegistry registry) { + mainComponents.setRegistry(registry); + } + + public BeanRegistry getRegistry() { + return mainComponents.getRegistry(); + } + + public void applyConfiguration(Configuration configuration) { + hotDeployer = configuration.isHotDeploy() ? new DefaultHotDeployer() : new NullHotDeployer(); + this.configuration = configuration; + } + + public URIFactory getUriFactory() { + return configuration.getUriFactory(); + } + + /** + * Sets the configuration object for this router. + * Only used for xml + * + * @param configuration the configuration object + */ + @MCChildElement(order = -1) + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } + + public Configuration getConfiguration() { + return configuration; + } + + public RuleReinitializer getReinitializer() { + return reinitializer; + } + + private static void handleOpenAPIParsingException(OpenAPIParsingException e) { + System.err.printf(""" + ================================================================================================ + + Configuration Error: Could not read or parse OpenAPI Document + + Reason: %s + + Location: %s + + Have a look at the proxies.xml file. + """, e.getMessage(), e.getLocation()); + throw new ExitException(); + } + + private static void handleDuplicateOpenAPIPaths(DuplicatePathException e) { + System.err.printf(""" + ================================================================================================ + + Configuration Error: Several OpenAPI Documents share the same path! + + An API routes and validates requests according to the path of the OpenAPI's servers.url fields. + Within one API the same path should be used only by one OpenAPI. Change the paths or place + openapi-elements into separate api-elements. + + Shared path: %s + %n""", e.getPath()); + throw new ExitException(); + } +} \ No newline at end of file diff --git a/core/src/main/java/com/predic8/membrane/core/DummyTestRouter.java b/core/src/main/java/com/predic8/membrane/core/DummyTestRouter.java new file mode 100644 index 0000000000..fbca1b94e3 --- /dev/null +++ b/core/src/main/java/com/predic8/membrane/core/DummyTestRouter.java @@ -0,0 +1,197 @@ +/* Copyright 2009, 2011, 2012 predic8 GmbH, www.predic8.com + + 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 com.predic8.membrane.core; + +import com.predic8.membrane.core.exchangestore.*; +import com.predic8.membrane.core.interceptor.*; +import com.predic8.membrane.core.kubernetes.client.*; +import com.predic8.membrane.core.proxies.*; +import com.predic8.membrane.core.resolver.*; +import com.predic8.membrane.core.transport.http.*; +import com.predic8.membrane.core.transport.http.client.*; +import com.predic8.membrane.core.util.*; +import org.springframework.context.*; + +import java.io.*; +import java.util.*; + +import static com.predic8.membrane.core.RuleManager.RuleDefinitionSource.MANUAL; + +/** + * TODO rename this class: It is also being used in case the router is being started + * from the command line (=in a non-test environment). + */ +public class DummyTestRouter extends AbstractRouter { + + private FlowController flowController = new FlowController(this); + private ExchangeStore exchangeStore = new LimitedMemoryExchangeStore(); + private RuleManager ruleManager = new RuleManager(); + + private final TimerManager timerManager = new TimerManager(); + private final HttpClientFactory httpClientFactory = new HttpClientFactory(timerManager); + private final KubernetesClientFactory kubernetesClientFactory = new KubernetesClientFactory(httpClientFactory); + private ResolverMap resolverMap = new ResolverMap(httpClientFactory, kubernetesClientFactory); + + private HttpTransport transport; + + private DNSCache dnsCache = new DNSCache(); + + private URIFactory uriFactory = new URIFactory(); + + private final Statistics statistics = new Statistics(); + private ApplicationContext applicationContext; + + private String baseLocation; + + private Configuration configuration = new Configuration(); + + public DummyTestRouter() { + this(null); + } + + public DummyTestRouter(ProxyConfiguration proxyConfiguration) { + transport = createTransport(); + if (proxyConfiguration != null) + getResolverMap().getHTTPSchemaResolver().getHttpClientConfig().setProxy(proxyConfiguration); + } + + @Override + public void init() { + initProxies(); + } + + @Override + public void add(Proxy proxy) throws IOException { + ruleManager.addProxy(proxy, MANUAL); + } + + @Override + public Configuration getConfiguration() { + return configuration; + } + + @Override + public FlowController getFlowController() { + return flowController; + } + + @Override + public ExchangeStore getExchangeStore() { + return exchangeStore; + } + + @Override + public RuleManager getRuleManager() { + return ruleManager; + } + + @Override + public String getBaseLocation() { + return baseLocation; + } + + @Override + public ResolverMap getResolverMap() { + return resolverMap; + } + + @Override + public DNSCache getDnsCache() { + return dnsCache; + } + + @Override + public HttpTransport getTransport() { + return transport; + } + + @Override + public URIFactory getUriFactory() { + return uriFactory; + } + + @Override + public ApplicationContext getBeanFactory() { + return applicationContext; + } + + @Override + public HttpClientFactory getHttpClientFactory() { + return null; + } + + @Override + public TimerManager getTimerManager() { + return timerManager; + } + + @Override + public Statistics getStatistics() { + return statistics; + } + + /** + * Same as the default config from monitor-beans.xml + * + * TODO: Sync somehow with standard transport order maybe TransportConfig class or in Transport? + */ + private static HttpTransport createTransport() { + HttpTransport transport = new HttpTransport(); + List interceptors = new ArrayList<>(); + interceptors.add(new RuleMatchingInterceptor()); + interceptors.add(new DispatchingInterceptor()); + interceptors.add(new UserFeatureInterceptor()); + interceptors.add(new InternalRoutingInterceptor()); + HTTPClientInterceptor httpClientInterceptor = new HTTPClientInterceptor(); + interceptors.add(httpClientInterceptor); + transport.setFlow(interceptors); + return transport; + } + + @Override + public void start() { + + } + + @Override + public void stop() { + + } + + @Override + public boolean isRunning() { + return false; + } + + public void setExchangeStore(ExchangeStore exchangeStore) { + this.exchangeStore = exchangeStore; + } + + public void setHttpClientConfig(HttpClientConfiguration httpClientConfig) { + throw new UnsupportedOperationException(); + } + + public HttpClientConfiguration getHttpClientConfig() { + return resolverMap.getHTTPSchemaResolver().getHttpClientConfig(); + } + + public void setApplicationContext(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + public void setBaseLocation(String baseLocation) { + this.baseLocation = baseLocation; + } +} diff --git a/core/src/main/java/com/predic8/membrane/core/HttpRouter.java b/core/src/main/java/com/predic8/membrane/core/HttpRouter.java index 1bde0fe7cb..d219639291 100644 --- a/core/src/main/java/com/predic8/membrane/core/HttpRouter.java +++ b/core/src/main/java/com/predic8/membrane/core/HttpRouter.java @@ -1,4 +1,4 @@ -/* Copyright 2009, 2011, 2012 predic8 GmbH, www.predic8.com +/* Copyright 2025 predic8 GmbH, www.predic8.com Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,52 +14,12 @@ package com.predic8.membrane.core; -import com.predic8.membrane.core.interceptor.*; -import com.predic8.membrane.core.transport.*; import com.predic8.membrane.core.transport.http.*; -import com.predic8.membrane.core.transport.http.client.*; -import java.util.*; - -public class HttpRouter extends Router { - - public HttpRouter() { - this(null); - } - - public HttpRouter(ProxyConfiguration proxyConfiguration) { - transport = createTransport(); - resolverMap.getHTTPSchemaResolver().getHttpClientConfig().setProxy(proxyConfiguration); - } - - /** - * Same as the default config from monitor-beans.xml - */ - private Transport createTransport() { - Transport transport = new HttpTransport(); - List interceptors = new ArrayList<>(); - interceptors.add(new RuleMatchingInterceptor()); - interceptors.add(new DispatchingInterceptor()); - interceptors.add(new UserFeatureInterceptor()); - interceptors.add(new InternalRoutingInterceptor()); - HTTPClientInterceptor httpClientInterceptor = new HTTPClientInterceptor(); - interceptors.add(httpClientInterceptor); - transport.setFlow(interceptors); - return transport; - } - - @Override - public HttpTransport getTransport() { - return (HttpTransport)transport; - } - - /** - * TODO Only used for tests. It s brittle cause it is dependent on - * the list. In tests interceptors in the proxy can be used instead. - */ - public void addUserFeatureInterceptor(Interceptor i) { - List is = getTransport().getFlow(); - is.add(is.size()-3, i); - } +public class HttpRouter extends DefaultRouter { + @Override + public HttpTransport getTransport() { + return (HttpTransport) super.getTransport(); + } } diff --git a/core/src/main/java/com/predic8/membrane/core/MainComponents.java b/core/src/main/java/com/predic8/membrane/core/MainComponents.java new file mode 100644 index 0000000000..003b3efa5b --- /dev/null +++ b/core/src/main/java/com/predic8/membrane/core/MainComponents.java @@ -0,0 +1,50 @@ +/* Copyright 2025 predic8 GmbH, www.predic8.com + + 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 com.predic8.membrane.core; + +import com.predic8.membrane.core.exchangestore.*; +import com.predic8.membrane.core.interceptor.*; +import com.predic8.membrane.core.resolver.*; +import com.predic8.membrane.core.transport.*; +import com.predic8.membrane.core.transport.http.*; +import com.predic8.membrane.core.util.*; +import org.springframework.context.*; + +public interface MainComponents { + + Transport getTransport(); + + FlowController getFlowController(); + + ExchangeStore getExchangeStore(); + + void setExchangeStore(ExchangeStore exchangeStore); + + RuleManager getRuleManager(); + + ResolverMap getResolverMap(); + + DNSCache getDnsCache(); + + URIFactory getUriFactory(); + + ApplicationContext getBeanFactory(); + + HttpClientFactory getHttpClientFactory(); + + TimerManager getTimerManager(); + + Statistics getStatistics(); +} diff --git a/core/src/main/java/com/predic8/membrane/core/Router.java b/core/src/main/java/com/predic8/membrane/core/Router.java index 454c3670a9..f078c94926 100644 --- a/core/src/main/java/com/predic8/membrane/core/Router.java +++ b/core/src/main/java/com/predic8/membrane/core/Router.java @@ -1,4 +1,4 @@ -/* Copyright 2009, 2012 predic8 GmbH, www.predic8.com +/* Copyright 2025 predic8 GmbH, www.predic8.com Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,601 +14,19 @@ package com.predic8.membrane.core; -import com.predic8.membrane.annot.*; -import com.predic8.membrane.annot.beanregistry.*; -import com.predic8.membrane.core.RuleManager.*; -import com.predic8.membrane.core.config.spring.*; -import com.predic8.membrane.core.exchangestore.*; -import com.predic8.membrane.core.interceptor.*; -import com.predic8.membrane.core.interceptor.administration.*; -import com.predic8.membrane.core.jmx.*; -import com.predic8.membrane.core.kubernetes.*; -import com.predic8.membrane.core.kubernetes.client.*; -import com.predic8.membrane.core.openapi.*; -import com.predic8.membrane.core.openapi.serviceproxy.*; import com.predic8.membrane.core.proxies.*; -import com.predic8.membrane.core.resolver.*; -import com.predic8.membrane.core.router.hotdeploy.*; -import com.predic8.membrane.core.transport.*; -import com.predic8.membrane.core.transport.http.*; -import com.predic8.membrane.core.transport.http.client.*; -import com.predic8.membrane.core.util.*; -import org.slf4j.*; -import org.springframework.beans.*; -import org.springframework.beans.factory.*; import org.springframework.context.*; -import org.springframework.context.support.*; -import org.springframework.core.io.*; -import javax.annotation.concurrent.*; import java.io.*; -import java.nio.charset.*; -import java.util.*; -import java.util.Timer; -import java.util.concurrent.*; -import static com.predic8.membrane.core.jmx.JmxExporter.*; -import static com.predic8.membrane.core.util.DLPUtil.*; -import static java.util.concurrent.Executors.*; +public interface Router extends Lifecycle, MainComponents { -/** - * @description

- * Membrane API Gateway's main object. - *

- *

- * The router is a Spring Lifecycle object: It is automatically started and stopped according to the - * Lifecycle of the Spring Context containing it. In Membrane's standard setup (standalone or in a J2EE web - * app), Membrane itself controls the creation of the Spring Context and its Lifecycle. - *

- *

- * In this case, the router is hot deployable: It can monitor proxies.xml, the Spring - * configuration file, for changes and reinitialize the Spring Context, when a change is detected. Note - * that, during the Spring Context restart, the router object itself along with almost all other Membrane - * objects (interceptors, etc.) will be recreated. - *

- *

Router must be a singleton with just one instance. Membrane should never have more than one router.

- * @topic 1. Proxies and Flow - */ -@MCMain( - outputPackage = "com.predic8.membrane.core.config.spring", - outputName = "router-conf.xsd", - targetNamespace = "http://membrane-soa.org/proxies/1/") -@MCElement(name = "router") -public class Router implements Lifecycle, ApplicationContextAware, BeanRegistryAware, BeanNameAware, BeanCacheObserver { + void init(); - private static final Logger log = LoggerFactory.getLogger(Router.class.getName()); + void add(Proxy proxy) throws IOException; - private ApplicationContext beanFactory; + Configuration getConfiguration(); - private BeanRegistry registry; + String getBaseLocation(); - /** - * Indicates whether the router should automatically open TCP ports when adding proxies. - * This flag determines if the ports associated with the proxies are opened immediately - * when they are added to the router. Setting this to {@code false} allows for proxies - * to be defined without opening the associated ports, providing more control over when - * the ports are made accessible. - */ - private boolean openPorts = true; - - // - // Configuration - // - private String id; - private String baseLocation; - - private Configuration config = new Configuration(); - - // - // Components - // - protected RuleManager ruleManager = new RuleManager(); - protected final FlowController flowController; - protected ExchangeStore exchangeStore = new LimitedMemoryExchangeStore(); - protected Transport transport; - protected final ResolverMap resolverMap; - protected final DNSCache dnsCache = new DNSCache(); - private final KubernetesWatcher kubernetesWatcher = new KubernetesWatcher(this); - private final TimerManager timerManager = new TimerManager(); - private final HttpClientFactory httpClientFactory = new HttpClientFactory(timerManager); - private final KubernetesClientFactory kubernetesClientFactory = new KubernetesClientFactory(httpClientFactory); - - protected final ExecutorService backgroundInitializer = - newSingleThreadExecutor(new HttpServerThreadFactory("Router Background Initializer")); - - - protected final Statistics statistics = new Statistics(); - - private final Object lock = new Object(); - - @GuardedBy("lock") - private boolean running; - - // - // Reinitialization - // - private Timer reinitializer; - - /** - * HotDeployer for changes on the XML configuration file. Does not cover YAML. - * Not synchronized, since only modified during initialization - * Initialized with NullHotDeployer to avoid NPEs - */ - private HotDeployer hotDeployer = new DefaultHotDeployer(); - - public Router() { - ruleManager.setRouter(this); - resolverMap = new ResolverMap(httpClientFactory, kubernetesClientFactory); - resolverMap.addRuleResolver(this); - flowController = new FlowController(this); - } - - // - // Initialization - // - - public void init() throws Exception { - initRemainingRules(); - transport.init(this); - displayTraceWarning(); - } - - private void initRemainingRules() throws Exception { - for (Proxy proxy : getRuleManager().getRules()) - proxy.init(this); - } - - public static Router init(String resource) { - log.debug("loading spring config: {}", resource); - - TrackingFileSystemXmlApplicationContext bf = - new TrackingFileSystemXmlApplicationContext(new String[]{resource}, false); - bf.refresh(); - bf.start(); - - if (bf.getBeansOfType(Router.class).size() > 1) { - throw new RuntimeException("More than one router found in spring config (beans %s). This is not supported anymore.".formatted(bf.getBeanDefinitionNames())); - } - - return bf.getBean("router", Router.class); - } - - public static Router initFromXMLString(String xmlString) { - GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(); - ctx.load(new ByteArrayResource(xmlString.getBytes(StandardCharsets.UTF_8))); - ctx.refresh(); - ctx.start(); - return ctx.getBean(Router.class); - } - - @Override - public void start() { - try { - if (exchangeStore == null) - exchangeStore = new LimitedMemoryExchangeStore(); - if (transport == null) - transport = new HttpTransport(); - kubernetesWatcher.start(); - - init(); - initJmx(); - getRuleManager().openPorts(); - - try { - hotDeployer.init(this); - hotDeployer.start(); - } catch (Exception e) { - shutdown(); - throw e; - } - - if (config.getRetryInitInterval() > 0) - startAutoReinitializer(); - } catch (DuplicatePathException e) { - System.err.printf(""" - ================================================================================================ - - Configuration Error: Several OpenAPI Documents share the same path! - - An API routes and validates requests according to the path of the OpenAPI's servers.url fields. - Within one API the same path should be used only by one OpenAPI. Change the paths or place - openapi-elements into separate api-elements. - - Shared path: %s - %n""", e.getPath()); - throw new ExitException(); - } catch (OpenAPIParsingException e) { - System.err.printf(""" - ================================================================================================ - - Configuration Error: Could not read or parse OpenAPI Document - - Reason: %s - - Location: %s - - Have a look at the proxies.xml file. - """, e.getMessage(), e.getLocation()); - throw new ExitException(); - } catch (Exception e) { - if (e instanceof RuntimeException) - throw (RuntimeException) e; - throw new RuntimeException(e); - } - - startJmx(); - - synchronized (lock) { - running = true; - } - } - - public Collection getRules() { - return getRuleManager().getRulesBySource(RuleDefinitionSource.SPRING); - } - - @MCChildElement(order = 3) - public void setRules(Collection proxies) { - getRuleManager().removeAllRules(); - for (Proxy proxy : proxies) - getRuleManager().addProxy(proxy, RuleDefinitionSource.SPRING); - } - - @SuppressWarnings("NullableProblems") - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - beanFactory = applicationContext; - if (applicationContext instanceof BaseLocationApplicationContext) - setBaseLocation(((BaseLocationApplicationContext) applicationContext).getBaseLocation()); - } - - public RuleManager getRuleManager() { - return ruleManager; - } - - public void setRuleManager(RuleManager ruleManager) { - this.ruleManager = ruleManager; - ruleManager.setRouter(this); - } - - public ExchangeStore getExchangeStore() { - return exchangeStore; - } - - /** - * @description Spring Bean ID of an {@link ExchangeStore}. The exchange store will be used by this router's - * components ({@link AdminConsoleInterceptor}, {@link ExchangeStoreInterceptor}, etc.) by default, if - * no other exchange store is explicitly set to be used by them. - * @default create a {@link LimitedMemoryExchangeStore} limited to the size of 1 MB. - */ - @MCAttribute - public void setExchangeStore(ExchangeStore exchangeStore) { - this.exchangeStore = exchangeStore; - } - - public Transport getTransport() { - return transport; - } - - /** - * @description Used to override the default 'transport' chain. The transport chain is the one global - * interceptor chain called *for every* incoming HTTP Exchanges. The transport chain uses <userFeature/> - * to call 'down' to a specific <api/>, <serviceProxy/> or similar. The default transport chain - * is shown in proxies-full-sample.xml . - */ - @MCChildElement(order = 1, allowForeign = true) - public void setTransport(Transport transport) { - this.transport = transport; - } - - public HttpClientConfiguration getHttpClientConfig() { - return resolverMap.getHTTPSchemaResolver().getHttpClientConfig(); - } - - /** - * @description A 'global' (per router) <httpClientConfig>. This instance is used everywhere - * a HTTP Client is used. Usually, in every specific place, you can still configure a local - * <httpClientConfig> (with higher precedence compared to this global instance). - */ - @MCChildElement() - public void setHttpClientConfig(HttpClientConfiguration httpClientConfig) { - resolverMap.getHTTPSchemaResolver().setHttpClientConfig(httpClientConfig); - } - - public DNSCache getDnsCache() { - return dnsCache; - } - - public ResolverMap getResolverMap() { - return resolverMap; - } - - /** - * Closes all ports (if any were opened) and waits for running exchanges to complete. - *

- * When running as an embedded servlet, this has no effect. - */ - public void shutdown() { - backgroundInitializer.shutdown(); - if (transport != null) - transport.closeAll(); - timerManager.shutdown(); - } - - public ExecutorService getBackgroundInitializer() { - return backgroundInitializer; - } - - public void add(Proxy proxy) throws IOException { - if (proxy instanceof SSLableProxy sp) { - if (openPorts) - ruleManager.addProxyAndOpenPortIfNew(sp); - else - ruleManager.addProxy(sp, RuleDefinitionSource.MANUAL); - } else { - ruleManager.addProxy(proxy, RuleDefinitionSource.MANUAL); - } - } - - private void startJmx() { - if (getBeanFactory() == null) - return; - - try { - getBeanFactory().getBean(JMX_EXPORTER_NAME, JmxExporter.class).initAfterBeansAdded(); - } catch (NoSuchBeanDefinitionException ignored) { - // If bean is not available, then don't start jmx - } - - } - - private void initJmx() { - if (beanFactory == null) - return; - - try { - JmxExporter exporter = beanFactory.getBean(JMX_EXPORTER_NAME, JmxExporter.class); - //exporter.removeBean(prefix + jmxRouterName); - exporter.addBean("org.membrane-soa:00=routers, name=" + config.getJmx(), new JmxRouter(this, exporter)); - } catch (NoSuchBeanDefinitionException ignored) { - // If bean is not available do not init jmx - } - - } - - // - // Reinitialization - // - - private void startAutoReinitializer() { - if (getInactiveRules().isEmpty()) - return; - - reinitializer = new Timer("auto reinitializer", true); - reinitializer.schedule(new TimerTask() { - @Override - public void run() { - tryReinitialization(); - } - }, config.getRetryInitInterval(), config.getRetryInitInterval()); - } - - public void tryReinitialization() { - boolean stillFailing = false; - ArrayList inactive = getInactiveRules(); - if (!inactive.isEmpty()) { - log.info("Trying to activate all inactive rules."); - for (Proxy proxy : inactive) { - try { - log.info("Trying to start API {}.", proxy.getName()); - Proxy newProxy = proxy.clone(); - if (!newProxy.isActive()) { - log.warn("New rule for API {} is still not active.", proxy.getName()); - stillFailing = true; - } - getRuleManager().replaceRule(proxy, newProxy); - } catch (CloneNotSupportedException e) { - log.error("", e); - } - } - } - if (stillFailing) - log.info("There are still inactive rules."); - else { - stopAutoReinitializer(); - log.info("All rules have been initialized."); - } - } - - public void stopAutoReinitializer() { - if (reinitializer != null) { - reinitializer.cancel(); - } - } - - @Override - public void stop() { - kubernetesWatcher.stop(); - hotDeployer.stop(); - shutdown(); - - synchronized (lock) { - running = false; - lock.notifyAll(); - } - } - - @Override - public boolean isRunning() { - synchronized (lock) { - return running; - } - } - - private ArrayList getInactiveRules() { - ArrayList inactive = new ArrayList<>(); - for (Proxy proxy : getRuleManager().getRules()) - if (!proxy.isActive()) - inactive.add(proxy); - return inactive; - } - - public String getBaseLocation() { - return baseLocation; - } - - public void setBaseLocation(String baseLocation) { - this.baseLocation = baseLocation; - } - - public ApplicationContext getBeanFactory() { - return beanFactory; - } - - public boolean isProduction() { - return config.isProduction(); - } - - public Statistics getStatistics() { - return statistics; - } - - @SuppressWarnings("NullableProblems") - @Override - public void setBeanName(String s) { - this.id = s; - } - - /** - * @description Sets a global chain that applies to all requests and responses. - */ - @MCChildElement(order = 2) - public void setGlobalInterceptor(GlobalInterceptor globalInterceptor) { - registry.register("globalInterceptor", globalInterceptor); - } - - public String getId() { - return id; - } - - /** - * waits until the router has shut down - */ - public void waitFor() throws InterruptedException { - synchronized (lock) { - while (running) - lock.wait(); - } - } - - public TimerManager getTimerManager() { - return timerManager; - } - - public KubernetesClientFactory getKubernetesClientFactory() { - return kubernetesClientFactory; - } - - public HttpClientFactory getHttpClientFactory() { - return httpClientFactory; - } - - public FlowController getFlowController() { - return flowController; - } - - public void handleAsynchronousInitializationResult(boolean success) { - if (!success && !config.isRetryInit()) - System.exit(1); - ApiInfo.logInfosAboutStartedProxies(ruleManager); - } - - @Override - public void handleBeanEvent(BeanDefinitionChanged bdc, Object bean, Object oldBean) throws IOException { - if (bean instanceof GlobalInterceptor) { - return; - } - - if (!(bean instanceof Proxy newProxy)) { - throw new IllegalArgumentException("Bean must be a Proxy instance, but got: " + bean.getClass().getName()); - } - - if (newProxy.getName() == null) - newProxy.setName(bdc.bd().getName()); - - // TODO: Comment or code Should be deleted before merge - // Comment is kept for discussion only. - // - // init() in Proxies was called twice, here and in Router.initRemainingRules - // We should only keep one place. Which one is up to discussion - // - // try { - // newProxy.init(this); - // } catch (ConfigurationException e) { - // SpringConfigurationErrorHandler.handleRootCause(e, log); - // throw e; - // } catch (Exception e) { - // throw new RuntimeException("Could not init rule.", e); - // } - - if (bdc.action().isAdded()) - add(newProxy); - else if (bdc.action().isDeleted()) - getRuleManager().removeRule((Proxy) oldBean); - else if (bdc.action().isModified()) - getRuleManager().replaceRule((Proxy) oldBean, newProxy); - } - - @Override - public boolean isActivatable(BeanDefinition bd) { - return Proxy.class.isAssignableFrom(new GrammarAutoGenerated().getElement(bd.getKind())); - } - - public AbstractRefreshableApplicationContext getRef() { - if (beanFactory instanceof AbstractRefreshableApplicationContext bf) - return bf; - throw new RuntimeException("ApplicationContext is not a AbstractRefreshableApplicationContext. Please set ."); - } - - @Override - public void setRegistry(BeanRegistry registry) { - this.registry = registry; - } - - public BeanRegistry getRegistry() { - return registry; - } - - public void applyConfiguration(Configuration configuration) { - hotDeployer = configuration.isHotDeploy() ? new DefaultHotDeployer() : new NullHotDeployer(); - this.config = configuration; - } - - public URIFactory getUriFactory() { - return config.getUriFactory(); - } - - /** - * Sets the configuration object for this router. - * Only used for xml - * - * @param config the configuration object - */ - @MCChildElement(order = -1) - public void setConfig(Configuration config) { - this.config = config; - } - - public Configuration getConfig() { - return config; - } - - /** - * Configures whether the router should open tcp ports when adding proxies. Use this field to create a router - * and open the ports later - * @param openPorts a boolean indicating whether ports should be opened (true) or closed (false) - */ - public void setOpenPorts(boolean openPorts) { - this.openPorts = openPorts; - } -} \ No newline at end of file +} diff --git a/core/src/main/java/com/predic8/membrane/core/RouterXmlBootstrap.java b/core/src/main/java/com/predic8/membrane/core/RouterXmlBootstrap.java new file mode 100644 index 0000000000..d3ebf731bf --- /dev/null +++ b/core/src/main/java/com/predic8/membrane/core/RouterXmlBootstrap.java @@ -0,0 +1,65 @@ +/* Copyright 2025 predic8 GmbH, www.predic8.com + + 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 com.predic8.membrane.core; + +import com.predic8.membrane.core.config.spring.*; +import org.slf4j.*; +import org.springframework.context.support.*; +import org.springframework.core.io.*; + +import java.nio.charset.*; +import java.util.*; + +/** + * Bootstrapping a {@link DefaultRouter} instance using Spring XML-based configuration. + */ +public class RouterXmlBootstrap { + + private static final Logger log = LoggerFactory.getLogger(RouterXmlBootstrap.class); + + /** + * Initializes a {@link DefaultRouter} instance from the specified Spring XML configuration resource. + * + * @param resource the path to the Spring XML configuration file that defines the {@link DefaultRouter} bean + * @return the initialized {@link DefaultRouter} instance + * @throws RuntimeException if no {@link DefaultRouter} bean is found or more than one {@link DefaultRouter} bean is found + */ + public static DefaultRouter initByXML(String resource) { + log.debug("loading spring config: {}", resource); + + TrackingFileSystemXmlApplicationContext bf = + new TrackingFileSystemXmlApplicationContext(new String[]{resource}, false); + bf.refresh(); + + if (bf.getBeansOfType(DefaultRouter.class).size() > 1) { + throw new RuntimeException( + "More than one router bean found in the Spring configuration (%s). This is no longer supported." + .formatted(Arrays.toString(bf.getBeanDefinitionNames())) + ); + } + DefaultRouter router = bf.getBean("router", DefaultRouter.class); + bf.start(); // Starting ApplicationContext will also call router.start(). Init should happen before. + return router; + } + + public static DefaultRouter initFromXMLString(String xmlString) { + log.debug("Loading spring config from string"); + GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(); + ctx.load(new ByteArrayResource(xmlString.getBytes(StandardCharsets.UTF_8))); + ctx.refresh(); + ctx.start(); + return ctx.getBean(DefaultRouter.class); + } +} diff --git a/core/src/main/java/com/predic8/membrane/core/RuleManager.java b/core/src/main/java/com/predic8/membrane/core/RuleManager.java index 24cf5e74c5..4b975b8b1a 100644 --- a/core/src/main/java/com/predic8/membrane/core/RuleManager.java +++ b/core/src/main/java/com/predic8/membrane/core/RuleManager.java @@ -36,7 +36,7 @@ public class RuleManager { private static final Logger log = LoggerFactory.getLogger(RuleManager.class.getName()); - private Router router; + private DefaultRouter router; protected final List proxies = new Vector<>(); private final List ruleSources = new ArrayList<>(); @@ -62,6 +62,11 @@ public boolean isAnyRuleWithPort(int port) { return false; } + /** + * Do not call directly. Router should call this method. Call Router.add() + Router.start() instead. + * @param proxy + * @throws IOException + */ public void addProxyAndOpenPortIfNew(SSLableProxy proxy) throws IOException { addProxyAndOpenPortIfNew(proxy, RuleDefinitionSource.MANUAL); } @@ -281,6 +286,7 @@ public synchronized void replaceRule(Proxy proxy, Proxy newProxy) { getExchangeStore().removeAllExchanges(proxy); int i = proxies.indexOf(proxy); + newProxy.init(router); proxies.set(i, newProxy); for (IRuleChangeListener listener : listeners) { @@ -296,7 +302,7 @@ public synchronized void removeAllRules() { removeRule(proxies.getFirst()); } - public void setRouter(Router router) { + public void setRouter(DefaultRouter router) { this.router = router; } @@ -340,5 +346,4 @@ public void add(int index, Proxy e) { } }; } - -} +} \ No newline at end of file diff --git a/core/src/main/java/com/predic8/membrane/core/RuleReinitializer.java b/core/src/main/java/com/predic8/membrane/core/RuleReinitializer.java new file mode 100644 index 0000000000..4d69875149 --- /dev/null +++ b/core/src/main/java/com/predic8/membrane/core/RuleReinitializer.java @@ -0,0 +1,96 @@ +/* Copyright 2025 predic8 GmbH, www.predic8.com + + 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 com.predic8.membrane.core; + +import com.predic8.membrane.core.proxies.*; +import org.slf4j.*; + +import java.util.*; + +public class RuleReinitializer { + + private static final Logger log = LoggerFactory.getLogger(RuleReinitializer.class); + + private final DefaultRouter router; + + private Timer timer; + + public RuleReinitializer(DefaultRouter router) { + this.router = router; + } + + synchronized void start() { + log.info("Starting rule reinitializer."); + if (timer != null) + return; // Already started. + + if (getInactiveRules().isEmpty()) + return; + + timer = new Timer("reinitializer", true); + timer.schedule(new TimerTask() { + @Override + public void run() { + retry(); + } + }, router.getConfiguration().getRetryInitInterval(), router.getConfiguration().getRetryInitInterval()); + } + + public synchronized void stop() { + if (timer != null) { + timer.cancel(); + } + timer = null; + } + + /** + * Should only be called from timer in this class + */ + public void retry() { + boolean stillFailing = false; + List inactive = getInactiveRules(); + if (!inactive.isEmpty()) { + log.info("Trying to activate all inactive rules."); + for (Proxy proxy : inactive) { + try { + log.info("Trying to start API {}.", proxy.getName()); + Proxy newProxy = proxy.clone(); + if (!newProxy.isActive()) { + log.warn("New rule for API {} is still not active.", proxy.getName()); + stillFailing = true; + } + router.getRuleManager().replaceRule(proxy, newProxy); + } catch (CloneNotSupportedException e) { + log.error("", e); + } + } + } + if (stillFailing) + log.info("There are still inactive rules."); + else { + stop(); + log.info("All rules have been initialized."); + } + } + + + List getInactiveRules() { + ArrayList inactive = new ArrayList<>(); + for (Proxy proxy : router.getRuleManager().getRules()) + if (!proxy.isActive()) + inactive.add(proxy); + return inactive; + } +} diff --git a/core/src/main/java/com/predic8/membrane/core/cli/RouterCLI.java b/core/src/main/java/com/predic8/membrane/core/cli/RouterCLI.java index f31f0540b7..6eff721d93 100644 --- a/core/src/main/java/com/predic8/membrane/core/cli/RouterCLI.java +++ b/core/src/main/java/com/predic8/membrane/core/cli/RouterCLI.java @@ -14,47 +14,32 @@ package com.predic8.membrane.core.cli; -import com.predic8.membrane.annot.beanregistry.BeanDefinition; -import com.predic8.membrane.annot.beanregistry.BeanRegistryImplementation; -import com.predic8.membrane.core.Configuration; -import com.predic8.membrane.core.ExitException; -import com.predic8.membrane.core.HttpRouter; -import com.predic8.membrane.core.Router; -import com.predic8.membrane.core.config.spring.GrammarAutoGenerated; -import com.predic8.membrane.core.config.spring.TrackingFileSystemXmlApplicationContext; -import com.predic8.membrane.core.exceptions.SpringConfigurationErrorHandler; -import com.predic8.membrane.core.openapi.serviceproxy.APIProxy; -import com.predic8.membrane.core.openapi.serviceproxy.OpenAPISpec; -import com.predic8.membrane.core.resolver.ResolverMap; -import com.predic8.membrane.core.resolver.ResourceRetrievalException; -import com.predic8.schema.*; -import org.apache.commons.cli.ParseException; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.Optional; +import com.predic8.membrane.annot.beanregistry.*; +import com.predic8.membrane.core.*; +import com.predic8.membrane.core.config.spring.*; +import com.predic8.membrane.core.exceptions.*; +import com.predic8.membrane.core.openapi.serviceproxy.*; +import com.predic8.membrane.core.resolver.*; +import org.apache.commons.cli.*; +import org.jetbrains.annotations.*; +import org.slf4j.*; +import org.springframework.beans.factory.xml.*; + +import java.io.*; +import java.util.*; import static com.predic8.membrane.core.Constants.*; -import static com.predic8.membrane.core.cli.util.JwkGenerator.generateJWK; -import static com.predic8.membrane.core.cli.util.JwkGenerator.privateJWKtoPublic; -import static com.predic8.membrane.core.config.spring.TrackingFileSystemXmlApplicationContext.InvalidConfigurationException; -import static com.predic8.membrane.core.config.spring.TrackingFileSystemXmlApplicationContext.handleXmlBeanDefinitionStoreException; -import static com.predic8.membrane.core.openapi.serviceproxy.OpenAPISpec.YesNoOpenAPIOption.YES; -import static com.predic8.membrane.core.openapi.util.OpenAPIUtil.isOpenAPIMisplacedError; -import static com.predic8.membrane.core.util.ExceptionUtil.concatMessageAndCauseMessages; -import static com.predic8.membrane.core.util.OSUtil.fixBackslashes; -import static com.predic8.membrane.core.util.URIUtil.pathFromFileURI; -import static com.predic8.membrane.core.util.text.TerminalColors.BRIGHT_CYAN; -import static com.predic8.membrane.core.util.text.TerminalColors.RESET; -import static java.lang.Integer.parseInt; -import static org.apache.commons.lang3.exception.ExceptionUtils.getMessage; -import static org.apache.commons.lang3.exception.ExceptionUtils.getRootCauseMessage; +import static com.predic8.membrane.core.cli.util.JwkGenerator.*; +import static com.predic8.membrane.core.config.spring.CheckableBeanFactory.*; +import static com.predic8.membrane.core.config.spring.TrackingFileSystemXmlApplicationContext.*; +import static com.predic8.membrane.core.openapi.serviceproxy.OpenAPISpec.YesNoOpenAPIOption.*; +import static com.predic8.membrane.core.openapi.util.OpenAPIUtil.*; +import static com.predic8.membrane.core.util.ExceptionUtil.*; +import static com.predic8.membrane.core.util.OSUtil.*; +import static com.predic8.membrane.core.util.URIUtil.*; +import static com.predic8.membrane.core.util.text.TerminalColors.*; +import static java.lang.Integer.*; +import static org.apache.commons.lang3.exception.ExceptionUtils.*; public class RouterCLI { @@ -90,12 +75,9 @@ private static void start(String[] args) { if (commandLine.getCommand().getName().equals("private-jwk-to-public")) { privateJwkToPublic(commandLine); } - - try { - getRouter(commandLine).waitFor(); - } catch (InterruptedException e) { - // do nothing - } + var router = getRouter(commandLine); + if (router instanceof DefaultRouter dr) + dr.waitFor(); } private static void privateJwkToPublic(MembraneCommandLine commandLine) { @@ -153,10 +135,10 @@ public static String getExceptionMessageWithCauses(Throwable throwable) { return null; } - private static Router initRouterByConfig(MembraneCommandLine commandLine) throws Exception { + private static DefaultRouter initRouterByConfig(MembraneCommandLine commandLine) throws Exception { String config = getRulesFile(commandLine); if (config.endsWith(".xml")) { - Router router = initRouterByXml(config); + var router = initRouterByXml(config); logStartupMessage(); return router; } @@ -167,19 +149,18 @@ private static Router initRouterByConfig(MembraneCommandLine commandLine) throws } private static Router initRouterByOpenApiSpec(MembraneCommandLine commandLine) throws Exception { - Router router = new HttpRouter(); + Router router = new DummyTestRouter(); router.getRuleManager().addProxyAndOpenPortIfNew(getApiProxy(commandLine)); router.init(); return router; } - private static Router initRouterByYAML(MembraneCommandLine commandLine, String option) throws Exception { + private static DefaultRouter initRouterByYAML(MembraneCommandLine commandLine, String option) throws Exception { return initRouterByYAML(commandLine.getCommand().getOptionValue(option)); } - private static Router initRouterByYAML(String location) throws Exception { - var router = new Router(); - router.setOpenPorts(false); + private static DefaultRouter initRouterByYAML(String location) throws Exception { + var router = new DefaultRouter(); router.setBaseLocation(location); GrammarAutoGenerated grammar = new GrammarAutoGenerated(); @@ -191,7 +172,6 @@ private static Router initRouterByYAML(String location) throws Exception { reg.finishStaticConfiguration(); router.start(); - router.getRuleManager().openPorts(); logStartupMessage(); return router; } @@ -233,9 +213,9 @@ private static String getLocation(MembraneCommandLine commandLine) throws IOExce return new File(getUserDir(), location).getCanonicalPath(); } - private static Router initRouterByXml(String config) throws Exception { + private static DefaultRouter initRouterByXml(String config) throws Exception { try { - return Router.init(config); + return RouterXmlBootstrap.initByXML(config); } catch (XmlBeanDefinitionStoreException e) { handleXmlBeanDefinitionStoreException(e); } diff --git a/core/src/main/java/com/predic8/membrane/core/exchangestore/AbstractPersistentExchangeStore.java b/core/src/main/java/com/predic8/membrane/core/exchangestore/AbstractPersistentExchangeStore.java index e55b3425c3..f2e55df17d 100644 --- a/core/src/main/java/com/predic8/membrane/core/exchangestore/AbstractPersistentExchangeStore.java +++ b/core/src/main/java/com/predic8/membrane/core/exchangestore/AbstractPersistentExchangeStore.java @@ -22,7 +22,6 @@ import com.predic8.membrane.core.http.*; import com.predic8.membrane.core.interceptor.*; import com.predic8.membrane.core.proxies.*; -import org.slf4j.*; import java.util.*; import java.util.concurrent.*; diff --git a/core/src/main/java/com/predic8/membrane/core/exchangestore/ElasticSearchExchangeStore.java b/core/src/main/java/com/predic8/membrane/core/exchangestore/ElasticSearchExchangeStore.java index 670ae7ca8f..ba5d1b6304 100644 --- a/core/src/main/java/com/predic8/membrane/core/exchangestore/ElasticSearchExchangeStore.java +++ b/core/src/main/java/com/predic8/membrane/core/exchangestore/ElasticSearchExchangeStore.java @@ -507,11 +507,9 @@ private void setUpIndex() { log.info("Index {} created",index); } } catch (JSONException e) { - if(indexRes.getJSONObject("error").getJSONArray("root_cause") - .getJSONObject(0).getString("type").equals("resource_already_exists_exception")){ + if(indexRes.has("error") && indexRes.getJSONObject("error").getJSONArray("root_cause").getJSONObject(0).getString("type").equals("resource_already_exists_exception")){ log.info("Index already exists skipping index creation"); - } - else{ + } else { log.error("Error happened. Reply from elastic search is below"); log.error(indexRes.toString()); } diff --git a/core/src/main/java/com/predic8/membrane/core/exchangestore/MongoDBExchangeStore.java b/core/src/main/java/com/predic8/membrane/core/exchangestore/MongoDBExchangeStore.java index 1ad4eac40a..97735ae2fa 100644 --- a/core/src/main/java/com/predic8/membrane/core/exchangestore/MongoDBExchangeStore.java +++ b/core/src/main/java/com/predic8/membrane/core/exchangestore/MongoDBExchangeStore.java @@ -22,7 +22,7 @@ import com.mongodb.client.model.ReplaceOptions; import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.AbstractExchange; import com.predic8.membrane.core.exchange.snapshots.AbstractExchangeSnapshot; import com.predic8.membrane.core.proxies.Proxy; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/AbstractInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/AbstractInterceptor.java index 0c898eab62..08139df867 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/AbstractInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/AbstractInterceptor.java @@ -18,7 +18,6 @@ import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.*; import com.predic8.membrane.core.http.*; -import com.predic8.membrane.core.interceptor.flow.*; import com.predic8.membrane.core.proxies.*; import java.util.*; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/AbstractInterceptorWithSession.java b/core/src/main/java/com/predic8/membrane/core/interceptor/AbstractInterceptorWithSession.java index aad4cb2ce8..7bb5f85816 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/AbstractInterceptorWithSession.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/AbstractInterceptorWithSession.java @@ -66,7 +66,7 @@ public Outcome handleRequest(Exchange exc) { outcome = handleRequestInternal(exc); } catch (Exception e) { log.error("", e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .flow(REQUEST) .detail("Error handling request!") .exception(e) @@ -85,7 +85,7 @@ public Outcome handleResponse(Exchange exc) { return outcome; } catch (Exception e) { log.error("", e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .flow(RESPONSE) .detail("Error handling response!") .exception(e) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/AcmeHttpChallengeInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/AcmeHttpChallengeInterceptor.java index 7e171d20a7..5bc4ba8155 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/AcmeHttpChallengeInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/AcmeHttpChallengeInterceptor.java @@ -13,21 +13,19 @@ limitations under the License. */ package com.predic8.membrane.core.interceptor; -import com.predic8.membrane.annot.MCElement; +import com.predic8.membrane.annot.*; import com.predic8.membrane.core.exceptions.*; -import com.predic8.membrane.core.exchange.Exchange; -import com.predic8.membrane.core.http.Response; +import com.predic8.membrane.core.exchange.*; +import com.predic8.membrane.core.http.*; import com.predic8.membrane.core.proxies.*; -import com.predic8.membrane.core.transport.ssl.AcmeSSLContext; -import com.predic8.membrane.core.transport.ssl.SSLContext; -import com.predic8.membrane.core.transport.ssl.acme.AcmeClient; +import com.predic8.membrane.core.transport.ssl.*; +import com.predic8.membrane.core.transport.ssl.acme.*; import org.jose4j.lang.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.slf4j.*; -import static com.predic8.membrane.core.http.MimeType.APPLICATION_OCTET_STREAM; -import static com.predic8.membrane.core.interceptor.Outcome.ABORT; -import static java.util.Arrays.stream; +import static com.predic8.membrane.core.http.MimeType.*; +import static com.predic8.membrane.core.interceptor.Outcome.*; +import static java.util.Arrays.*; /** * @description @@ -53,7 +51,7 @@ public Outcome handleRequest(Exchange exc) { ? exc.getRequest().getHeader().getHost().replaceAll(":.*", "") : exc.getRequest().getHeader().getHost(); - for (Proxy proxy : router.getRules()) { + for (Proxy proxy : router.getRuleManager().getRules()) { if (!(proxy instanceof SSLableProxy sp)) continue; SSLContext sslInboundContext = sp.getSslInboundContext(); @@ -72,7 +70,7 @@ public Outcome handleRequest(Exchange exc) { try { keyAuth = token + "." + acmeClient.getThumbprint(); } catch (JoseException e) { - ProblemDetails.user(router.isProduction(),getDisplayName()) + ProblemDetails.user(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not create thumbprint!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/ApisJsonInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/ApisJsonInterceptor.java index 8bdc3981de..87ec005cb0 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/ApisJsonInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/ApisJsonInterceptor.java @@ -59,7 +59,7 @@ public Outcome handleRequest(Exchange exc) { try { initJson(router, exc); } catch (JsonProcessingException e) { - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not create APIs JSON!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/DispatchingInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/DispatchingInterceptor.java index 1ced96ac4a..e0c559d110 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/DispatchingInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/DispatchingInterceptor.java @@ -66,7 +66,7 @@ public Outcome handleRequest(Exchange exc) { pd.buildAndSetResponse(exc); return ABORT; } catch (Exception e) { - internal(router.isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .detail("Could not get forwarding destination to dispatch request") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/EchoInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/EchoInterceptor.java index 3d109cfdf2..650b008f2c 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/EchoInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/EchoInterceptor.java @@ -43,7 +43,7 @@ public Outcome handleRequest(Exchange exc) { } } catch (Exception e) { log.error("Could not create echo.", e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not create echo!") .exception(e) .stacktrace(false) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/FlowController.java b/core/src/main/java/com/predic8/membrane/core/interceptor/FlowController.java index f0c6fc7b2c..36cefd6b8e 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/FlowController.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/FlowController.java @@ -94,7 +94,7 @@ public Outcome invokeRequestHandlers(Exchange exchange, List interc } catch (Exception e) { String msg = "Aborting! Exception caused in %s during %s %s flow.".formatted(interceptor.getDisplayName(), exchange.getRequest().getUri(), flow); log.warn(msg, e); - internal(router.isProduction(),interceptor.getDisplayName()) + internal(router.getConfiguration().isProduction(),interceptor.getDisplayName()) .detail(msg) .exception(e) .buildAndSetResponse(exchange); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/HTTPClientInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/HTTPClientInterceptor.java index 4496d1d1bd..07d0c98f9d 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/HTTPClientInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/HTTPClientInterceptor.java @@ -87,7 +87,7 @@ public Outcome handleRequest(Exchange exc) { } catch (ConnectException e) { String msg = "Target %s is not reachable.".formatted(getDestination(exc)); log.warn(msg + PROXIES_HINT); - gateway(router.isProduction(), getDisplayName()) + gateway(router.getConfiguration().isProduction(), getDisplayName()) .addSubSee("connect") .status(502) .detail(msg) @@ -95,7 +95,7 @@ public Outcome handleRequest(Exchange exc) { return ABORT; } catch (SocketTimeoutException e) { // Details are logged further down in the HTTPClient - internal(router.isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .addSubSee("socket-timeout") .detail("Target %s is not reachable.".formatted(exc.getDestinations())) .buildAndSetResponse(exc); @@ -103,7 +103,7 @@ public Outcome handleRequest(Exchange exc) { } catch (UnknownHostException e) { String msg = "Target host %s of API %s is unknown. DNS was unable to resolve host name.".formatted(URLUtil.getHost(getDestination(exc)), exc.getProxy().getName()); log.warn(msg + PROXIES_HINT); - gateway(router.isProduction(), getDisplayName()) + gateway(router.getConfiguration().isProduction(), getDisplayName()) .addSubSee("unknown-host") .status(502) .detail(msg) @@ -112,7 +112,7 @@ public Outcome handleRequest(Exchange exc) { } catch (MalformedURLException e) { log.info("Malformed URL. Requested path is: {} {}",exc.getRequest().getUri() , e.getMessage()); log.debug("",e); - user(router.isProduction(), getDisplayName()) + user(router.getConfiguration().isProduction(), getDisplayName()) .title("Request path or 'Host' header is malformed") .addSubSee("malformed-url") .exception(e) @@ -123,7 +123,7 @@ public Outcome handleRequest(Exchange exc) { return ABORT; } catch (ProtocolUpgradeDeniedException e) { log.debug("Denied protocol upgrade request. uri={} protocol={}", exc.getRequest().getUri(), e.getProtocol()); - gateway(router.isProduction(), getDisplayName()) + gateway(router.getConfiguration().isProduction(), getDisplayName()) .status(401) .title("Protocol upgrade has been denied.") .addSubSee("denied-protocol-upgrade") @@ -134,7 +134,7 @@ public Outcome handleRequest(Exchange exc) { return ABORT; } catch (Exception e) { log.error("", e); - internal(router.isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .exception(e) .internal("proxy", exc.getProxy().getName()) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/Interceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/Interceptor.java index 29486c68e6..0f0ded2c10 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/Interceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/Interceptor.java @@ -53,6 +53,10 @@ public boolean isAbort() { } } + void init(Router router); + + void init(Router router, Proxy proxy); + Outcome handleRequest(Exchange exchange); Outcome handleResponse(Exchange exchange); @@ -93,7 +97,5 @@ public boolean isAbort() { */ String getHelpId(); - void init(Router router); - void init(Router router, Proxy proxy); } diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/InternalRoutingInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/InternalRoutingInterceptor.java index ced4fe0d40..b926e5d40e 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/InternalRoutingInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/InternalRoutingInterceptor.java @@ -57,7 +57,7 @@ public Outcome handleRequest(Exchange exchange) { } catch (Exception e) { String detail = "Could not invoke request handler for internal route."; log.error(detail, e); // Most should be handled inside the interceptors - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .flow(Flow.REQUEST) .detail(detail) .exception(e) @@ -81,7 +81,7 @@ public Outcome handleResponse(Exchange exc) { } catch (Exception e) { String detail = "Could not invoke response handler for internal route."; log.error(detail, e); // Most should be handled inside the interceptors - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .flow(Flow.RESPONSE) .detail(detail) .exception(e) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/LimitInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/LimitInterceptor.java index b9c37acef3..8dbb75e35c 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/LimitInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/LimitInterceptor.java @@ -82,7 +82,7 @@ private Outcome handleMessage(Exchange exc, Message msg) { long len = msg.getHeader().getContentLength(); if (len != -1 && len > maxBodyLength) { log.info("Message length of {} exceeded limit {}.",len,maxBodyLength); - security(router.isProduction(), getDisplayName()) + security(router.getConfiguration().isProduction(), getDisplayName()) .title("Message is too large.") .detail("Message bodies must be smaller than limit.") .internal("maxBodyLength", maxBodyLength) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/MethodOverrideInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/MethodOverrideInterceptor.java index 9a96509d78..258ad2cc80 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/MethodOverrideInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/MethodOverrideInterceptor.java @@ -42,7 +42,7 @@ public Outcome handleRequest(Exchange exc) { break; } } catch (IOException e) { - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could overwrite method.") .internal("method", methodHeader) .exception(e) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/RegExReplaceInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/RegExReplaceInterceptor.java index dfea02b061..203f9b8a31 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/RegExReplaceInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/RegExReplaceInterceptor.java @@ -69,7 +69,7 @@ private Outcome handleInternal(Exchange exc, Message message) { try { replaceBody(message); } catch (Exception e) { - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not replace body!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/RelocatingInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/RelocatingInterceptor.java index ae16b5c325..b33d826a3c 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/RelocatingInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/RelocatingInterceptor.java @@ -62,7 +62,7 @@ public Outcome handleResponse(Exchange exc) { rewrite(exc); } catch (Exception e) { log.error("",e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Error rewriting URI") .topLevel("URI", exc.getRequestURI()) .exception(e) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/RuleMatchingInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/RuleMatchingInterceptor.java index ac6da7eb92..20d6dce417 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/RuleMatchingInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/RuleMatchingInterceptor.java @@ -50,7 +50,7 @@ public Outcome handleRequest(Exchange exc) { if (proxy instanceof NullProxy) { // Do not log. 404 is too common - user(getRouter().isProduction(), "routing") + user(router.getConfiguration().isProduction(), "routing") .status(404) .title("Invalid path or method") .detail("The requested path or HTTP method is not supported.") diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/acl/AbstractClientAddress.java b/core/src/main/java/com/predic8/membrane/core/interceptor/acl/AbstractClientAddress.java index d1accfec21..444cb58de2 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/acl/AbstractClientAddress.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/acl/AbstractClientAddress.java @@ -13,7 +13,7 @@ limitations under the License. */ package com.predic8.membrane.core.interceptor.acl; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.AbstractXmlElement; import javax.xml.stream.XMLStreamReader; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/acl/AccessControl.java b/core/src/main/java/com/predic8/membrane/core/interceptor/acl/AccessControl.java index 9949c4e11f..6c9bedce2a 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/acl/AccessControl.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/acl/AccessControl.java @@ -18,7 +18,7 @@ import javax.xml.stream.XMLStreamReader; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.AbstractXmlElement; public class AccessControl extends AbstractXmlElement { diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Any.java b/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Any.java index f13f8ed062..1441e50cfc 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Any.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Any.java @@ -14,7 +14,7 @@ package com.predic8.membrane.core.interceptor.acl; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; public class Any extends AbstractClientAddress { diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Hostname.java b/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Hostname.java index bb71c83037..62d20ed25a 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Hostname.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Hostname.java @@ -13,7 +13,7 @@ limitations under the License. */ package com.predic8.membrane.core.interceptor.acl; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -104,6 +104,6 @@ public boolean matches(String hostname, String ip) { @Override public void init(Router router) { super.init(router); - reverseDNS = router.getTransport().isReverseDNS(); + reverseDNS = router.getTransport() != null && router.getTransport().isReverseDNS(); } } diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Ip.java b/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Ip.java index 29b2347526..b0e2427bab 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Ip.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Ip.java @@ -13,7 +13,7 @@ limitations under the License. */ package com.predic8.membrane.core.interceptor.acl; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import javax.xml.stream.XMLStreamReader; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Resource.java b/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Resource.java index 61e4227fb2..245ab3462f 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Resource.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/acl/Resource.java @@ -22,10 +22,10 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; +import com.predic8.membrane.core.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.predic8.membrane.core.Router; import com.predic8.membrane.core.config.AbstractXmlElement; import com.predic8.membrane.core.config.GenericComplexElement; import com.predic8.membrane.core.util.text.TextUtil; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/administration/DynamicAdminPageInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/administration/DynamicAdminPageInterceptor.java index 86a8461374..d86dbcfab8 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/administration/DynamicAdminPageInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/administration/DynamicAdminPageInterceptor.java @@ -60,7 +60,7 @@ public Outcome handleRequest(Exchange exc) { o = dispatchRequest(exc); } catch (Exception e) { log.error("", e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Error in dynamic administration request!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/antivirus/ClamAntiVirusInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/antivirus/ClamAntiVirusInterceptor.java index 2435a43ccd..2c60c064e4 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/antivirus/ClamAntiVirusInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/antivirus/ClamAntiVirusInterceptor.java @@ -72,7 +72,7 @@ private String getBody(Exchange exc) { private Outcome gatewayTimeout(Exchange exc) { log.error("Could not reach clamav daemon on {}:{}",host,port ); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .title("Virus scanner error!") .detail("Could not execute virus scan.") .internal("message","Could not reach clamav daemon.") diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/extractors/ApiKeyExpressionExtractor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/extractors/ApiKeyExpressionExtractor.java index 13063d7188..eeeecefd17 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/extractors/ApiKeyExpressionExtractor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/extractors/ApiKeyExpressionExtractor.java @@ -14,7 +14,7 @@ package com.predic8.membrane.core.interceptor.apikey.extractors; import com.predic8.membrane.annot.*; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.xml.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.interceptor.*; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/extractors/ApiKeyExtractor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/extractors/ApiKeyExtractor.java index 5f9a203fb6..eecb159bab 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/extractors/ApiKeyExtractor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/extractors/ApiKeyExtractor.java @@ -13,7 +13,7 @@ limitations under the License. */ package com.predic8.membrane.core.interceptor.apikey.extractors; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import java.util.Optional; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/stores/ApiKeyStore.java b/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/stores/ApiKeyStore.java index d414de5cfe..a00298f497 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/stores/ApiKeyStore.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/stores/ApiKeyStore.java @@ -20,7 +20,7 @@ public interface ApiKeyStore { /** - * Lifecycle hook invoked once to provide the {@link Router} context. + * Lifecycle hook invoked once to provide the {@link DefaultRouter} context. * Default is a no-op to preserve backward compatibility; implementations may override. * * @param router non-null router instance diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/stores/JDBCApiKeyStore.java b/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/stores/JDBCApiKeyStore.java index 08158a00cc..af498a153d 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/stores/JDBCApiKeyStore.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/apikey/stores/JDBCApiKeyStore.java @@ -17,7 +17,7 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCChildElement; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.DefaultRouter; import com.predic8.membrane.core.util.ConfigurationException; import com.predic8.membrane.core.util.jdbc.AbstractJdbcSupport; import org.jetbrains.annotations.NotNull; @@ -67,7 +67,7 @@ apikey VARCHAR(255) NOT NULL PRIMARY KEY """; @Override - public void init(Router router) { + public void init(DefaultRouter router) { super.init(router); createTablesIfNotExist(); } diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/BasicAuthenticationInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/BasicAuthenticationInterceptor.java index 9ad9b99c1e..ea39c1c0ce 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/BasicAuthenticationInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/BasicAuthenticationInterceptor.java @@ -79,7 +79,7 @@ private String getPassword(Exchange exc) { } private Outcome deny(Exchange exc) { - security(router.isProduction(),getDisplayName()) + security(router.getConfiguration().isProduction(),getDisplayName()) .status(401) .title("Unauthorized") .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/CachingUserDataProvider.java b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/CachingUserDataProvider.java index c0e81664e2..e991cef61c 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/CachingUserDataProvider.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/CachingUserDataProvider.java @@ -19,7 +19,7 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCChildElement; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.predic8.membrane.annot.Required; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/CustomStatementJdbcUserDataProvider.java b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/CustomStatementJdbcUserDataProvider.java index 768e142d96..1803216b9f 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/CustomStatementJdbcUserDataProvider.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/CustomStatementJdbcUserDataProvider.java @@ -15,7 +15,7 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.predic8.membrane.annot.Required; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/EmptyTokenProvider.java b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/EmptyTokenProvider.java index 540bd943e6..a7407eddfd 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/EmptyTokenProvider.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/EmptyTokenProvider.java @@ -17,7 +17,7 @@ import java.util.NoSuchElementException; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; @MCElement(name="emptyTokenProvider", component =false) public class EmptyTokenProvider implements TokenProvider { diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/FileUserDataProvider.java b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/FileUserDataProvider.java index 031bc78729..8dff83d166 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/FileUserDataProvider.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/FileUserDataProvider.java @@ -15,7 +15,8 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; + import java.io.*; import java.nio.file.*; import java.util.*; @@ -56,7 +57,7 @@ public Map verify(Map postData) { userAttributes = getUsersByName().get(username); if (userAttributes == null) throw new NoSuchElementException(); - String pw = null; + String pw; String postDataPassword = postData.get("password"); String userHash = userAttributes.getPassword(); String[] userHashSplit = userHash.split("\\$"); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/JdbcUserDataProvider.java b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/JdbcUserDataProvider.java index 04bcc81cbe..b493b685d6 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/JdbcUserDataProvider.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/JdbcUserDataProvider.java @@ -15,7 +15,7 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.interceptor.registration.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/JwtSessionManager.java b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/JwtSessionManager.java index d56c2e5548..db67506ec0 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/JwtSessionManager.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/JwtSessionManager.java @@ -15,7 +15,7 @@ import com.predic8.membrane.annot.MCElement; import com.predic8.membrane.annot.MCTextContent; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import org.jetbrains.annotations.*; import org.jose4j.json.JsonUtil; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/LDAPUserDataProvider.java b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/LDAPUserDataProvider.java index 2b78fd9319..1bac01a14d 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/LDAPUserDataProvider.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/LDAPUserDataProvider.java @@ -36,6 +36,7 @@ import javax.naming.directory.SearchResult; import javax.net.SocketFactory; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.security.SSLParser; import com.predic8.membrane.core.transport.ssl.SSLContext; import com.predic8.membrane.core.transport.ssl.StaticSSLContext; @@ -46,7 +47,6 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCChildElement; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; /** * @description A user data provider querying an LDAP server to authorize users and retrieve attributes. diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/LoginInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/LoginInterceptor.java index 3e4f3d689e..cf0a6ac29a 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/LoginInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/LoginInterceptor.java @@ -150,7 +150,7 @@ public Outcome handleRequest(Exchange exc) { loginDialog.handleLoginRequest(exc); } catch (Exception e) { log.error("",e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not handle login request.!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/StaticUserDataProvider.java b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/StaticUserDataProvider.java index 3331e8e2be..4643545467 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/StaticUserDataProvider.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/StaticUserDataProvider.java @@ -13,16 +13,12 @@ limitations under the License. */ package com.predic8.membrane.core.interceptor.authentication.session; -import com.predic8.membrane.annot.MCAttribute; -import com.predic8.membrane.annot.MCChildElement; -import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.annot.MCOtherAttributes; -import com.predic8.membrane.core.Router; -import org.apache.commons.codec.digest.Crypt; - -import java.security.SecureRandom; +import com.predic8.membrane.annot.*; +import com.predic8.membrane.core.*; +import org.apache.commons.codec.digest.*; + import java.util.*; -import java.util.regex.Pattern; +import java.util.regex.*; /** * @description A user data provider listing all user data in-place in the config file. @@ -44,8 +40,6 @@ public class StaticUserDataProvider implements UserDataProvider { private List users = new ArrayList<>(); private Map usersByName = new HashMap<>(); - private SecureRandom random = new SecureRandom(); - private int saltByteSize = 128; @Override public Map verify(Map postData) { diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/TOTPTokenProvider.java b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/TOTPTokenProvider.java index f18b1c2833..848e4d327f 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/TOTPTokenProvider.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/TOTPTokenProvider.java @@ -17,7 +17,7 @@ import java.util.NoSuchElementException; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.interceptor.authentication.session.totp.OtpProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/TokenProvider.java b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/TokenProvider.java index 2172fe2476..ba5d0cc317 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/TokenProvider.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/TokenProvider.java @@ -15,12 +15,12 @@ import java.util.Map; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; public interface TokenProvider { - public void init(Router router); - public void requestToken(Map userAttributes); - public void verifyToken(Map userAttributes, String token); + void init(Router router); + void requestToken(Map userAttributes); + void verifyToken(Map userAttributes, String token); } diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/UnifyingUserDataProvider.java b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/UnifyingUserDataProvider.java index 329726654a..64b8fe62a3 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/UnifyingUserDataProvider.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/UnifyingUserDataProvider.java @@ -23,7 +23,7 @@ import com.predic8.membrane.annot.MCChildElement; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; /** * @explanation

diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/WhateverMobileSMSTokenProvider.java b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/WhateverMobileSMSTokenProvider.java index d69bda4ca7..8964a9abce 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/WhateverMobileSMSTokenProvider.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/authentication/session/WhateverMobileSMSTokenProvider.java @@ -15,7 +15,7 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Request; import com.predic8.membrane.core.transport.http.HttpClient; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/BalancerHealthMonitor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/BalancerHealthMonitor.java index cef060b03d..eff6c3226d 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/BalancerHealthMonitor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/BalancerHealthMonitor.java @@ -56,7 +56,7 @@ public class BalancerHealthMonitor implements ApplicationContextAware, Initializ */ public static final int INITIAL_DELAY = 5000; - private Router router; + private DefaultRouter router; private int interval = 10000; private HttpClient client; @@ -158,7 +158,7 @@ private Exchange doCall(String url) throws Exception { @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.router = applicationContext.getBean(Router.class); + this.router = applicationContext.getBean(DefaultRouter.class); } @Override @@ -204,7 +204,7 @@ public HttpClientConfiguration getHttpClientConfig() { } /** - * @see Router#getHttpClientFactory() + * @see DefaultRouter#getHttpClientFactory() * @see HttpClientConfiguration * * @description Optional HTTP client configuration for health probes (e.g., timeouts, TLS). diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/ByThreadStrategy.java b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/ByThreadStrategy.java index 33deae8e2e..e024aa96c5 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/ByThreadStrategy.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/ByThreadStrategy.java @@ -19,7 +19,7 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.AbstractXmlElement; import com.predic8.membrane.core.exchange.AbstractExchange; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/ClusterNotificationInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/ClusterNotificationInterceptor.java index f9dff798bf..0c0a1f835d 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/ClusterNotificationInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/ClusterNotificationInterceptor.java @@ -74,7 +74,7 @@ public Outcome handleRequest(Exchange exc) { getParams(exc); } catch (Exception e) { log.error("",e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not decrypt parameters!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/DispatchingStrategy.java b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/DispatchingStrategy.java index 2e834da607..7f3091b16c 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/DispatchingStrategy.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/DispatchingStrategy.java @@ -13,7 +13,7 @@ limitations under the License. */ package com.predic8.membrane.core.interceptor.balancer; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.AbstractExchange; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/LoadBalancingInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/LoadBalancingInterceptor.java index 9ef5749275..6f4684fad5 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/LoadBalancingInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/LoadBalancingInterceptor.java @@ -76,7 +76,7 @@ public Outcome handleRequest(Exchange exc) { //2) All destinations got disabled externally (through Membrane maintenance API). See class EmptyNodeListException. String msg = "No backend node found that is ready to handle this request. Check health of backends and balancer configuration."; log.error(msg); - internal(router.isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .status(503) .title("Service unavailable") .addSubSee("node-dispatching") @@ -84,7 +84,7 @@ public Outcome handleRequest(Exchange exc) { .buildAndSetResponse(exc); return ABORT; } catch (Exception e) { - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .status(503) .title("Service unavailable") .addSubSee("node-dispatching") @@ -117,7 +117,7 @@ public Outcome handleResponse(Exchange exc) { try { sessionId = sessionIdExtractor.getSessionId(exc, RESPONSE); } catch (Exception e) { - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .addSubSee("sessionid-extraction") .detail("Could not get session id!") .exception(e) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/RoundRobinStrategy.java b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/RoundRobinStrategy.java index 57725f9e73..1c5cf46a38 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/RoundRobinStrategy.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/RoundRobinStrategy.java @@ -16,7 +16,7 @@ import javax.xml.stream.*; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.AbstractXmlElement; import com.predic8.membrane.core.exchange.AbstractExchange; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/SessionIdExtractor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/SessionIdExtractor.java index 736cd80e0c..de71248d41 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/SessionIdExtractor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/SessionIdExtractor.java @@ -14,7 +14,7 @@ package com.predic8.membrane.core.interceptor.balancer; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.interceptor.Interceptor.Flow; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/faultmonitoring/FaultMonitoringStrategy.java b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/faultmonitoring/FaultMonitoringStrategy.java index 84dbd5a9f6..a4bd00fd9f 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/faultmonitoring/FaultMonitoringStrategy.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/balancer/faultmonitoring/FaultMonitoringStrategy.java @@ -16,7 +16,7 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.AbstractXmlElement; import com.predic8.membrane.core.exchange.AbstractExchange; import com.predic8.membrane.core.interceptor.balancer.*; @@ -122,6 +122,7 @@ public class FaultMonitoringStrategy extends AbstractXmlElement implements Dispa private final Random random = new Random(); private HttpClientStatusEventBus httpClientStatusEventBus; + @Override public void init(Router router) { httpClientStatusEventBus = new HttpClientStatusEventBus(); httpClientStatusEventBus.registerListener(new MyHttpClientStatusEventListener()); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/cache/CacheInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/cache/CacheInterceptor.java index c90f9dcf25..dfb85269af 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/cache/CacheInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/cache/CacheInterceptor.java @@ -17,7 +17,7 @@ import com.predic8.membrane.annot.MCChildElement; import com.predic8.membrane.annot.MCElement; import com.predic8.membrane.annot.Required; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Header; import com.predic8.membrane.core.http.HeaderField; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/flow/AbstractFlowInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/flow/AbstractFlowInterceptor.java index edee39ebb0..7efa576deb 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/flow/AbstractFlowInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/flow/AbstractFlowInterceptor.java @@ -14,7 +14,7 @@ package com.predic8.membrane.core.interceptor.flow; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.ProxyAware; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.interceptor.AbstractInterceptor; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/flow/CallInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/flow/CallInterceptor.java index 36a6aac2b7..baa13a5a58 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/flow/CallInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/flow/CallInterceptor.java @@ -96,7 +96,7 @@ private Outcome handleInternal(Exchange exc) { return CONTINUE; } catch (Exception e) { log.error("Error processing response from {}: {}", dest, e.getMessage(), e); - internal(router.isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .addSubSee("internal-calling") .detail("Internal call") .exception(e) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/flow/ForInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/flow/ForInterceptor.java index cdafbeb686..6864e4d1ca 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/flow/ForInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/flow/ForInterceptor.java @@ -80,7 +80,7 @@ private Outcome handleInternal(Exchange exc, Flow flow) { try { o = exchangeExpression.evaluate(exc, flow, Object.class); } catch (ExchangeExpressionException e) { - ProblemDetails pd = ProblemDetails.internal(router.isProduction(), getDisplayName()); + ProblemDetails pd = ProblemDetails.internal(router.getConfiguration().isProduction(), getDisplayName()); e.provideDetails(pd) .detail("Error evaluating expression on exchange.") .component(getDisplayName()) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/flow/IfInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/flow/IfInterceptor.java index f00c84e7f6..c119945918 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/flow/IfInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/flow/IfInterceptor.java @@ -73,7 +73,7 @@ private Outcome handleInternal(Exchange exc, Flow flow) { try { result = exchangeExpression.evaluate(exc, flow, Boolean.class); } catch (ExchangeExpressionException e) { - e.provideDetails(internal(router.isProduction(), getDisplayName())) + e.provideDetails(internal(router.getConfiguration().isProduction(), getDisplayName())) .detail("Error evaluating expression on exchange.") .buildAndSetResponse(exc); return ABORT; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/flow/ReturnInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/flow/ReturnInterceptor.java index 830dc5e77f..b0ef343f3f 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/flow/ReturnInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/flow/ReturnInterceptor.java @@ -61,7 +61,7 @@ public Outcome handleRequest(Exchange exc) { } catch (IOException e) { String detail = "Could not create response!"; log.error(detail, e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail(detail) .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/flow/choice/ChooseInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/flow/choice/ChooseInterceptor.java index f8446742c6..f012d9a598 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/flow/choice/ChooseInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/flow/choice/ChooseInterceptor.java @@ -80,7 +80,7 @@ private Outcome handleInternal(Exchange exc, Flow flow) { } private void handleExpressionProblemDetails(ExchangeExpressionException e, Exchange exc) { - e.provideDetails(internal(router.isProduction(),getDisplayName())) + e.provideDetails(internal(router.getConfiguration().isProduction(),getDisplayName())) .addSubSee("expression-evaluation") .detail("Error evaluating expression on exchange in if plugin.") .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/flow/choice/InterceptorContainer.java b/core/src/main/java/com/predic8/membrane/core/interceptor/flow/choice/InterceptorContainer.java index d879bebbb3..c13ef720ee 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/flow/choice/InterceptorContainer.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/flow/choice/InterceptorContainer.java @@ -42,7 +42,7 @@ Outcome invokeFlow(Exchange exc, Flow flow, Router router) { } private void handleInvocationProblemDetails(Exchange exc, Exception e, Router router) { - internal(router.isProduction(),"interceptor-container") + internal(router.getConfiguration().isProduction(),"interceptor-container") .detail("Error invoking plugin.") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/formvalidation/FormValidationInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/formvalidation/FormValidationInterceptor.java index 3d5b013879..2cd1b8ac5f 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/formvalidation/FormValidationInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/formvalidation/FormValidationInterceptor.java @@ -115,7 +115,7 @@ public Outcome handleRequest(Exchange exc) { try { propMap = URLParamUtil.getParams(router.getUriFactory(), exc, ERROR); } catch (Exception e) { - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not parse query parameters!") .topLevel("uri", exc.getRequest().getUri()) .exception(e) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/javascript/GraalVMJavascriptLanguageAdapter.java b/core/src/main/java/com/predic8/membrane/core/interceptor/javascript/GraalVMJavascriptLanguageAdapter.java index ecf9e8100d..a728fe0a5e 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/javascript/GraalVMJavascriptLanguageAdapter.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/javascript/GraalVMJavascriptLanguageAdapter.java @@ -32,7 +32,7 @@ public GraalVMJavascriptLanguageAdapter(Router router) { @Override public ProblemDetails getProblemDetails(Exception e) { - ProblemDetails pd = internal(router.isProduction(),"javascript"); + ProblemDetails pd = internal(router.getConfiguration().isProduction(),"javascript"); if (e instanceof PolyglotException pe) { pd.internal("column", pe.getSourceLocation().getStartColumn()); pd.internal("line", pe.getSourceLocation().getStartLine() - preScriptLineLength ); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/javascript/LanguageAdapter.java b/core/src/main/java/com/predic8/membrane/core/interceptor/javascript/LanguageAdapter.java index ca0d80e745..13fcaacc49 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/javascript/LanguageAdapter.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/javascript/LanguageAdapter.java @@ -24,7 +24,6 @@ import org.slf4j.*; import org.springframework.context.*; -import java.io.*; import java.util.*; import java.util.function.*; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/javascript/RhinoJavascriptLanguageAdapter.java b/core/src/main/java/com/predic8/membrane/core/interceptor/javascript/RhinoJavascriptLanguageAdapter.java index b638b14bb6..7b6449cd34 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/javascript/RhinoJavascriptLanguageAdapter.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/javascript/RhinoJavascriptLanguageAdapter.java @@ -31,7 +31,7 @@ public RhinoJavascriptLanguageAdapter(Router router) { @Override public ProblemDetails getProblemDetails(Exception e) { - ProblemDetails pd = ProblemDetails.internal(router.isProduction(),"javascript"); + ProblemDetails pd = ProblemDetails.internal(router.getConfiguration().isProduction(),"javascript"); if (e.getCause() instanceof ScriptException se) { pd.internal("column", se.getColumnNumber() + 1); pd.internal("line", se.getLineNumber() - preScriptLineLength + 1); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/json/JsonProtectionInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/json/JsonProtectionInterceptor.java index b4e20cf6cc..1edf284263 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/json/JsonProtectionInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/json/JsonProtectionInterceptor.java @@ -75,7 +75,7 @@ private boolean shouldProvideDetails() { if (reportError != null) { return reportError; } - return !router.isProduction(); + return !router.getConfiguration().isProduction(); } private abstract static class Context { diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptor.java index 9b5cd2e4a5..a4fc9de313 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptor.java @@ -92,14 +92,14 @@ public Outcome handleRequest(Exchange exc) { var jwt = jwtRetriever.get(exc); return handleJwt(exc, jwt); } catch (JWTException e) { - ProblemDetails.security(router.isProduction(), "jwt-auth") + ProblemDetails.security(router.getConfiguration().isProduction(), "jwt-auth") .detail(e.getMessage()) .stacktrace(true) .status(400) .buildAndSetResponse(exc); return RETURN; } catch (JsonProcessingException e) { - ProblemDetails.security(router.isProduction(), "jwt-auth") + ProblemDetails.security(router.getConfiguration().isProduction(), "jwt-auth") .detail(ERROR_DECODED_HEADER_NOT_JSON) .addSubSee(ERROR_DECODED_HEADER_NOT_JSON_ID) .stacktrace(true) @@ -107,7 +107,7 @@ public Outcome handleRequest(Exchange exc) { .buildAndSetResponse(exc); return RETURN; } catch (InvalidJwtException e) { - ProblemDetails.security(router.isProduction(), "jwt-auth") + ProblemDetails.security(router.getConfiguration().isProduction(), "jwt-auth") .detail(ERROR_VALIDATION_FAILED) .addSubSee(ERROR_VALIDATION_FAILED_ID) .stacktrace(false) @@ -115,7 +115,7 @@ public Outcome handleRequest(Exchange exc) { .buildAndSetResponse(exc); return RETURN; } catch (Exception e) { - ProblemDetails.security(router.isProduction(), "jwt-auth") + ProblemDetails.security(router.getConfiguration().isProduction(), "jwt-auth") .detail(ERROR_JWT_NOT_FOUND) .addSubSee(ERROR_JWT_NOT_FOUND_ID) .stacktrace(true) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/jwt/JwtSignInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/jwt/JwtSignInterceptor.java index 19fc37caed..046c11d9df 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/jwt/JwtSignInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/jwt/JwtSignInterceptor.java @@ -89,7 +89,7 @@ private Outcome handleInternal(Exchange exc, Flow flow) { return CONTINUE; } catch (Exception e) { log.error("Error during attempt to sign JWT payload", e); - security(router.isProduction(),getDisplayName()) + security(router.getConfiguration().isProduction(),getDisplayName()) .addSubSee("crypto") .detail("Error during attempt to sign JWT payload.") .exception(e) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/kubernetes/KubernetesValidationInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/kubernetes/KubernetesValidationInterceptor.java index 9349b95bf5..c86b410cae 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/kubernetes/KubernetesValidationInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/kubernetes/KubernetesValidationInterceptor.java @@ -182,7 +182,7 @@ public Outcome handleRequest(Exchange exc) { return RETURN; } catch (Exception e) { log.error("", e); - internal(router.isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .component(getDisplayName()) .detail("Error handling request!") .exception(e) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/lang/AbstractSetterInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/lang/AbstractSetterInterceptor.java index 264fb54136..b5867ba1cd 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/lang/AbstractSetterInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/lang/AbstractSetterInterceptor.java @@ -73,7 +73,7 @@ private Outcome handleInternal(Exchange exchange, Flow flow) { } private ProblemDetails prepareProblemDetails(String msg) { - return internal(getRouter().isProduction(), getDisplayName()) + return internal(getRouter().getConfiguration().isProduction(), getDisplayName()) .title(msg) .internal("field", fieldName) .internal("expression", expression); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/lang/SetBodyInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/lang/SetBodyInterceptor.java index 34d5349c23..a6cdffab37 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/lang/SetBodyInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/lang/SetBodyInterceptor.java @@ -64,7 +64,7 @@ private Outcome handleInternal(Exchange exchange, Flow flow) { var message = "While evaluating expression %s: %s".formatted(expression, root.getMessage()); log.info(message); - internal(getRouter().isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .title("Error evaluating expression!") .internal("expression", expression) .exception(root) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/ntlm/NtlmInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/ntlm/NtlmInterceptor.java index 393dc618d7..6f69e9e050 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/ntlm/NtlmInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/ntlm/NtlmInterceptor.java @@ -92,7 +92,7 @@ public Outcome handleResponse(Exchange exc) { try { authenticationResult = authenticate(stableConnection, originalRequestUrl, user, pass, domain, workstation); } catch (Exception e) { - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not authenticate!") .internal("domain", domain) .internal("workstation", workstation) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/ClaimList.java b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/ClaimList.java index 685112ae31..76178d2869 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/ClaimList.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/ClaimList.java @@ -16,7 +16,7 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCChildElement; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.annot.Required; import java.util.*; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/ClientList.java b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/ClientList.java index f289a39b53..0920798bd6 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/ClientList.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/ClientList.java @@ -13,7 +13,7 @@ package com.predic8.membrane.core.interceptor.oauth2; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import java.util.NoSuchElementException; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/StaticClientList.java b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/StaticClientList.java index 56c41beaef..2a136f220b 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/StaticClientList.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/StaticClientList.java @@ -15,7 +15,7 @@ import com.predic8.membrane.annot.MCChildElement; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import java.util.ArrayList; import java.util.HashMap; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/authorizationservice/AuthorizationService.java b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/authorizationservice/AuthorizationService.java index 7aa855d502..54fa477187 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/authorizationservice/AuthorizationService.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/authorizationservice/AuthorizationService.java @@ -15,7 +15,7 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCChildElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.security.SSLParser; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Request; @@ -58,7 +58,6 @@ import static com.predic8.membrane.core.interceptor.oauth2.OAuth2TokenBody.authorizationCodeBodyBuilder; import static com.predic8.membrane.core.interceptor.oauth2.OAuth2TokenBody.refreshTokenBodyBuilder; import static com.predic8.membrane.core.interceptor.oauth2client.rf.JsonUtils.isJson; -import static com.predic8.membrane.core.interceptor.oauth2client.rf.OAuth2CallbackRequestHandler.MEMBRANE_MISSING_SESSION_DESCRIPTION; import static org.apache.commons.codec.binary.Base64.encodeBase64; public abstract class AuthorizationService { diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokengenerators/BearerJwtTokenGenerator.java b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokengenerators/BearerJwtTokenGenerator.java index 9aaab05118..dea9aa879d 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokengenerators/BearerJwtTokenGenerator.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokengenerators/BearerJwtTokenGenerator.java @@ -15,7 +15,7 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCChildElement; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.security.Blob; import com.predic8.membrane.core.interceptor.session.JwtSessionManager; import org.jose4j.json.JsonUtil; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokengenerators/BearerTokenGenerator.java b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokengenerators/BearerTokenGenerator.java index 5f74038020..37c0197d08 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokengenerators/BearerTokenGenerator.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokengenerators/BearerTokenGenerator.java @@ -14,7 +14,7 @@ package com.predic8.membrane.core.interceptor.oauth2.tokengenerators; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import java.math.BigInteger; import java.security.SecureRandom; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokengenerators/TokenGenerator.java b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokengenerators/TokenGenerator.java index e95cfdcfd2..88d8ee0482 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokengenerators/TokenGenerator.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokengenerators/TokenGenerator.java @@ -13,13 +13,13 @@ package com.predic8.membrane.core.interceptor.oauth2.tokengenerators; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import java.util.Map; import java.util.NoSuchElementException; public interface TokenGenerator { - public void init(Router router) throws Exception; + void init(Router router) throws Exception; /** * @return the token type used, probably "Bearer". diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokenvalidation/OAuth2TokenValidatorInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokenvalidation/OAuth2TokenValidatorInterceptor.java index dee5ea92a1..708433f7d2 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokenvalidation/OAuth2TokenValidatorInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2/tokenvalidation/OAuth2TokenValidatorInterceptor.java @@ -53,7 +53,7 @@ public Outcome handleRequest(Exchange exc) { if(callExchangeAndCheckFor200(buildAccessTokenValidationExchange(exc))) return CONTINUE; } catch (Exception e) { - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .exception(e) .buildAndSetResponse(exc); return ABORT; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2client/FlowInitiator.java b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2client/FlowInitiator.java index 100a2e2bcb..31e27f2015 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2client/FlowInitiator.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2client/FlowInitiator.java @@ -83,7 +83,7 @@ public Outcome handleRequest(Exchange exc) { return handleRequestInternal(exc); } catch (Exception e) { log.error("", e); - ProblemDetails.internal(router.isProduction(),getDisplayName()) + ProblemDetails.internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Error initiating OAuth2 flow!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2client/rf/SessionAuthorizer.java b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2client/rf/SessionAuthorizer.java index 6cc5e3e550..08214dfde9 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2client/rf/SessionAuthorizer.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2client/rf/SessionAuthorizer.java @@ -15,7 +15,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Response; import com.predic8.membrane.core.interceptor.Outcome; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2server/LoginDialog2.java b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2server/LoginDialog2.java index 4c0a6aa414..01d1413134 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2server/LoginDialog2.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/oauth2server/LoginDialog2.java @@ -77,7 +77,7 @@ public LoginDialog2( wsi.setDocBase(dialogLocation); } - public void init(Router router) throws Exception { + public void init(DefaultRouter router) throws Exception { uriFactory = router.getUriFactory(); wsi.init(router); router.getResolverMap().resolve(ResolverMap.combine(router.getBaseLocation(), wsi.getDocBase(), "index.html")).close(); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/ratelimit/RateLimitInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/ratelimit/RateLimitInterceptor.java index 429dfbc8b0..427d4778b1 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/ratelimit/RateLimitInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/ratelimit/RateLimitInterceptor.java @@ -104,7 +104,7 @@ public Outcome handleRequest(Exchange exc) { return CONTINUE; } catch (SpelEvaluationException e) { log.info("Cannot evaluate keyExpression {} cause is {}", expression, e.getCause()); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .addSubType("rate-limit") .detail("Cannot evaluate keyExpression '%s' cause is %s".formatted(expression, e.getMessage())) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/registration/RegistrationInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/registration/RegistrationInterceptor.java index 3193cad33c..5a20322d80 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/registration/RegistrationInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/registration/RegistrationInterceptor.java @@ -71,7 +71,7 @@ public Outcome handleRequest(Exchange exc) { connection.createStatement().executeUpdate(getInsertAccountIntoDatabaseSQL(user)); } catch (SQLException e) { log.error("",e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not access database") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/rest/HTTP2XMLInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/rest/HTTP2XMLInterceptor.java index 7ab0b96e9b..f653eb6136 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/rest/HTTP2XMLInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/rest/HTTP2XMLInterceptor.java @@ -40,7 +40,7 @@ public Outcome handleRequest(Exchange exc) { return handleRequestInternal(exc); } catch (Exception e) { log.error("",e); - user(router.isProduction(),getDisplayName()) + user(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not generate XML from HTTP information!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/rest/REST2SOAPInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/rest/REST2SOAPInterceptor.java index 9c4c8445b6..eb92d7ca92 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/rest/REST2SOAPInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/rest/REST2SOAPInterceptor.java @@ -66,7 +66,7 @@ public Outcome handleRequest(Exchange exc) { getRequestXMLSource(exc), exc.getStringProperties()); } catch (Exception e) { log.error("", e); - user(router.isProduction(), getDisplayName()) + user(router.getConfiguration().isProduction(), getDisplayName()) .detail("Could not covert REST to SOAP!") .exception(e) .buildAndSetResponse(exc); @@ -84,7 +84,7 @@ public Outcome handleResponse(Exchange exc) { return handleResponseInternal(exc); } catch (Exception e) { log.error("", e); - user(router.isProduction(), getDisplayName()) + user(router.getConfiguration().isProduction(), getDisplayName()) .detail("Could not covert SOAP to REST!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/rest/RESTInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/rest/RESTInterceptor.java index 514cd75344..3810d646d5 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/rest/RESTInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/rest/RESTInterceptor.java @@ -49,7 +49,7 @@ public Outcome handleRequest(Exchange exc) { try { o = dispatchRequest(exc); } catch (Exception e) { - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Error dispatching request!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/rest/SOAP2RESTInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/rest/SOAP2RESTInterceptor.java index 7058d32905..ad2c93898b 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/rest/SOAP2RESTInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/rest/SOAP2RESTInterceptor.java @@ -56,7 +56,7 @@ public Outcome handleRequest(Exchange exc) { transformAndReplaceBody(exc.getRequest(), requestXSLT, new StreamSource(exc.getRequest().getBodyAsStreamDecoded()), exc.getStringProperties()); } catch (Exception e) { log.error("", e); - user(router.isProduction(),getDisplayName()) + user(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not transform using XSLT!") .exception(e) .stacktrace(true) @@ -83,7 +83,7 @@ public Outcome handleResponse(Exchange exc) { transformAndReplaceBody(exc.getResponse(), responseXSLT, getExchangeXMLSource(exc), exc.getStringProperties()); } catch (Exception e) { log.error("", e); - user(router.isProduction(),getDisplayName()) + user(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not transform using XSLT!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/rewrite/ReverseProxyingInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/rewrite/ReverseProxyingInterceptor.java index 045151a23c..826546df79 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/rewrite/ReverseProxyingInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/rewrite/ReverseProxyingInterceptor.java @@ -72,7 +72,7 @@ public Outcome handleRequest(Exchange exc) { target = new URL(exc.getDestinations().getFirst()); } catch (MalformedURLException e) { log.error("Could not parse target URL: {}",destination); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not parse target URL") .internal("URL", exc.getDestinations().getFirst()) .exception(e) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/schemavalidation/ValidatorInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/schemavalidation/ValidatorInterceptor.java index 198210a690..ce740bb09f 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/schemavalidation/ValidatorInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/schemavalidation/ValidatorInterceptor.java @@ -153,7 +153,7 @@ private Outcome handleInternal(Exchange exc, Flow flow) { return CONTINUE; } catch (IOException e) { log.error("", e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .addSubSee("io") .detail("Could not read message body") .exception(e) @@ -165,7 +165,7 @@ private Outcome handleInternal(Exchange exc, Flow flow) { return validator.validateMessage(exc, flow); } catch (Exception e) { log.error("", e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Error validating message") .addSubSee("generic") .internal("validator", validator.getName()) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/server/WSDLPublisherInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/server/WSDLPublisherInterceptor.java index 2b2ee61b91..5c1c00075f 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/server/WSDLPublisherInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/server/WSDLPublisherInterceptor.java @@ -170,7 +170,7 @@ public Outcome handleRequest(final Exchange exc) { return handleRequestInternal(exc); } catch (Exception e) { log.error("", e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not return WSDL document!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/server/WebServerInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/server/WebServerInterceptor.java index 17a7f4dcba..c9ede2d6e1 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/server/WebServerInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/server/WebServerInterceptor.java @@ -99,7 +99,7 @@ public Outcome handleRequest(Exchange exc) { return handleRequestInternal(exc); } catch (IOException e) { log.error("", e); - internal(router.isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .flow(Flow.REQUEST) .detail("Error serving document") .exception(e) @@ -180,7 +180,7 @@ public Outcome handleRequest(Exchange exc) { try { return router.getUriFactory().create(exc.getDestinations().getFirst()); } catch (URISyntaxException e) { - internal(router.isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .addSubSee("uri-creation") .detail("Could not create uri") .exception(e) @@ -253,7 +253,7 @@ public Response createResponse(ResolverMap rr, String resPath) { .body(rr.resolve(resPath), true) .build(); } catch (Exception e) { - return internal(router.isProduction(), getDisplayName()) + return internal(router.getConfiguration().isProduction(), getDisplayName()) .title("Could not resolve file") .topLevel("path", resPath) .exception(e) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/session/MemcachedSessionManager.java b/core/src/main/java/com/predic8/membrane/core/interceptor/session/MemcachedSessionManager.java index 711f4754fd..50d4e9d92e 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/session/MemcachedSessionManager.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/session/MemcachedSessionManager.java @@ -17,7 +17,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.HeaderField; import com.predic8.membrane.core.util.MemcachedConnector; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/session/SessionManager.java b/core/src/main/java/com/predic8/membrane/core/interceptor/session/SessionManager.java index 699b8f52fd..8e7bf825d4 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/session/SessionManager.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/session/SessionManager.java @@ -16,7 +16,7 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.predic8.membrane.annot.MCAttribute; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Header; import com.predic8.membrane.core.http.HeaderField; diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/soap/SampleSoapServiceInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/soap/SampleSoapServiceInterceptor.java index 5825368d06..5967b9cbf6 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/soap/SampleSoapServiceInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/soap/SampleSoapServiceInterceptor.java @@ -58,7 +58,7 @@ public Outcome handleRequest(Exchange exc) { try { return handleRequestInternal(exc); } catch (Exception e) { - internal(router.isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .detail("Could not process SOAP request!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/statistics/StatisticsProvider.java b/core/src/main/java/com/predic8/membrane/core/interceptor/statistics/StatisticsProvider.java index bd08e67fcd..5029207e5f 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/statistics/StatisticsProvider.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/statistics/StatisticsProvider.java @@ -67,7 +67,7 @@ public Outcome handleRequest(Exchange exc) { try { con = dataSource.getConnection(); } catch (SQLException e) { - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not connect to database") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/stomp/STOMPClient.java b/core/src/main/java/com/predic8/membrane/core/interceptor/stomp/STOMPClient.java index 3452527e7f..b112e506c8 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/stomp/STOMPClient.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/stomp/STOMPClient.java @@ -109,7 +109,7 @@ public Outcome handleRequest(Exchange exc) { return handleRequestInternal(exc); } catch (IOException e) { log.error("", e); - user(router.isProduction(),getDisplayName()) + user(router.getConfiguration().isProduction(),getDisplayName()) .detail("Error in STOMP client!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/templating/TemplateInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/templating/TemplateInterceptor.java index 8afe65d194..266b586ad3 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/templating/TemplateInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/templating/TemplateInterceptor.java @@ -69,7 +69,7 @@ protected Outcome handleInternal(Exchange exc, Flow flow) { process(exc, flow); } catch (GroovyRuntimeException e) { log.warn("Groovy error executing template: {}", e.getMessage()); - internal(router.isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .addSubSee("groovy") .detail("Groovy error during template rendering.") .exception(e) @@ -77,7 +77,7 @@ protected Outcome handleInternal(Exchange exc, Flow flow) { .buildAndSetResponse(exc); return ABORT; } catch (TemplateExecutionException tee) { - ProblemDetails pd = internal(router.isProduction(), getDisplayName()) + ProblemDetails pd = internal(router.getConfiguration().isProduction(), getDisplayName()) .topLevel("line",tee.getLineNumber()) .topLevel("message", tee.getMessage()) .addSubSee("template"); @@ -104,7 +104,7 @@ protected Outcome handleInternal(Exchange exc, Flow flow) { } catch (Exception e) { log.warn("Error executing template.", e); - internal(router.isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .addSubSee("template") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/ws_addressing/WsaEndpointRewriterInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/ws_addressing/WsaEndpointRewriterInterceptor.java index 1b6dddd38d..0a37888fb6 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/ws_addressing/WsaEndpointRewriterInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/ws_addressing/WsaEndpointRewriterInterceptor.java @@ -56,7 +56,7 @@ public Outcome handleRequest(Exchange exc) { new WsaEndpointRewriter().rewriteEndpoint(message.getBodyAsStreamDecoded(), output, new Location( protocol, host, port)); } catch (Exception e) { log.error("",e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .detail("Could not rewrite endpoint!") .exception(e) .buildAndSetResponse(exchange); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/xml/Json2XmlInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/xml/Json2XmlInterceptor.java index 5a0adadb33..9f633bfb28 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/xml/Json2XmlInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/xml/Json2XmlInterceptor.java @@ -74,7 +74,7 @@ private Outcome handleInternal(Exchange exchange, Flow flow) { try { msg.setBodyContent(json2Xml(msg)); } catch (Exception e) { - internal(router.isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .title("Error parsing JSON") .addSubType("validation/json") .exception(e) // Message contains a meaningful error message diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/xml/Xml2JsonInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/xml/Xml2JsonInterceptor.java index 042b3aa1b4..2b424face2 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/xml/Xml2JsonInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/xml/Xml2JsonInterceptor.java @@ -58,7 +58,7 @@ public Outcome handleRequest(Exchange exc) { return handleInternal(exc.getRequest()); } catch (Exception e) { log.error("", e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .flow(REQUEST) .detail("Could not transform XML to JSON!") .exception(e) @@ -72,7 +72,7 @@ public Outcome handleResponse(Exchange exc) { try { return handleInternal(exc.getResponse()); } catch (Exception e) { - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .flow(Flow.RESPONSE) .detail("Could not return WSDL document!") .exception(e) diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/xmlcontentfilter/XMLContentFilterInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/xmlcontentfilter/XMLContentFilterInterceptor.java index e14716c6ef..9efccd1884 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/xmlcontentfilter/XMLContentFilterInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/xmlcontentfilter/XMLContentFilterInterceptor.java @@ -98,7 +98,7 @@ private Outcome handleMessage(Exchange exc, Message message) { return CONTINUE; } catch (Exception e) { log.error("", e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .title("XML Error") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/xmlprotection/XMLProtectionInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/xmlprotection/XMLProtectionInterceptor.java index ab40b42270..41a69d3f12 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/xmlprotection/XMLProtectionInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/xmlprotection/XMLProtectionInterceptor.java @@ -51,7 +51,7 @@ public Outcome handleRequest(Exchange exc) { return handleInternal(exc); } catch (Exception e) { log.error("", e); - user(router.isProduction(), getDisplayName()) + user(router.getConfiguration().isProduction(), getDisplayName()) .detail("Error inspecting body!") .exception(e) .buildAndSetResponse(exc); @@ -71,7 +71,7 @@ private Outcome handleInternal(Exchange exc) throws Exception { if (!exc.getRequest().isXML()) { String msg = "Content-Type %s is not XML.".formatted(exc.getRequest().getHeader().getContentType()); log.warn(msg); - user(router.isProduction(), getDisplayName()) + user(router.getConfiguration().isProduction(), getDisplayName()) .title("Request discarded by xmlProtection") .detail(msg) .buildAndSetResponse(exc); @@ -81,7 +81,7 @@ private Outcome handleInternal(Exchange exc) throws Exception { if (!protectXML(exc)) { String msg = "Request was rejected by XML protection. Please check XML."; log.warn(msg); - security(router.isProduction(), getDisplayName()) + security(router.getConfiguration().isProduction(), getDisplayName()) .title("Content violates XML security policy") .detail(msg) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/xslt/XSLTInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/xslt/XSLTInterceptor.java index 847e8266dc..1697b64c40 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/xslt/XSLTInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/xslt/XSLTInterceptor.java @@ -53,7 +53,7 @@ public Outcome handleRequest(Exchange exc) { try { transformMsg(exc.getRequest(), xslt, exc.getStringProperties()); } catch (Exception e) { - user(router.isProduction(),getDisplayName()) + user(router.getConfiguration().isProduction(),getDisplayName()) .detail("Error transforming request!") .exception(e) .buildAndSetResponse(exc); @@ -68,7 +68,7 @@ public Outcome handleResponse(Exchange exc) { transformMsg(exc.getResponse(), xslt, exc.getStringProperties()); } catch (Exception e) { log.error("Error transforming response!", e); - user(router.isProduction(),getDisplayName()) + user(router.getConfiguration().isProduction(),getDisplayName()) .detail("Error transforming response!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/jmx/JmxRouter.java b/core/src/main/java/com/predic8/membrane/core/jmx/JmxRouter.java index f2aa721b50..34704d8522 100644 --- a/core/src/main/java/com/predic8/membrane/core/jmx/JmxRouter.java +++ b/core/src/main/java/com/predic8/membrane/core/jmx/JmxRouter.java @@ -13,7 +13,7 @@ package com.predic8.membrane.core.jmx; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.DefaultRouter; import com.predic8.membrane.core.proxies.Proxy; import com.predic8.membrane.core.proxies.ServiceProxy; import org.springframework.jmx.export.annotation.ManagedAttribute; @@ -23,10 +23,10 @@ public class JmxRouter { - private final Router router; + private final DefaultRouter router; private final JmxExporter exporter; - public JmxRouter(Router router, JmxExporter exporter) { + public JmxRouter(DefaultRouter router, JmxExporter exporter) { this.router = router; this.exporter = exporter; exportServiceProxyList(); @@ -34,11 +34,11 @@ public JmxRouter(Router router, JmxExporter exporter) { @ManagedAttribute public String getName(){ - return router.getConfig().getJmx(); + return router.getConfiguration().getJmx(); } private void exportServiceProxyList(){ - for(Proxy proxy : router.getRules()){ + for(Proxy proxy : router.getRuleManager().getRules()){ if(proxy instanceof ServiceProxy){ exportServiceProxy((ServiceProxy) proxy); } @@ -46,7 +46,7 @@ private void exportServiceProxyList(){ } private void exportServiceProxy(ServiceProxy rule) { - String prefix = "org.membrane-soa:00=serviceProxies, 01=" + router.getConfig().getJmx()+ ", name="; + String prefix = "org.membrane-soa:00=serviceProxies, 01=%s, name=".formatted(router.getConfiguration().getJmx()); exporter.addBean(prefix + rule.getName().replace(":",""), new JmxServiceProxy(rule, router)); } } diff --git a/core/src/main/java/com/predic8/membrane/core/jmx/JmxServiceProxy.java b/core/src/main/java/com/predic8/membrane/core/jmx/JmxServiceProxy.java index 2783c40a9c..c0b52846b6 100644 --- a/core/src/main/java/com/predic8/membrane/core/jmx/JmxServiceProxy.java +++ b/core/src/main/java/com/predic8/membrane/core/jmx/JmxServiceProxy.java @@ -13,7 +13,7 @@ package com.predic8.membrane.core.jmx; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.DefaultRouter; import com.predic8.membrane.core.proxies.ServiceProxy; import org.springframework.jmx.export.annotation.ManagedAttribute; import org.springframework.jmx.export.annotation.ManagedOperation; @@ -25,9 +25,9 @@ public class JmxServiceProxy { private final ServiceProxy rule; - private final Router router; + private final DefaultRouter router; - public JmxServiceProxy(ServiceProxy rule, Router router) { + public JmxServiceProxy(ServiceProxy rule, DefaultRouter router) { this.rule = rule; this.router = router; } diff --git a/core/src/main/java/com/predic8/membrane/core/kubernetes/KubernetesWatcher.java b/core/src/main/java/com/predic8/membrane/core/kubernetes/KubernetesWatcher.java index 9d39d62b98..6f0d8dbfc1 100644 --- a/core/src/main/java/com/predic8/membrane/core/kubernetes/KubernetesWatcher.java +++ b/core/src/main/java/com/predic8/membrane/core/kubernetes/KubernetesWatcher.java @@ -37,14 +37,14 @@ public class KubernetesWatcher { private static final Logger LOG = LoggerFactory.getLogger(KubernetesWatcher.class); - private final Router router; + private final DefaultRouter router; private final BeanCollector beanRegistry; private final GrammarAutoGenerated grammar; private KubernetesClient client; private ExecutorService executors; private final ConcurrentHashMap watches = new ConcurrentHashMap<>(); - public KubernetesWatcher(Router router) { + public KubernetesWatcher(DefaultRouter router) { this.router = router; this.grammar = new GrammarAutoGenerated(); var br = new BeanRegistryImplementation(router, router, grammar); @@ -86,7 +86,7 @@ private KubernetesClient getClient() { } private Optional findK8sValidatingInterceptor() { - return router.getRules().stream() + return router.getRuleManager().getRules().stream() .map(Proxy::getFlow) .filter(Objects::nonNull) .flatMap(Collection::stream) diff --git a/core/src/main/java/com/predic8/membrane/core/lang/AbstractScriptInterceptor.java b/core/src/main/java/com/predic8/membrane/core/lang/AbstractScriptInterceptor.java index d1c87b8439..1791e1d7be 100644 --- a/core/src/main/java/com/predic8/membrane/core/lang/AbstractScriptInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/lang/AbstractScriptInterceptor.java @@ -105,7 +105,7 @@ protected Outcome runScript(Exchange exc, Flow flow) { msg.setBodyContent(om.writeValueAsBytes(m)); } catch (JsonProcessingException e) { log.error("", e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .addSubSee("json-processing-1") .detail("Error serializing Map to JSON") .exception(e) @@ -137,7 +137,7 @@ protected Outcome runScript(Exchange exc, Flow flow) { msg.setBodyContent(om.writeValueAsBytes(m)); } catch (JsonProcessingException e) { log.error("", e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .addSubSee("json-processing-2") .detail("Error serializing Map to JSON") .exception(e) @@ -174,7 +174,7 @@ protected void handleScriptExecutionException(Exchange exc, Exception e) { log.warn("Error executing {} script: {}", name, e.getMessage()); log.warn("Script: {}", src); - exc.setResponse(internal(router.isProduction(),getDisplayName()) + exc.setResponse(internal(router.getConfiguration().isProduction(),getDisplayName()) .addSubSee("script-execution") .title("Error executing script.") .addSubType("scripting") diff --git a/core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/ApiDocsInterceptor.java b/core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/ApiDocsInterceptor.java index fbf972def9..dafd124cb5 100644 --- a/core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/ApiDocsInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/ApiDocsInterceptor.java @@ -53,7 +53,7 @@ public Outcome handleRequest(Exchange exc) { publisher = new OpenAPIPublisher(ruleApiSpecs); } catch (Exception e) { log.error("", e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .addSubSee("publisher-creation") .detail("Error creating OpenAPI publisher!") .exception(e) @@ -69,7 +69,7 @@ public Outcome handleRequest(Exchange exc) { return publisher.handleOverviewOpenAPIDoc(exc, router, log); } catch (Exception e) { log.error("", e); - internal(router.isProduction(),getDisplayName()) + internal(router.getConfiguration().isProduction(),getDisplayName()) .addSubSee("publisher-handling") .detail("Error generating OpenAPI overview!") .exception(e) diff --git a/core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIInterceptor.java b/core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIInterceptor.java index 9ed2b64c78..ab5e899e9a 100644 --- a/core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIInterceptor.java @@ -108,7 +108,7 @@ public Outcome handleRequest(Exchange exc) { } catch (OpenAPIParsingException e) { String detail = "Could not parse OpenAPI with title %s. Check syntax and references.".formatted(rec.api.getInfo().getTitle()); log.warn(detail); - internal(router.isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .addSubSee("openapi-parsing") .flow(REQUEST) .detail(detail) @@ -116,7 +116,7 @@ public Outcome handleRequest(Exchange exc) { .buildAndSetResponse(exc); return RETURN; } catch (ReadingBodyException e) { - user(router.isProduction(), getDisplayName()) + user(router.getConfiguration().isProduction(), getDisplayName()) .addSubSee("reading-body") .flow(REQUEST) .detail("Connection problem: %s . Maybe the peer or the network closed the connection?".formatted(e.getMessage())) @@ -126,7 +126,7 @@ public Outcome handleRequest(Exchange exc) { } catch (Throwable t /* On purpose! Catch absolutely all */) { final String LOG_MESSAGE = "Message could not be validated against OpenAPI cause of an error during validation. Please check the OpenAPI with title %s."; log.error(LOG_MESSAGE.formatted(rec.api.getInfo().getTitle()), t); - user(router.isProduction(), getDisplayName()) + user(router.getConfiguration().isProduction(), getDisplayName()) .addSubSee("generic") .flow(REQUEST) .detail(LOG_MESSAGE.formatted(rec.api.getInfo().getTitle())) @@ -162,7 +162,7 @@ public Outcome handleResponse(Exchange exc) { } catch (OpenAPIParsingException e) { String detail = "Could not parse OpenAPI with title %s. Check syntax and references.".formatted(rec.api.getInfo().getTitle()); log.warn(detail, e); - user(router.isProduction(), getDisplayName()) + user(router.getConfiguration().isProduction(), getDisplayName()) .addSubType("openapi") .flow(RESPONSE) .detail(detail) @@ -171,7 +171,7 @@ public Outcome handleResponse(Exchange exc) { return RETURN; } catch (Throwable t /* On Purpose! Catch absolutely all */) { log.error("", t); - user(router.isProduction(), getDisplayName()) + user(router.getConfiguration().isProduction(), getDisplayName()) .addSubSee("generic") .flow(RESPONSE) .detail("Message could not be validated against OpenAPI cause of an error during validation. Please check the OpenAPI with title %s.".formatted(rec.api.getInfo().getTitle())) @@ -350,7 +350,7 @@ private String buildValidationPropertiesDescription(Map props) { } private void createErrorResponse(Exchange exc, ValidationErrors errors, ValidationErrors.Direction direction, boolean validationDetails) { - user(router.isProduction(), getDisplayName()) + user(router.getConfiguration().isProduction(), getDisplayName()) .title("OpenAPI message validation failed") .addSubType("validation") .status(errors.get(0).getContext().getStatusCode()) diff --git a/core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIPublisherInterceptor.java b/core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIPublisherInterceptor.java index c26cf0617a..3255c31b71 100644 --- a/core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIPublisherInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIPublisherInterceptor.java @@ -119,7 +119,7 @@ public Outcome handleRequest(Exchange exc) { return handleOverviewOpenAPIDoc(exc); } catch (Exception e) { log.error("", e); - internal(router.isProduction(), getDisplayName()) + internal(router.getConfiguration().isProduction(), getDisplayName()) .detail("Error handling OpenAPI overview!") .exception(e) .buildAndSetResponse(exc); diff --git a/core/src/main/java/com/predic8/membrane/core/proxies/AbstractProxy.java b/core/src/main/java/com/predic8/membrane/core/proxies/AbstractProxy.java index b35df337de..1c8eb2dc3d 100644 --- a/core/src/main/java/com/predic8/membrane/core/proxies/AbstractProxy.java +++ b/core/src/main/java/com/predic8/membrane/core/proxies/AbstractProxy.java @@ -101,7 +101,7 @@ public final void init(Router router) { } active = true; } catch (Exception e) { - if (!router.getConfig().isRetryInit()) + if (!router.getConfiguration().isRetryInit()) throw e; log.error("", e); active = false; diff --git a/core/src/main/java/com/predic8/membrane/core/proxies/Proxy.java b/core/src/main/java/com/predic8/membrane/core/proxies/Proxy.java index 99307694b8..911280dba7 100644 --- a/core/src/main/java/com/predic8/membrane/core/proxies/Proxy.java +++ b/core/src/main/java/com/predic8/membrane/core/proxies/Proxy.java @@ -38,7 +38,7 @@ public interface Proxy extends Cloneable { RuleStatisticCollector getStatisticCollector(); - void init(Router router) throws Exception; + void init(Router router); boolean isTargetAdjustHostHeader(); diff --git a/core/src/main/java/com/predic8/membrane/core/proxies/SOAPProxy.java b/core/src/main/java/com/predic8/membrane/core/proxies/SOAPProxy.java index 5afa1f8982..2eb4c99d37 100644 --- a/core/src/main/java/com/predic8/membrane/core/proxies/SOAPProxy.java +++ b/core/src/main/java/com/predic8/membrane/core/proxies/SOAPProxy.java @@ -22,7 +22,6 @@ import com.predic8.membrane.core.interceptor.schemavalidation.ValidatorInterceptor; import com.predic8.membrane.core.interceptor.server.*; import com.predic8.membrane.core.interceptor.soap.*; -import com.predic8.membrane.core.openapi.serviceproxy.OpenAPIInterceptor; import com.predic8.membrane.core.openapi.util.*; import com.predic8.membrane.core.resolver.*; import com.predic8.membrane.core.transport.http.client.*; @@ -54,7 +53,7 @@ * - Provides a simple service explorer * @explanation If the WSDL specified by the wsdl attribute is unavailable at startup, the <soapProxy> * becomes inactive. Reinitialization can be triggered via the admin console or automatically by the - * {@link Router}, which periodically attempts to restore the proxy. + * {@link DefaultRouter}, which periodically attempts to restore the proxy. * @topic 1. Proxies and Flow */ @MCElement(name = "soapProxy") diff --git a/core/src/main/java/com/predic8/membrane/core/proxies/SSLProxy.java b/core/src/main/java/com/predic8/membrane/core/proxies/SSLProxy.java index 69f0c21905..793aa1849b 100644 --- a/core/src/main/java/com/predic8/membrane/core/proxies/SSLProxy.java +++ b/core/src/main/java/com/predic8/membrane/core/proxies/SSLProxy.java @@ -18,7 +18,7 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCChildElement; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.security.SSLParser; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.interceptor.*; @@ -45,7 +45,7 @@ import static com.predic8.membrane.core.interceptor.FlowController.ABORTION_REASON; /** - * TODO Do will still use this? + * Proxies SSL connections to a target server without decrypting the traffic. */ @MCElement(name="sslProxy") public class SSLProxy implements Proxy { @@ -195,7 +195,7 @@ public SSLProvider getSslOutboundContext() { Router router; @Override - public void init(Router router) throws Exception { + public void init(Router router) { this.router = router; cm = new ConnectionManager(connectionConfiguration.getKeepAliveTimeout(), router.getTimerManager()); for (SSLInterceptor i : sslInterceptors) @@ -220,11 +220,7 @@ public String getErrorState() { @Override public SSLProxy clone() throws CloneNotSupportedException { SSLProxy clone = (SSLProxy) super.clone(); - try { - clone.init(router); - } catch (Exception e) { - throw new RuntimeException(e); - } + clone.init(router); return clone; } diff --git a/core/src/main/java/com/predic8/membrane/core/proxies/SSLableProxy.java b/core/src/main/java/com/predic8/membrane/core/proxies/SSLableProxy.java index e57fff2ec2..890e5c22bc 100644 --- a/core/src/main/java/com/predic8/membrane/core/proxies/SSLableProxy.java +++ b/core/src/main/java/com/predic8/membrane/core/proxies/SSLableProxy.java @@ -15,7 +15,9 @@ package com.predic8.membrane.core.proxies; import com.predic8.membrane.annot.*; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.security.*; +import com.predic8.membrane.core.kubernetes.client.*; import com.predic8.membrane.core.transport.ssl.*; import org.jetbrains.annotations.*; @@ -46,7 +48,7 @@ public void init() { if (acmeCtx == null) acmeCtx = new AcmeSSLContext(sslInboundParser, host, router.getHttpClientFactory(), router.getTimerManager()); setSslInboundContext(acmeCtx); - acmeCtx.init(router.getKubernetesClientFactory(), router.getHttpClientFactory()); + acmeCtx.init(router); return; } sslInboundContext = generateSslInboundContext(); diff --git a/core/src/main/java/com/predic8/membrane/core/resolver/ResolverMap.java b/core/src/main/java/com/predic8/membrane/core/resolver/ResolverMap.java index 3e5750a02b..9332178b3d 100644 --- a/core/src/main/java/com/predic8/membrane/core/resolver/ResolverMap.java +++ b/core/src/main/java/com/predic8/membrane/core/resolver/ResolverMap.java @@ -229,7 +229,7 @@ private SchemaResolver getSchemaResolver(String uri) { throw new RuntimeException("No SchemaResolver defined for " + uri); } - public void addRuleResolver(Router r) { + public void addRuleResolver(DefaultRouter r) { addSchemaResolver(new RuleResolver(r)); } diff --git a/core/src/main/java/com/predic8/membrane/core/resolver/RuleResolver.java b/core/src/main/java/com/predic8/membrane/core/resolver/RuleResolver.java index c3f4374f92..55f0bf577e 100644 --- a/core/src/main/java/com/predic8/membrane/core/resolver/RuleResolver.java +++ b/core/src/main/java/com/predic8/membrane/core/resolver/RuleResolver.java @@ -34,8 +34,8 @@ public class RuleResolver implements SchemaResolver { private static final Logger log = LoggerFactory.getLogger(RuleResolver.class); - final Router router; - public RuleResolver(Router router) { + final DefaultRouter router; + public RuleResolver(DefaultRouter router) { this.router = router; } diff --git a/core/src/main/java/com/predic8/membrane/core/router/hotdeploy/DefaultHotDeployer.java b/core/src/main/java/com/predic8/membrane/core/router/hotdeploy/DefaultHotDeployer.java index 8c542ab87a..b3bad0a542 100644 --- a/core/src/main/java/com/predic8/membrane/core/router/hotdeploy/DefaultHotDeployer.java +++ b/core/src/main/java/com/predic8/membrane/core/router/hotdeploy/DefaultHotDeployer.java @@ -16,6 +16,7 @@ import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.spring.*; +import org.jetbrains.annotations.*; import org.slf4j.*; import javax.annotation.concurrent.*; @@ -24,22 +25,26 @@ public class DefaultHotDeployer implements HotDeployer { private static final Logger log = LoggerFactory.getLogger(DefaultHotDeployer.class.getName()); - @GuardedBy("this") + @GuardedBy("lock") private HotDeploymentThread hdt; - private Router router; + private DefaultRouter router; + + private final Object lock = new Object(); @Override - public void init(Router router) { + public void start(@NotNull DefaultRouter router) { this.router = router; + startInternal(); } - @Override - public void start() { + private void startInternal() { // Prevent multiple threads from starting hot deployment at the same time. - synchronized (this) { - if (hdt != null) - throw new IllegalStateException("Hot deployment already started."); + synchronized (lock) { + if (hdt != null) { + log.warn("Hot deployment already started."); + return; + } if (!(router.getBeanFactory() instanceof TrackingApplicationContext tac)) { log.warn(""" @@ -56,11 +61,11 @@ public void start() { @Override public void stop() { - synchronized (this) { + synchronized (lock) { if (hdt == null) return; - router.stopAutoReinitializer(); + router.getReinitializer().stop(); hdt.stopASAP(); hdt = null; } @@ -68,8 +73,8 @@ public void stop() { @Override public void setEnabled(boolean enabled) { - if (enabled) - start(); + if (enabled && router != null) + startInternal(); else stop(); } diff --git a/core/src/main/java/com/predic8/membrane/core/router/hotdeploy/HotDeployer.java b/core/src/main/java/com/predic8/membrane/core/router/hotdeploy/HotDeployer.java index 18ce8c29bd..3ecf941099 100644 --- a/core/src/main/java/com/predic8/membrane/core/router/hotdeploy/HotDeployer.java +++ b/core/src/main/java/com/predic8/membrane/core/router/hotdeploy/HotDeployer.java @@ -18,7 +18,7 @@ public interface HotDeployer { - void start(); + void start(DefaultRouter router); void stop(); @@ -28,6 +28,5 @@ default boolean isEnabled() { return false; } - default void init(Router router) {} } diff --git a/core/src/main/java/com/predic8/membrane/core/router/hotdeploy/NullHotDeployer.java b/core/src/main/java/com/predic8/membrane/core/router/hotdeploy/NullHotDeployer.java index 2e732c02ec..35c4c6a761 100644 --- a/core/src/main/java/com/predic8/membrane/core/router/hotdeploy/NullHotDeployer.java +++ b/core/src/main/java/com/predic8/membrane/core/router/hotdeploy/NullHotDeployer.java @@ -14,9 +14,11 @@ package com.predic8.membrane.core.router.hotdeploy; +import com.predic8.membrane.core.*; + public class NullHotDeployer implements HotDeployer { @Override - public void start() { + public void start(DefaultRouter router) { } @@ -24,7 +26,6 @@ public void start() { public void stop() { } - @Override public void setEnabled(boolean enabled) { diff --git a/core/src/main/java/com/predic8/membrane/core/sslinterceptor/GateKeeperClientInterceptor.java b/core/src/main/java/com/predic8/membrane/core/sslinterceptor/GateKeeperClientInterceptor.java deleted file mode 100644 index 1fb3aeadd7..0000000000 --- a/core/src/main/java/com/predic8/membrane/core/sslinterceptor/GateKeeperClientInterceptor.java +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright 2019 predic8 GmbH, www.predic8.com - - 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 com.predic8.membrane.core.sslinterceptor; - -import com.fasterxml.jackson.databind.*; -import com.google.common.cache.*; -import com.google.common.collect.*; -import com.predic8.membrane.annot.*; -import com.predic8.membrane.core.*; -import com.predic8.membrane.core.interceptor.*; -import com.predic8.membrane.core.transport.http.*; -import com.predic8.membrane.core.transport.http.client.*; -import com.predic8.membrane.core.transport.ssl.*; - -import java.util.*; - -import static com.predic8.membrane.core.http.MimeType.*; -import static com.predic8.membrane.core.http.Request.post; -import static java.util.concurrent.TimeUnit.*; - -/** - * Connects to the predic8 Gatekeeper to check, whether access is allowed or not. - */ -@MCElement(id = "sslProxy-gatekeeper", name = "gatekeeper", component = false) -public class GateKeeperClientInterceptor implements SSLInterceptor { - - protected final String name; - private String url; - private HttpClientConfiguration httpClientConfiguration; - - private HttpClient httpClient; - private final ObjectMapper om = new ObjectMapper(); - - public GateKeeperClientInterceptor() { - name = "gatekeeper"; - } - - @Override - public void init(Router router) throws Exception { - httpClient = router.getHttpClientFactory().createClient(httpClientConfiguration); - } - - final Cache cache = CacheBuilder.newBuilder().expireAfterWrite(1, MINUTES).build(); - - public Outcome handleRequest(SSLExchange exc) throws Exception { - - String ruleName = exc.getRule().getName(); - String clientIP = exc.getRemoteAddrIp(); - - - String body = om.writeValueAsString(ImmutableMap.builder() - .put("rule", ruleName) - .put("clientIP", clientIP) - .build()); - - Map result = cache.getIfPresent(body); - if (result == null) - result = getResult(body); - if (result.get("error") != null) - return createResponse(exc); - boolean gate = (boolean) result.get("gate"); - - if (gate) { - cache.put(body, result); - return Outcome.CONTINUE; - } - return createResponse(exc); - } - - private Map getResult(String body) throws Exception { - var exc = post(this.url).contentType(APPLICATION_JSON).body(body).buildExchange(); - httpClient.call(exc); - - - if(exc.getResponse().getStatusCode() != 200) - return ImmutableMap.of("error", "status " + exc.getResponse().getStatusCode()); - - return ImmutableMap.copyOf(om.readValue(exc.getResponse().getBodyAsStreamDecoded(), Map.class)); - } - - private Outcome createResponse(SSLExchange exc) { - exc.setError(TLSError.access_denied); - return Outcome.RETURN; - } - - public String getUrl() { - return url; - } - - @MCAttribute - public void setUrl(String url) { - this.url = url; - } - - public HttpClientConfiguration getHttpClientConfiguration() { - return httpClientConfiguration; - } - - @MCChildElement(order = 10) - public void setHttpClientConfiguration(HttpClientConfiguration httpClientConfiguration) { - this.httpClientConfiguration = httpClientConfiguration; - } -} diff --git a/core/src/main/java/com/predic8/membrane/core/sslinterceptor/RouterIpResolverInterceptor.java b/core/src/main/java/com/predic8/membrane/core/sslinterceptor/RouterIpResolverInterceptor.java index 473a9e1cd8..b2539010ee 100644 --- a/core/src/main/java/com/predic8/membrane/core/sslinterceptor/RouterIpResolverInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/sslinterceptor/RouterIpResolverInterceptor.java @@ -18,7 +18,7 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCChildElement; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.security.SSLParser; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Response; @@ -112,7 +112,7 @@ public void setSslParser(SSLParser sslParser) { } @Override - public void init(Router router) throws Exception { + public void init(Router router) { httpClient = router.getHttpClientFactory().createClient(httpClientConfiguration); if (sslParser != null) sslContext = new StaticSSLContext(sslParser, router.getResolverMap(), router.getBaseLocation()); diff --git a/core/src/main/java/com/predic8/membrane/core/sslinterceptor/SSLInterceptor.java b/core/src/main/java/com/predic8/membrane/core/sslinterceptor/SSLInterceptor.java index b451ba39f6..298ddd70aa 100644 --- a/core/src/main/java/com/predic8/membrane/core/sslinterceptor/SSLInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/sslinterceptor/SSLInterceptor.java @@ -13,12 +13,12 @@ limitations under the License. */ package com.predic8.membrane.core.sslinterceptor; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.interceptor.Outcome; import com.predic8.membrane.core.transport.ssl.SSLExchange; public interface SSLInterceptor { - void init(Router router) throws Exception; + void init(Router router); Outcome handleRequest(SSLExchange exc) throws Exception; } diff --git a/core/src/main/java/com/predic8/membrane/core/transport/Transport.java b/core/src/main/java/com/predic8/membrane/core/transport/Transport.java index 8d1a15cca7..f9581a11dd 100644 --- a/core/src/main/java/com/predic8/membrane/core/transport/Transport.java +++ b/core/src/main/java/com/predic8/membrane/core/transport/Transport.java @@ -35,7 +35,7 @@ public abstract class Transport { protected final Set menuListeners = new HashSet<>(); private List interceptors = new Vector<>(); - private Router router; + private DefaultRouter router; private boolean reverseDNS = true; private int concurrentConnectionLimitPerIp = -1; @@ -53,7 +53,7 @@ public void setFlow(List flow) { this.interceptors = flow; } - public void init(Router router) throws Exception { + public void init(DefaultRouter router) { this.router = router; if (interceptors.isEmpty()) { @@ -76,14 +76,18 @@ public void init(Router router) throws Exception { /** * Look up an interceptor in the Spring context; fall back to default construction. */ - private @NotNull T getInterceptor(Class clazz) throws ReflectiveOperationException { + private @NotNull T getInterceptor(Class clazz) { BeanFactory bf = router.getBeanFactory(); if (bf instanceof ListableBeanFactory lbf) { T bean = lbf.getBeanProvider(clazz).getIfAvailable(); if (bean != null) return bean; } - return clazz.getConstructor().newInstance(); + try { + return clazz.getConstructor().newInstance(); + } catch (Exception e) { + throw new RuntimeException("Cannot instantiate object of class %s".formatted(clazz),e); + } } /** @@ -99,7 +103,7 @@ public void init(Router router) throws Exception { return new ExchangeStoreInterceptor(router.getExchangeStore()); } - public Router getRouter() { + public DefaultRouter getRouter() { return router; } diff --git a/core/src/main/java/com/predic8/membrane/core/transport/http/AbstractHttpHandler.java b/core/src/main/java/com/predic8/membrane/core/transport/http/AbstractHttpHandler.java index 04b6d31f48..725bb671d0 100644 --- a/core/src/main/java/com/predic8/membrane/core/transport/http/AbstractHttpHandler.java +++ b/core/src/main/java/com/predic8/membrane/core/transport/http/AbstractHttpHandler.java @@ -52,7 +52,7 @@ protected void invokeHandlers() throws AbortException, NoMoreRequestsException, getTransport().getRouter().getFlowController().invokeRequestHandlers(exchange, transport.getFlow()); if (exchange.getResponse() == null) { log.info("Interceptor chain returned no response"); - internal(transport.getRouter().isProduction(),"http-handler") + internal(transport.getRouter().getConfiguration().isProduction(),"http-handler") .addSubSee("no-response-produced") .detail("No response was generated by the interceptor chain.") .internal("interceptors", transport.getFlow()) @@ -77,7 +77,7 @@ protected void invokeHandlers() throws AbortException, NoMoreRequestsException, } private Response generateErrorResponse(Exception e) { - return internal(transport.getRouter().isProduction(),"http-handler") + return internal(transport.getRouter().getConfiguration().isProduction(),"http-handler") .addSubSee("error-during-request-phase") .exception(e) .build(); diff --git a/core/src/main/java/com/predic8/membrane/core/transport/http/HttpTransport.java b/core/src/main/java/com/predic8/membrane/core/transport/http/HttpTransport.java index c3cfa9fe86..46a191cc0a 100644 --- a/core/src/main/java/com/predic8/membrane/core/transport/http/HttpTransport.java +++ b/core/src/main/java/com/predic8/membrane/core/transport/http/HttpTransport.java @@ -36,11 +36,15 @@ import static java.util.concurrent.TimeUnit.*; /** + * HttpTransport is responsible for opening and closing ports. Besides HttpTransport there is also a ServletTransport. + * * @description

* The transport receives messages from clients and invokes interceptors in the request and response flow. * The interceptors that are engaged with the transport are global and are invoked for each message flowing * through the router. *

+ * + * */ @MCElement(name="transport") public class HttpTransport extends Transport { @@ -60,7 +64,7 @@ public class HttpTransport extends Transport { new SynchronousQueue<>(), new HttpServerThreadFactory()); @Override - public void init(Router router) throws Exception { + public void init(DefaultRouter router) { super.init(router); } @@ -108,7 +112,7 @@ public synchronized void closeAll(boolean waitForCompletion) { closePort(ipPort); } log.debug("Closing all stream pumps."); - Router router = getRouter(); + DefaultRouter router = getRouter(); if (router != null) router.getStatistics().getStreamPumpStats().closeAllStreamPumps(); @@ -284,7 +288,7 @@ public int getForceSocketCloseOnHotDeployAfter() { /** * @description When proxies.xml is changed and <router hotDeploy="true">, the Spring Context is automatically refreshed, - * which restarts the {@link Router} object (=Membrane API Gateway). Before the context refresh, all open socket connections + * which restarts the {@link DefaultRouter} object (=Membrane API Gateway). Before the context refresh, all open socket connections * have to be closed. Exchange objects which are still running might delay this process. Setting forceSocketCloseOnHotDeployAfter * to a non-zero number of milliseconds forces connections to be closed after this time. * @default 30000 diff --git a/core/src/main/java/com/predic8/membrane/core/transport/http2/Http2ExchangeHandler.java b/core/src/main/java/com/predic8/membrane/core/transport/http2/Http2ExchangeHandler.java index b5778abcf6..ff6b8d3cbd 100644 --- a/core/src/main/java/com/predic8/membrane/core/transport/http2/Http2ExchangeHandler.java +++ b/core/src/main/java/com/predic8/membrane/core/transport/http2/Http2ExchangeHandler.java @@ -163,7 +163,7 @@ private FlowController getFlowController() { } private Response generateErrorResponse(Exception e) { - return internal(transport.getRouter().isProduction(),"http2-exchange-handler") + return internal(transport.getRouter().getConfiguration().isProduction(),"http2-exchange-handler") .exception(e) .build(); } diff --git a/core/src/main/java/com/predic8/membrane/core/transport/ssl/AcmeSSLContext.java b/core/src/main/java/com/predic8/membrane/core/transport/ssl/AcmeSSLContext.java index 4852c21ae4..6bc6ded6f8 100644 --- a/core/src/main/java/com/predic8/membrane/core/transport/ssl/AcmeSSLContext.java +++ b/core/src/main/java/com/predic8/membrane/core/transport/ssl/AcmeSSLContext.java @@ -13,6 +13,7 @@ limitations under the License. */ package com.predic8.membrane.core.transport.ssl; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.security.*; import com.predic8.membrane.core.kubernetes.client.*; import com.predic8.membrane.core.transport.http.*; @@ -57,6 +58,14 @@ public AcmeSSLContext(SSLParser parser, this.timerManager = timerManager != null ? timerManager : new TimerManager(); } + public void init(Router router) { + KubernetesClientFactory kcf = null; + if (router instanceof DefaultRouter dr) { + kcf = dr.getRegistry().getBean(KubernetesClientFactory.class).orElse(null); + } + init(kcf,router.getHttpClientFactory()); + } + public void init(@Nullable KubernetesClientFactory kubernetesClientFactory, @Nullable HttpClientFactory httpClientFactory) { client.init(kubernetesClientFactory, httpClientFactory); initAndSchedule(); diff --git a/core/src/main/java/com/predic8/membrane/core/transport/ws/WebSocketInterceptorInterface.java b/core/src/main/java/com/predic8/membrane/core/transport/ws/WebSocketInterceptorInterface.java index aab0aacdd5..08f4f9e76b 100644 --- a/core/src/main/java/com/predic8/membrane/core/transport/ws/WebSocketInterceptorInterface.java +++ b/core/src/main/java/com/predic8/membrane/core/transport/ws/WebSocketInterceptorInterface.java @@ -14,7 +14,7 @@ package com.predic8.membrane.core.transport.ws; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; /** * Created by Predic8 on 12.04.2017. diff --git a/core/src/main/java/com/predic8/membrane/core/transport/ws/interceptors/WebSocketLogInterceptor.java b/core/src/main/java/com/predic8/membrane/core/transport/ws/interceptors/WebSocketLogInterceptor.java index 6dd7437efa..ee5fe9eff4 100644 --- a/core/src/main/java/com/predic8/membrane/core/transport/ws/interceptors/WebSocketLogInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/transport/ws/interceptors/WebSocketLogInterceptor.java @@ -16,7 +16,7 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.transport.ws.WebSocketFrame; import com.predic8.membrane.core.transport.ws.WebSocketInterceptorInterface; import com.predic8.membrane.core.transport.ws.WebSocketSender; diff --git a/core/src/main/java/com/predic8/membrane/core/transport/ws/interceptors/WebSocketSpringInterceptor.java b/core/src/main/java/com/predic8/membrane/core/transport/ws/interceptors/WebSocketSpringInterceptor.java index ae14bd9257..7df8bb2fcb 100644 --- a/core/src/main/java/com/predic8/membrane/core/transport/ws/interceptors/WebSocketSpringInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/transport/ws/interceptors/WebSocketSpringInterceptor.java @@ -18,7 +18,7 @@ import com.predic8.membrane.annot.MCAttribute; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.transport.ws.WebSocketFrame; import com.predic8.membrane.core.transport.ws.WebSocketInterceptorInterface; import com.predic8.membrane.core.transport.ws.WebSocketSender; diff --git a/core/src/main/java/com/predic8/membrane/core/transport/ws/interceptors/WebSocketStompReassembler.java b/core/src/main/java/com/predic8/membrane/core/transport/ws/interceptors/WebSocketStompReassembler.java index c754faaade..732f546274 100644 --- a/core/src/main/java/com/predic8/membrane/core/transport/ws/interceptors/WebSocketStompReassembler.java +++ b/core/src/main/java/com/predic8/membrane/core/transport/ws/interceptors/WebSocketStompReassembler.java @@ -16,7 +16,7 @@ import com.predic8.membrane.annot.MCChildElement; import com.predic8.membrane.annot.MCElement; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Body; import com.predic8.membrane.core.http.Request; diff --git a/core/src/main/java/com/predic8/membrane/core/util/TimerManager.java b/core/src/main/java/com/predic8/membrane/core/util/TimerManager.java index 696e11e1bd..b64370bd88 100644 --- a/core/src/main/java/com/predic8/membrane/core/util/TimerManager.java +++ b/core/src/main/java/com/predic8/membrane/core/util/TimerManager.java @@ -13,6 +13,9 @@ limitations under the License. */ package com.predic8.membrane.core.util; +import com.predic8.membrane.core.*; +import org.slf4j.*; + import java.util.Timer; import java.util.TimerTask; @@ -20,17 +23,23 @@ * Manages periodic tasks with a single timer. */ public class TimerManager { + + private static final Logger log = LoggerFactory.getLogger(TimerManager.class); + protected final java.util.Timer timer = new Timer(true); public void schedulePeriodicTask(TimerTask task, long period, String title) { + log.debug("Scheduling periodic task {} every {} ms.", title, period); timer.schedule(task, period, period); } public void schedule(TimerTask task, long delay, String title) { + log.debug("Scheduling task {} in {} ms.", title, delay); timer.schedule(task, delay); } public void shutdown() { + log.debug("Shutting down timer."); timer.cancel(); } } diff --git a/core/src/main/java/com/predic8/membrane/core/util/jdbc/AbstractJdbcSupport.java b/core/src/main/java/com/predic8/membrane/core/util/jdbc/AbstractJdbcSupport.java index b9fb851b9f..908470963b 100644 --- a/core/src/main/java/com/predic8/membrane/core/util/jdbc/AbstractJdbcSupport.java +++ b/core/src/main/java/com/predic8/membrane/core/util/jdbc/AbstractJdbcSupport.java @@ -15,7 +15,7 @@ package com.predic8.membrane.core.util.jdbc; import com.predic8.membrane.annot.MCAttribute; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.DefaultRouter; import com.predic8.membrane.core.util.ConfigurationException; import javax.sql.DataSource; @@ -24,7 +24,7 @@ public abstract class AbstractJdbcSupport { private DataSource datasource; - private Router router; + private DefaultRouter router; private static final String DATASOURCE_SAMPLE = """ Sample: @@ -48,7 +48,7 @@ public abstract class AbstractJdbcSupport { """; - public void init(Router router) { + public void init(DefaultRouter router) { this.router = router; getDatasourceIfNull(); } diff --git a/core/src/test/java/com/predic8/membrane/AbstractTestWithRouter.java b/core/src/test/java/com/predic8/membrane/AbstractTestWithRouter.java index 3285f204cb..5880cea797 100644 --- a/core/src/test/java/com/predic8/membrane/AbstractTestWithRouter.java +++ b/core/src/test/java/com/predic8/membrane/AbstractTestWithRouter.java @@ -18,15 +18,15 @@ public abstract class AbstractTestWithRouter { - protected static Router router; + protected Router router; - @BeforeAll - static void setUp() { - router = new HttpRouter(); + @BeforeEach + void setUp() { + router = new TestRouter(); } - @AfterAll - static void shutDown() { - router.shutdown(); + @AfterEach + void shutDown() { + router.stop(); } } diff --git a/core/src/test/java/com/predic8/membrane/AllTests.java b/core/src/test/java/com/predic8/membrane/AllTests.java deleted file mode 100644 index 2c87adeadc..0000000000 --- a/core/src/test/java/com/predic8/membrane/AllTests.java +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2009, 2011 predic8 GmbH, www.predic8.com - - 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 com.predic8.membrane; - -import com.predic8.membrane.core.*; -import com.predic8.membrane.integration.*; -import org.junit.platform.suite.api.SelectClasses; -import org.junit.platform.suite.api.Suite; - -@Suite -@SelectClasses({ - UnitTests.class, - IntegrationTestsWithoutInternet.class, - IntegrationTestsWithInternet.class -}) -public class AllTests {} \ No newline at end of file diff --git a/core/src/test/java/com/predic8/membrane/core/RouterTest.java b/core/src/test/java/com/predic8/membrane/core/DefaultRouterTest.java similarity index 95% rename from core/src/test/java/com/predic8/membrane/core/RouterTest.java rename to core/src/test/java/com/predic8/membrane/core/DefaultRouterTest.java index 91dce137f7..82631db90e 100644 --- a/core/src/test/java/com/predic8/membrane/core/RouterTest.java +++ b/core/src/test/java/com/predic8/membrane/core/DefaultRouterTest.java @@ -26,7 +26,7 @@ import static io.restassured.filter.log.LogDetail.*; import static org.hamcrest.Matchers.*; -class RouterTest { +class DefaultRouterTest { public static final String INTERNAL_SECRET = "supersecret"; static Router dev, prod; @@ -39,8 +39,8 @@ static void setUp() throws IOException { @AfterAll static void tearDown() { - prod.shutdown(); - dev.shutdown(); + prod.stop(); + dev.stop(); } @Test @@ -113,8 +113,8 @@ void devXML() { } private static Router createRouter(int port, boolean production) throws IOException { - HttpRouter r = new HttpRouter(); - r.getConfig().setProduction(production); + Router r = new DefaultRouter(); + r.getConfiguration().setProduction(production); APIProxy api = new APIProxy(); api.setKey(new APIProxyKey(port)); api.getFlow().add(new AbstractInterceptor() { @@ -128,7 +128,7 @@ public String getDisplayName() { return "interceptor"; } }); - r.getConfig().setHotDeploy(false); + r.getConfiguration().setHotDeploy(false); r.add(api); r.start(); return r; diff --git a/core/src/test/java/com/predic8/membrane/core/MockRouter.java b/core/src/test/java/com/predic8/membrane/core/MockRouter.java index 05fd44d1e2..ad7a4fa899 100644 --- a/core/src/test/java/com/predic8/membrane/core/MockRouter.java +++ b/core/src/test/java/com/predic8/membrane/core/MockRouter.java @@ -13,19 +13,18 @@ limitations under the License. */ package com.predic8.membrane.core; -import com.predic8.membrane.core.exchangestore.ForgetfulExchangeStore; -import com.predic8.membrane.core.transport.Transport; -import com.predic8.membrane.core.transport.http.MockHttpTransport; +import com.predic8.membrane.core.exchangestore.*; +import com.predic8.membrane.core.transport.http.*; -public class MockRouter extends Router { +public class MockRouter extends DefaultRouter { public MockRouter() { setExchangeStore(new ForgetfulExchangeStore()); } @Override - public Transport getTransport() { + public HttpTransport getTransport() { return new MockHttpTransport(); } -} +} \ No newline at end of file diff --git a/core/src/test/java/com/predic8/membrane/core/RuleManagerTest.java b/core/src/test/java/com/predic8/membrane/core/RuleManagerTest.java index b5a48b5beb..99ee5f3dd0 100644 --- a/core/src/test/java/com/predic8/membrane/core/RuleManagerTest.java +++ b/core/src/test/java/com/predic8/membrane/core/RuleManagerTest.java @@ -58,7 +58,7 @@ public void setUp() throws Exception{ @AfterEach public void tearDown() { - router.shutdown(); + router.stop(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/RuleManagerUriTemplateTest.java b/core/src/test/java/com/predic8/membrane/core/RuleManagerUriTemplateTest.java index 6a8d4d2eef..4503a410a1 100644 --- a/core/src/test/java/com/predic8/membrane/core/RuleManagerUriTemplateTest.java +++ b/core/src/test/java/com/predic8/membrane/core/RuleManagerUriTemplateTest.java @@ -13,7 +13,6 @@ limitations under the License. */ package com.predic8.membrane.core; -import com.predic8.membrane.*; import com.predic8.membrane.core.config.*; import com.predic8.membrane.core.openapi.serviceproxy.*; import com.predic8.membrane.core.proxies.Proxy; @@ -26,7 +25,7 @@ import static com.predic8.membrane.core.http.Request.*; import static org.junit.jupiter.api.Assertions.*; -public class RuleManagerUriTemplateTest extends AbstractTestWithRouter { +public class RuleManagerUriTemplateTest { static Stream matches() { return Stream.of(Arguments.of("/foo","/foo"), @@ -57,9 +56,9 @@ void pathDoesntMatchesUriTemplate(String uriTemplate,String path) throws Excepti assertNotEquals(p, getMatchingProxy(uriTemplate, path, p)); } - private static Proxy getMatchingProxy(String uriTemplate, String path, APIProxy p) throws URISyntaxException { + private Proxy getMatchingProxy(String uriTemplate, String path, APIProxy p) throws URISyntaxException { p.setPath(new Path(false, uriTemplate)); - p.init(router); + p.init(new DefaultRouter()); return new RuleManager() {{ proxies.add(p); }}.getMatchingRule(get(path).buildExchange()); diff --git a/core/src/test/java/com/predic8/membrane/core/SimpleTest.java b/core/src/test/java/com/predic8/membrane/core/SimpleTest.java index 8457b4ae62..65500f6dc3 100644 --- a/core/src/test/java/com/predic8/membrane/core/SimpleTest.java +++ b/core/src/test/java/com/predic8/membrane/core/SimpleTest.java @@ -19,11 +19,11 @@ public class SimpleTest { - private static Router router; + private static DefaultRouter router; @BeforeAll - static void setUp() throws Exception { - router = Router.init("classpath:/test-proxies.xml"); + static void setUp() { + router = RouterXmlBootstrap.initByXML("classpath:/test-proxies.xml"); } @Test @@ -32,8 +32,8 @@ public void test() { } @AfterAll - static void tearDown() throws Exception { - router.shutdown(); + static void tearDown() { + router.stop(); } } diff --git a/core/src/test/java/com/predic8/membrane/core/TestRouter.java b/core/src/test/java/com/predic8/membrane/core/TestRouter.java new file mode 100644 index 0000000000..c5df8b9f64 --- /dev/null +++ b/core/src/test/java/com/predic8/membrane/core/TestRouter.java @@ -0,0 +1,42 @@ +/* Copyright 2025 predic8 GmbH, www.predic8.com + + 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 com.predic8.membrane.core; + +import com.predic8.membrane.core.transport.http.*; +import com.predic8.membrane.core.transport.http.client.*; + +/** + * Opens ports but does not start hotdeployer, reinit, ... + */ +public class TestRouter extends DefaultRouter { + + public TestRouter() { + } + + /* + TODO: overwrite init(), start() to do nothing + */ + + public TestRouter(ProxyConfiguration proxyConfiguration) { + if (proxyConfiguration != null) + getResolverMap().getHTTPSchemaResolver().getHttpClientConfig().setProxy(proxyConfiguration); + } + + @Override + public HttpTransport getTransport() { + return (HttpTransport) super.getTransport(); + } + +} diff --git a/core/src/test/java/com/predic8/membrane/core/UnitTests.java b/core/src/test/java/com/predic8/membrane/core/UnitTests.java index e63eec2563..5c66021a62 100644 --- a/core/src/test/java/com/predic8/membrane/core/UnitTests.java +++ b/core/src/test/java/com/predic8/membrane/core/UnitTests.java @@ -19,9 +19,7 @@ @SelectPackages({"com.predic8"}) @ExcludePackages("com.predic8.membrane.integration") @ExcludeClassNamePatterns({ - "com.predic8.membrane.AllTests", // Replaced with package scan "com.predic8.membrane.core.transport.http.ConnectionTest", // #2180 should fix it - "com.predic8.membrane.integration.withinternet.interceptor.RewriteInterceptorIntegrationTest", // Rewrite as UnitTest with sampleSOAPService "com.predic8.membrane.core.interceptor.tunnel.WebsocketStompTest", // Fails: not standalone; depends on external WS+STOMP setup "com.predic8.membrane.core.interceptor.oauth2client.OAuth2Resource2InterceptorTest", // Disabled: incomplete setup; AuthorizationService (and other) not configured "com.predic8.membrane.core.util.MemcachedConnectorTest" // Disabled: not standalone; needs Memcached at 127.0.0.1:11211 (fails with Connection refused) diff --git a/core/src/test/java/com/predic8/membrane/core/acl/ACLTest.java b/core/src/test/java/com/predic8/membrane/core/acl/ACLTest.java index 519b33780a..1a5f245401 100644 --- a/core/src/test/java/com/predic8/membrane/core/acl/ACLTest.java +++ b/core/src/test/java/com/predic8/membrane/core/acl/ACLTest.java @@ -15,6 +15,7 @@ import com.predic8.membrane.core.*; import com.predic8.membrane.core.interceptor.acl.*; +import org.junit.jupiter.api.*; import java.util.function.*; @@ -22,9 +23,21 @@ public abstract class ACLTest extends AccessControlInterceptor { + protected Router router; + + @BeforeEach + void setUpEach() { + router = new DummyTestRouter(); + router.start(); + } + + @AfterEach + void tearDownEach() { + router.stop(); + } + private AccessControlInterceptor createRouter(boolean isReverseDNS, boolean useForwardedFor, Function f) { - Router router = new Router(); - AccessControlInterceptor aci = buildAci(f.apply(router), router); + AccessControlInterceptor aci = buildAci(f.apply(router)); aci.setUseXForwardedForAsClientAddr(useForwardedFor); return aci; } @@ -33,11 +46,11 @@ AccessControlInterceptor createIpACI(String scheme, ParseType ptype, boolean isR return createRouter(isReverseDNS, useForwardedFor, router -> getIpResource(scheme, ptype, router)); } - AccessControlInterceptor createHostnameACI(String scheme, boolean isReverseDNS) throws Exception { + AccessControlInterceptor createHostnameACI(String scheme, boolean isReverseDNS) { return createRouter(isReverseDNS, false, router -> getHostnameResource(scheme, router)); } - private static AccessControlInterceptor buildAci(Resource resource, Router router) { + private static AccessControlInterceptor buildAci(Resource resource) { return new ACLTest() {{ setAccessControl(new AccessControl(router) {{ addResource(resource); diff --git a/core/src/test/java/com/predic8/membrane/core/azure/AzureDnsApiSimulator.java b/core/src/test/java/com/predic8/membrane/core/azure/AzureDnsApiSimulator.java index cc9795e7ae..27099706d9 100644 --- a/core/src/test/java/com/predic8/membrane/core/azure/AzureDnsApiSimulator.java +++ b/core/src/test/java/com/predic8/membrane/core/azure/AzureDnsApiSimulator.java @@ -15,7 +15,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.predic8.membrane.core.HttpRouter; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Response; import com.predic8.membrane.core.interceptor.AbstractInterceptor; @@ -34,7 +34,7 @@ public class AzureDnsApiSimulator { private static final Logger log = LoggerFactory.getLogger(AzureDnsApiSimulator.class); private final int port; - private HttpRouter router; + private Router router; private final Map>> tableStorage = new HashMap<>(); @@ -43,8 +43,7 @@ public AzureDnsApiSimulator(int port) { } public void start() throws IOException { - router = new HttpRouter(); - router.getConfig().setHotDeploy(false); + router = new TestRouter(); var sp = new ServiceProxy(new ServiceProxyKey(port), "localhost", port); diff --git a/core/src/test/java/com/predic8/membrane/core/config/ReadRulesConfigurationTest.java b/core/src/test/java/com/predic8/membrane/core/config/ReadRulesConfigurationTest.java index 3a89abd588..7d1b53b52b 100644 --- a/core/src/test/java/com/predic8/membrane/core/config/ReadRulesConfigurationTest.java +++ b/core/src/test/java/com/predic8/membrane/core/config/ReadRulesConfigurationTest.java @@ -13,102 +13,101 @@ limitations under the License. */ package com.predic8.membrane.core.config; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.proxies.*; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; -import java.util.List; +import java.util.*; import static org.junit.jupiter.api.Assertions.*; public class ReadRulesConfigurationTest { - private static Router router; - - private static List proxies; - - @BeforeAll - public static void setUp() { - router = Router.init("classpath:/proxies.xml"); - proxies = router.getRuleManager().getRules(); - } - - @Test - void testRulesSize() { - assertEquals(3, proxies.size()); - } - - @Test - void testProxyRuleListenPort() { - assertEquals(3090, proxies.getFirst().getKey().getPort()); - } - - @Test - void testServiceProxyListenPort() { - assertEquals(3000, proxies.get(1).getKey().getPort()); - } - - @Test - void testServiceProxyTargetPort() { - assertEquals(80, ((ServiceProxy) proxies.get(1)).getTargetPort()); - } - - @Test - void testServiceProxyTargetHost() { - assertEquals("thomas-bayer.com", ((ServiceProxy) proxies.get(1)).getTargetHost()); - } - - @Test - void testServiceProxyDefaultMethod() { - assertEquals("*", proxies.get(1).getKey().getMethod()); - } - - @Test - void testTestServiceProxyDefaultHost() { - assertEquals("*", proxies.get(1).getKey().getHost()); - } - - @Test - void testLocalServiceProxyListenPort() { - assertEquals(2000, proxies.get(2).getKey().getPort()); - } - - @Test - void testLocalServiceProxyTargetPort() { - assertEquals(3011, ((ServiceProxy) proxies.get(2)).getTargetPort()); - } - - @Test - void testServiceProxyMethodSet() { - assertEquals("GET", proxies.get(2).getKey().getMethod()); - } - - @Test - void testServiceProxyHostSet() { - assertEquals("localhost", proxies.get(2).getKey().getHost()); - } - - @Test - void testLocalServiceProxyInboundSSL() { + private static DefaultRouter router; + + private static List proxies; + + @BeforeAll + static void setUp() { + router = RouterXmlBootstrap.initByXML("classpath:/proxies.xml"); + proxies = router.getRuleManager().getRules(); + } + + @AfterAll + static void tearDown() { + router.stop(); + } + + @Test + void testRulesSize() { + assertEquals(3, proxies.size()); + } + + @Test + void testProxyRuleListenPort() { + assertEquals(3090, proxies.getFirst().getKey().getPort()); + } + + @Test + void testServiceProxyListenPort() { + assertEquals(3000, proxies.get(1).getKey().getPort()); + } + + @Test + void testServiceProxyTargetPort() { + assertEquals(80, ((ServiceProxy) proxies.get(1)).getTargetPort()); + } + + @Test + void testServiceProxyTargetHost() { + assertEquals("thomas-bayer.com", ((ServiceProxy) proxies.get(1)).getTargetHost()); + } + + @Test + void testServiceProxyDefaultMethod() { + assertEquals("*", proxies.get(1).getKey().getMethod()); + } + + @Test + void testTestServiceProxyDefaultHost() { + assertEquals("*", proxies.get(1).getKey().getHost()); + } + + @Test + void testLocalServiceProxyListenPort() { + assertEquals(2000, proxies.get(2).getKey().getPort()); + } + + @Test + void testLocalServiceProxyTargetPort() { + assertEquals(3011, ((ServiceProxy) proxies.get(2)).getTargetPort()); + } + + @Test + void testServiceProxyMethodSet() { + assertEquals("GET", proxies.get(2).getKey().getMethod()); + } + + @Test + void testServiceProxyHostSet() { + assertEquals("localhost", proxies.get(2).getKey().getHost()); + } + + @Test + void testLocalServiceProxyInboundSSL() { if (proxies.get(2) instanceof SSLableProxy sp) { - assertFalse(sp.isInboundSSL()); - } - assertTrue(true); - } - - @Test - void testLocalServiceProxyOutboundSSL() { - if (proxies.get(2) instanceof SSLableProxy sp) { - assertNull(sp.getSslOutboundContext()); - } - assertTrue(true); - } - - @AfterAll - public static void tearDown() { - router.shutdown(); - } - + assertFalse(sp.isInboundSSL()); + return; + } + fail(); + } + + @Test + void testLocalServiceProxyOutboundSSL() { + if (proxies.get(2) instanceof SSLableProxy sp) { + assertNull(sp.getSslOutboundContext()); + return; + } + fail(); + } } diff --git a/core/src/test/java/com/predic8/membrane/core/config/ReadRulesWithInterceptorsConfigurationTest.java b/core/src/test/java/com/predic8/membrane/core/config/ReadRulesWithInterceptorsConfigurationTest.java index 664f3da706..f72c3d4189 100644 --- a/core/src/test/java/com/predic8/membrane/core/config/ReadRulesWithInterceptorsConfigurationTest.java +++ b/core/src/test/java/com/predic8/membrane/core/config/ReadRulesWithInterceptorsConfigurationTest.java @@ -24,13 +24,13 @@ public class ReadRulesWithInterceptorsConfigurationTest { - private static Router router; + private static DefaultRouter router; private static List proxies; @BeforeAll static void setUp() { - router = Router.init("src/test/resources/ref.proxies.xml"); + router = RouterXmlBootstrap.initByXML("src/test/resources/ref.proxies.xml"); proxies = router.getRuleManager().getRules(); } @@ -65,7 +65,7 @@ void ruleInterceptorDisplayNames() { @AfterAll static void tearDown() { - router.shutdown(); + router.stop(); } } diff --git a/core/src/test/java/com/predic8/membrane/core/config/SpringReferencesTest.java b/core/src/test/java/com/predic8/membrane/core/config/SpringReferencesTest.java index 1996ac8ed6..41e9e83225 100644 --- a/core/src/test/java/com/predic8/membrane/core/config/SpringReferencesTest.java +++ b/core/src/test/java/com/predic8/membrane/core/config/SpringReferencesTest.java @@ -25,21 +25,21 @@ public class SpringReferencesTest { - private static Router r; + private static DefaultRouter r; @BeforeAll public static void before() { - r = Router.init("classpath:/proxies-using-spring-refs.xml"); + r = RouterXmlBootstrap.initByXML("classpath:/proxies-using-spring-refs.xml"); } @AfterAll public static void after() { - r.shutdown(); + r.stop(); } @Test public void doit() { - ServiceProxy p = (ServiceProxy) r.getRules().iterator().next(); + ServiceProxy p = (ServiceProxy) r.getRuleManager().getRules().getFirst(); List is = p.getFlow(); assertEquals(LogInterceptor.class, is.get(0).getClass()); diff --git a/core/src/test/java/com/predic8/membrane/core/exchangestore/AbortExchangeTest.java b/core/src/test/java/com/predic8/membrane/core/exchangestore/AbortExchangeTest.java index 0b710aec76..a528f26900 100644 --- a/core/src/test/java/com/predic8/membrane/core/exchangestore/AbortExchangeTest.java +++ b/core/src/test/java/com/predic8/membrane/core/exchangestore/AbortExchangeTest.java @@ -13,43 +13,35 @@ limitations under the License. */ package com.predic8.membrane.core.exchangestore; -import com.predic8.membrane.core.HttpRouter; -import com.predic8.membrane.core.Router; -import com.predic8.membrane.core.exchange.AbstractExchange; -import com.predic8.membrane.core.exchange.Exchange; -import com.predic8.membrane.core.http.BodyUtil; -import com.predic8.membrane.core.http.Request; -import com.predic8.membrane.core.http.Response; -import com.predic8.membrane.core.interceptor.AbstractInterceptor; -import com.predic8.membrane.core.interceptor.ExchangeStoreInterceptor; -import com.predic8.membrane.core.interceptor.Outcome; -import com.predic8.membrane.core.proxies.ServiceProxy; -import com.predic8.membrane.core.proxies.ServiceProxyKey; -import com.predic8.membrane.core.transport.http.HttpClient; -import org.apache.commons.io.IOUtils; +import com.predic8.membrane.core.*; +import com.predic8.membrane.core.exchange.*; +import com.predic8.membrane.core.http.*; +import com.predic8.membrane.core.interceptor.*; +import com.predic8.membrane.core.proxies.*; +import com.predic8.membrane.core.transport.http.*; +import org.apache.commons.io.*; import org.junit.jupiter.api.*; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; +import java.io.*; +import java.util.*; -import static com.predic8.membrane.core.http.Request.get; -import static com.predic8.membrane.core.interceptor.Outcome.RETURN; -import static java.lang.Thread.sleep; +import static com.predic8.membrane.core.http.Request.*; +import static com.predic8.membrane.core.interceptor.Outcome.*; +import static java.lang.Thread.*; import static org.junit.jupiter.api.Assertions.*; public class AbortExchangeTest { - Router router; + TestRouter router; @BeforeEach public void setup() throws Exception { - router = new HttpRouter(); - + router = new TestRouter(); LimitedMemoryExchangeStore es = new LimitedMemoryExchangeStore(); router.setExchangeStore(es); - router.getTransport().getFlow().add(2, new ExchangeStoreInterceptor(es)); + var global = new GlobalInterceptor(); + global.getFlow().add(new ExchangeStoreInterceptor(es)); + router.getRegistry().register("global",global); ServiceProxy sp2 = new ServiceProxy(new ServiceProxyKey("*", "*", ".*", 3031), "", -1); sp2.getFlow().add(new AbstractInterceptor() { @@ -73,8 +65,8 @@ public int read() { return RETURN; } }); - router.getRuleManager().addProxyAndOpenPortIfNew(sp2); - router.init(); + router.add(sp2); + router.start(); } @Test @@ -125,6 +117,6 @@ private Response performRequest() throws Exception { @AfterEach public void done() { - router.shutdown(); + router.stop(); } } diff --git a/core/src/test/java/com/predic8/membrane/core/exchangestore/ElasticSearchExchangeStoreTest.java b/core/src/test/java/com/predic8/membrane/core/exchangestore/ElasticSearchExchangeStoreTest.java index 07493028cc..fb2963303a 100644 --- a/core/src/test/java/com/predic8/membrane/core/exchangestore/ElasticSearchExchangeStoreTest.java +++ b/core/src/test/java/com/predic8/membrane/core/exchangestore/ElasticSearchExchangeStoreTest.java @@ -14,63 +14,68 @@ package com.predic8.membrane.core.exchangestore; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.predic8.membrane.core.HttpRouter; -import com.predic8.membrane.core.exchange.Exchange; -import com.predic8.membrane.core.http.Request; -import com.predic8.membrane.core.interceptor.AbstractInterceptor; -import com.predic8.membrane.core.interceptor.ExchangeStoreInterceptor; -import com.predic8.membrane.core.interceptor.Interceptor; -import com.predic8.membrane.core.interceptor.Outcome; -import com.predic8.membrane.core.interceptor.flow.ReturnInterceptor; -import com.predic8.membrane.core.interceptor.log.LogInterceptor; -import com.predic8.membrane.core.interceptor.templating.StaticInterceptor; -import com.predic8.membrane.core.proxies.ServiceProxy; -import com.predic8.membrane.core.proxies.ServiceProxyKey; -import com.predic8.membrane.core.transport.http.HttpClient; -import org.jetbrains.annotations.NotNull; +import com.fasterxml.jackson.core.*; +import com.fasterxml.jackson.databind.*; +import com.predic8.membrane.core.*; +import com.predic8.membrane.core.exchange.*; +import com.predic8.membrane.core.http.*; +import com.predic8.membrane.core.interceptor.*; +import com.predic8.membrane.core.interceptor.flow.*; +import com.predic8.membrane.core.interceptor.log.*; +import com.predic8.membrane.core.interceptor.templating.*; +import com.predic8.membrane.core.proxies.*; +import com.predic8.membrane.core.transport.http.*; +import org.jetbrains.annotations.*; import org.jose4j.base64url.Base64; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import static com.predic8.membrane.core.http.Header.AUTHORIZATION; -import static com.predic8.membrane.core.http.Header.CONTENT_TYPE; -import static com.predic8.membrane.core.http.MimeType.TEXT_PLAIN; -import static com.predic8.membrane.core.http.Response.ok; -import static com.predic8.membrane.core.interceptor.Outcome.RETURN; -import static java.nio.charset.StandardCharsets.UTF_8; +import org.junit.jupiter.api.*; + +import java.io.*; +import java.util.*; + +import static com.predic8.membrane.core.http.Header.*; +import static com.predic8.membrane.core.http.MimeType.*; +import static com.predic8.membrane.core.http.Response.*; +import static com.predic8.membrane.core.interceptor.Outcome.*; +import static java.nio.charset.StandardCharsets.*; import static org.junit.jupiter.api.Assertions.*; class ElasticSearchExchangeStoreTest { - private static HttpRouter gateway; - private static HttpRouter back; - private static HttpRouter elasticMock; - private static ElasticSearchExchangeStore es; + private static final ObjectMapper om = new ObjectMapper(); - private static final List insertedObjects = new ArrayList<>(); - private static String RESPONSE_BODY = """ + private static final String RESPONSE_BODY = """ {"demo": true}"""; - private String REQUEST_BODY = """ + private static final String REQUEST_BODY = """ {"where":"there"}"""; - @BeforeAll - public static void start() throws IOException { + private TestRouter gateway; + private TestRouter back; + private TestRouter elasticMock; + private ElasticSearchExchangeStore es; + + private final List insertedObjects = new ArrayList<>(); + + @BeforeEach + public void start() throws IOException { initializeElasticSearchMock(); initializeBackend(); } - private static void initializeElasticSearchMock() throws IOException { - elasticMock = new HttpRouter(); - elasticMock.getConfig().setHotDeploy(false); + @AfterEach + public void done() { + try { + back.stop(); + } finally { + try { + gateway.stop(); + } finally { + elasticMock.stop(); + } + } + } + + private void initializeElasticSearchMock() throws IOException { + elasticMock = new TestRouter(); ServiceProxy sp = new ServiceProxy(new ServiceProxyKey(3066), null, 0); sp.getFlow().add(createBodyLoggingInterceptor()); sp.getFlow().add(createElasticSearchMockInterceptor()); @@ -78,62 +83,52 @@ private static void initializeElasticSearchMock() throws IOException { elasticMock.start(); } - private static @NotNull LogInterceptor createBodyLoggingInterceptor() { + private @NotNull LogInterceptor createBodyLoggingInterceptor() { LogInterceptor log = new LogInterceptor(); log.setBody(true); return log; } - private static void initializeGateway(boolean addLoggingInterceptors) throws IOException { - gateway = new HttpRouter(); - gateway.getConfig().setHotDeploy(false); + private void initializeGateway(boolean addLoggingInterceptors) throws IOException { + gateway = new TestRouter(); es = new ElasticSearchExchangeStore(); es.setLocation("http://localhost:3066"); es.setUpdateIntervalMs(100); gateway.setExchangeStore(es); - int index = 4; - if (addLoggingInterceptors) - gateway.getTransport().getFlow().add(index++, createBodyLoggingInterceptor()); - gateway.getTransport().getFlow().add(index++, new ExchangeStoreInterceptor()); - if (addLoggingInterceptors) - gateway.getTransport().getFlow().add(index++, createBodyLoggingInterceptor()); gateway.add(new ServiceProxy(new ServiceProxyKey(3064), "localhost", 3065)); gateway.start(); + var global = new GlobalInterceptor(); + if (addLoggingInterceptors) { + global.getFlow().add(createBodyLoggingInterceptor()); + } + global.getFlow().add(new ExchangeStoreInterceptor()); } - private static void initializeBackend() throws IOException { - back = new HttpRouter(); - back.getConfig().setHotDeploy(false); + private void initializeBackend() throws IOException { + back = new TestRouter(); ServiceProxy sp = new ServiceProxy(new ServiceProxyKey(3065), null, 0); StaticInterceptor si = new StaticInterceptor(); si.setSrc(RESPONSE_BODY); sp.getFlow().add(si); ReturnInterceptor ri = new ReturnInterceptor(); - ri.setStatusCode(200); + ri.setStatus(200); sp.getFlow().add(ri); back.add(sp); back.start(); } - @AfterAll - public static void done() { - back.stop(); - elasticMock.stop(); - } - - private static Interceptor createElasticSearchMockInterceptor() { - ObjectMapper om = new ObjectMapper(); + private Interceptor createElasticSearchMockInterceptor() { return new AbstractInterceptor() { @Override public Outcome handleRequest(Exchange exc) { - if (exc.getRequest().isGETRequest()) { + if (exc.getRequest().isGETRequest() && exc.getRequest().getUri().equals("/membrane/_mapping")) { exc.setResponse(ok(""" - {"acknowledged": true}""").build()); + {"membrane": {"mappings": {"something":true}}}""").build()); return RETURN; } - if (exc.getRequest().getMethod().equals("GET") && exc.getRequest().getUri().equals("/membrane/_mapping")) { + if (exc.getRequest().isGETRequest()) { exc.setResponse(ok(""" - {"membrane": {"mappings": {"something":true}}}""").build()); + {"acknowledged": true}""").build()); return RETURN; } return getOutcome(exc, om); @@ -141,8 +136,8 @@ public Outcome handleRequest(Exchange exc) { }; } - private static @NotNull Outcome getOutcome(Exchange exc, ObjectMapper om) { - if (exc.getRequest().getMethod().equals("POST") && exc.getRequest().getUri().equals("/_bulk")) { + private @NotNull Outcome getOutcome(Exchange exc, ObjectMapper om) { + if (exc.getRequest().isPOSTRequest() && exc.getRequest().getUri().equals("/_bulk")) { for (String line : exc.getRequest().getBodyAsStringDecoded().split("\n")) { try { JsonNode obj = om.readTree(line); @@ -161,9 +156,9 @@ public Outcome handleRequest(Exchange exc) { return RETURN; } - public static List getInsertedObjectsAndClearList() { + public List getInsertedObjectsAndClearList() { synchronized (insertedObjects) { - List insertedObjects1 = new ArrayList(insertedObjects); + List insertedObjects1 = new ArrayList<>(insertedObjects); insertedObjects.clear(); return insertedObjects1; } @@ -183,9 +178,7 @@ private void runTest(boolean addLoggingInterceptors) throws Exception { initializeGateway(addLoggingInterceptors); try (var client = new HttpClient()) { - client.call(Request.post("http://localhost:3064") - .header(AUTHORIZATION, "Demo") - .body(REQUEST_BODY).buildExchange()); + client.call(Request.post("http://localhost:3064").header(AUTHORIZATION, "Demo").body(REQUEST_BODY).buildExchange()); } waitForExchangeStoreToFlush(); @@ -208,17 +201,11 @@ private void runTest(boolean addLoggingInterceptors) throws Exception { assertTrue(insertedObjects.get(1).get("timeResSent").longValue() > 1740000000000L); } - @AfterEach - public void done2() { - gateway.stop(); - } - private void waitForExchangeStoreToFlush() { while (true) { synchronized (es.shortTermMemoryForBatching) { int size = es.shortTermMemoryForBatching.size(); - if (size == 0 && !es.updateThreadWorking) - return; + if (size == 0 && !es.updateThreadWorking) return; } try { //noinspection BusyWait diff --git a/core/src/test/java/com/predic8/membrane/core/graphql/GraphQLProtectionInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/graphql/GraphQLProtectionInterceptorTest.java index 2ebd34b3ef..e4f1bf1f98 100644 --- a/core/src/test/java/com/predic8/membrane/core/graphql/GraphQLProtectionInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/graphql/GraphQLProtectionInterceptorTest.java @@ -13,7 +13,7 @@ limitations under the License. */ package com.predic8.membrane.core.graphql; -import com.predic8.membrane.core.HttpRouter; +import com.predic8.membrane.core.DummyTestRouter; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.graphql.blocklist.FeatureBlocklist; import com.predic8.membrane.core.graphql.blocklist.filters.*; @@ -37,12 +37,12 @@ public class GraphQLProtectionInterceptorTest { private static GraphQLProtectionInterceptor i; - private static HttpRouter router; + private static DummyTestRouter router; @BeforeAll static void init() { - router = new HttpRouter(); + router = new DummyTestRouter(); i = new GraphQLProtectionInterceptor(); i.init(router); } diff --git a/core/src/test/java/com/predic8/membrane/core/graphql/GraphQLoverHttpValidatorTest.java b/core/src/test/java/com/predic8/membrane/core/graphql/GraphQLoverHttpValidatorTest.java index fa0f252397..a55f5784d1 100644 --- a/core/src/test/java/com/predic8/membrane/core/graphql/GraphQLoverHttpValidatorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/graphql/GraphQLoverHttpValidatorTest.java @@ -30,7 +30,7 @@ public class GraphQLoverHttpValidatorTest { @BeforeEach void setup() { - Router router = new Router(); + DefaultRouter router = new DefaultRouter(); validator1 = new GraphQLoverHttpValidator(false, Lists.newArrayList("GET", "POST"), 3, 3, 2, null, router); } diff --git a/core/src/test/java/com/predic8/membrane/core/http/ChunkedBodyTest.java b/core/src/test/java/com/predic8/membrane/core/http/ChunkedBodyTest.java index 0f833435ea..823ba597a4 100644 --- a/core/src/test/java/com/predic8/membrane/core/http/ChunkedBodyTest.java +++ b/core/src/test/java/com/predic8/membrane/core/http/ChunkedBodyTest.java @@ -17,15 +17,14 @@ import com.fasterxml.jackson.databind.*; import com.google.common.io.*; import com.predic8.membrane.core.*; -import com.predic8.membrane.core.config.security.KeyStore; import com.predic8.membrane.core.config.security.*; +import com.predic8.membrane.core.config.security.KeyStore; import com.predic8.membrane.core.exchange.*; import com.predic8.membrane.core.interceptor.*; import com.predic8.membrane.core.proxies.*; import com.predic8.membrane.core.transport.http.*; import com.predic8.membrane.core.transport.http.client.*; -import okhttp3.Call; -import okhttp3.OkHttpClient; +import okhttp3.*; import org.apache.commons.httpclient.methods.*; import org.jetbrains.annotations.*; import org.junit.jupiter.api.*; @@ -42,10 +41,10 @@ import static com.predic8.membrane.core.Constants.*; import static com.predic8.membrane.core.http.ChunkedBody.*; import static com.predic8.membrane.core.http.ChunksBuilder.*; -import static com.predic8.membrane.core.http.Request.get; +import static com.predic8.membrane.core.http.Request.*; import static com.predic8.membrane.core.interceptor.Outcome.*; import static com.predic8.membrane.core.transport.http2.Http2ServerHandler.*; -import static java.lang.Thread.sleep; +import static java.lang.Thread.*; import static java.nio.charset.StandardCharsets.*; import static org.junit.jupiter.api.Assertions.*; @@ -105,7 +104,7 @@ void testReadTrailer() throws Exception { @Test void testWriteTrailer() throws IOException { - HttpRouter router = setupRouter(false, false); + Router router = setupRouter(false, false); try { org.apache.commons.httpclient.HttpClient hc = new org.apache.commons.httpclient.HttpClient(); for (int i = 0; i < 2; i++) { @@ -121,9 +120,9 @@ void testWriteTrailer() throws IOException { } @Test - void testReadWriteTrailerHttp2() throws IOException { - HttpRouter router = setupRouter(false, true); - HttpRouter router2 = setupRouter(true, false); + void readWriteTrailerHttp2() throws IOException { + Router router = setupRouter(false, true); + Router router2 = setupRouter(true, false); try { org.apache.commons.httpclient.HttpClient hc = new org.apache.commons.httpclient.HttpClient(); for (int i = 0; i < 2; i++) { @@ -141,7 +140,7 @@ void testReadWriteTrailerHttp2() throws IOException { @Test void testWriteTrailerHttp2() throws IOException, NoSuchAlgorithmException, KeyManagementException { - HttpRouter router = setupRouter(true, false); + Router router = setupRouter(true, false); try { X509TrustManager trustAll = new X509TrustManager() { @Override @@ -174,7 +173,7 @@ public X509Certificate[] getAcceptedIssuers() { assertEquals("Mon, 12 Dec 2022 09:28:00 GMT", res.trailers().get("Expires")); } } - try(ExecutorService es = hc.dispatcher().executorService()) { + try (ExecutorService es = hc.dispatcher().executorService()) { es.shutdown(); } hc.connectionPool().evictAll(); @@ -183,9 +182,8 @@ public X509Certificate[] getAcceptedIssuers() { } } - private HttpRouter setupRouter(boolean http2, boolean http2Client) { - HttpRouter router = new HttpRouter(); - router.getConfig().setHotDeploy(false); + private Router setupRouter(boolean http2, boolean http2Client) throws IOException { + TestRouter router = new TestRouter(); ServiceProxy sp = new ServiceProxy(new ServiceProxyKey(http2 ? 3060 : 3059), "localhost", 3060); if (http2) { SSLParser sslParser = getSslParserForHttp2(); @@ -193,57 +191,68 @@ private HttpRouter setupRouter(boolean http2, boolean http2Client) { } AtomicReference remoteSocketAddr = new AtomicReference<>(); if (http2Client) { - HTTPClientInterceptor interceptor = (HTTPClientInterceptor) router.getTransport().getFlow().stream().filter(i -> i instanceof HTTPClientInterceptor).findFirst().get(); - HttpClientConfiguration httpClientConfig = new HttpClientConfiguration(); - httpClientConfig.setUseExperimentalHttp2(true); - interceptor.setHttpClientConfig(httpClientConfig); +// HTTPClientInterceptor interceptor = (HTTPClientInterceptor) router.getTransport().getFlow().stream().filter(i -> i instanceof HTTPClientInterceptor).findFirst().get(); +// HttpClientConfiguration httpClientConfig = new HttpClientConfiguration(); +// httpClientConfig.setUseExperimentalHttp2(true); +// interceptor.setHttpClientConfig(httpClientConfig); SSLParser sslParser2 = getSslParserForHttp2Client(); sp.getTarget().setSslParser(sslParser2); } else { - sp.getFlow().add(new AbstractInterceptor() { - @Override - public Outcome handleRequest(Exchange exc) { - String remoteAddr = getRemoteAddr(exc); - if (remoteSocketAddr.get() == null) { - remoteSocketAddr.set(remoteAddr); - } else if (!remoteAddr.equals(remoteSocketAddr.get())) { - throw new RuntimeException("Keep-Alive is not working."); - } + sp.getFlow().add(getInterceptor(http2, remoteSocketAddr)); + } + router.add(sp); + router.start(); + if (http2Client) { + HTTPClientInterceptor interceptor = router.getTransport().getFirstInterceptorOfType(HTTPClientInterceptor.class).orElseThrow(); + HttpClientConfiguration cfg = new HttpClientConfiguration(); + cfg.setUseExperimentalHttp2(true); + interceptor.setHttpClientConfig(cfg); + interceptor.init(); // Copies the config into the HttpClient. It is needed to call because router.start() above already called init() + } + return router; + } - if (http2 && exc.getProperty(HTTP2_SERVER) == null) - throw new RuntimeException("HTTP/2 is not being used."); - if (!http2 && exc.getProperty(HTTP2_SERVER) != null) - throw new RuntimeException("HTTP/2 is being used."); - - Response r = Response.ok().build(); - r.getHeader().removeFields("Content-Length"); - r.getHeader().setValue("Transfer-Encoding", "chunked"); - r.getHeader().setValue("Content-Type", "text/plain"); - r.getHeader().setValue("Trailer", "Expires"); - r.setBody(new ChunkedBody(new ByteArrayInputStream(getContent()))); - exc.setResponse(r); - return RETURN; + private static @NotNull AbstractInterceptor getInterceptor(boolean http2, AtomicReference remoteSocketAddr) { + return new AbstractInterceptor() { + @Override + public Outcome handleRequest(Exchange exc) { + String remoteAddr = getRemoteAddr(exc); + if (remoteSocketAddr.get() == null) { + remoteSocketAddr.set(remoteAddr); + } else if (!remoteAddr.equals(remoteSocketAddr.get())) { + throw new RuntimeException("Keep-Alive is not working."); } - private static String getRemoteAddr(Exchange exc) { - return ((HttpServerHandler) exc.getHandler()).getSourceSocket().getRemoteSocketAddress().toString(); - } + if (http2 && exc.getProperty(HTTP2_SERVER) == null) + throw new RuntimeException("HTTP/2 is not being used."); + if (!http2 && exc.getProperty(HTTP2_SERVER) != null) + throw new RuntimeException("HTTP/2 is being used."); + + Response r = Response.ok().build(); + r.getHeader().removeFields("Content-Length"); + r.getHeader().setValue("Transfer-Encoding", "chunked"); + r.getHeader().setValue("Content-Type", "text/plain"); + r.getHeader().setValue("Trailer", "Expires"); + r.setBody(new ChunkedBody(new ByteArrayInputStream(getContent()))); + exc.setResponse(r); + return RETURN; + } - private static byte[] getContent() { - String cont; - try { - cont = Resources.toString(getResource("chunked-body-with-trailer.txt"), US_ASCII); - } catch (IOException e) { - throw new RuntimeException(e); - } - cont = cont.replaceAll("\n", "").replaceAll("\r", "").replaceAll("\\\\n", "\n").replaceAll("\\\\r", "\r"); - return cont.getBytes(US_ASCII); + private static String getRemoteAddr(Exchange exc) { + return ((HttpServerHandler) exc.getHandler()).getSourceSocket().getRemoteSocketAddress().toString(); + } + + private static byte[] getContent() { + String cont; + try { + cont = Resources.toString(getResource("chunked-body-with-trailer.txt"), US_ASCII); + } catch (IOException e) { + throw new RuntimeException(e); } - }); - } - router.getRules().add(sp); - router.start(); - return router; + cont = cont.replaceAll("\n", "").replaceAll("\r", "").replaceAll("\\\\n", "\n").replaceAll("\\\\r", "\r"); + return cont.getBytes(US_ASCII); + } + }; } private static @NotNull SSLParser getSslParserForHttp2() { @@ -285,7 +294,7 @@ void readTrailerTest() throws IOException { ByteArrayInputStream is = new ByteArrayInputStream(trailer); assertEquals(61, readChunkSize(is)); // 3D = 61 readTrailer(is); - assertEquals( 0,is.available()); // Check that everything is read + assertEquals(0, is.available()); // Check that everything is read } @Test @@ -306,7 +315,7 @@ void readStream() throws IOException { // 0 + CRLF + CRLF is not read yet assertFalse(cb.read); - if(!(is instanceof BodyInputStream bodyIs)) { + if (!(is instanceof BodyInputStream bodyIs)) { fail(); return; } @@ -329,7 +338,7 @@ void readStreamRepeatedly() throws IOException { // Re-Read JSON from the body (both reads will leave the final end-chunk unread) assertEquals(42, om.readTree(cb.getContentAsStream()).get("foo").asInt()); - if(!(cb.getContentAsStream() instanceof BodyInputStream bodyIs)) { + if (!(cb.getContentAsStream() instanceof BodyInputStream bodyIs)) { fail(); return; } @@ -374,7 +383,7 @@ void readStreamWith2ConcatenatedJSON() throws IOException { // Read the second JSON from the body assertEquals(43, om.readTree(is).get("foo").asInt()); - if(!(is instanceof BodyInputStream bodyIs)) { + if (!(is instanceof BodyInputStream bodyIs)) { fail(); return; } diff --git a/core/src/test/java/com/predic8/membrane/core/http/Http10Test.java b/core/src/test/java/com/predic8/membrane/core/http/Http10Test.java index 1c526036eb..fd1e4801bf 100644 --- a/core/src/test/java/com/predic8/membrane/core/http/Http10Test.java +++ b/core/src/test/java/com/predic8/membrane/core/http/Http10Test.java @@ -28,28 +28,29 @@ import static org.apache.http.params.CoreProtocolPNames.*; import static org.junit.jupiter.api.Assertions.*; -@SuppressWarnings("deprecation") public class Http10Test { - private static HttpRouter router; - private static HttpRouter router2; + private static DefaultRouter router; + private static DefaultRouter router2; @BeforeAll public static void setUp() throws Exception { ServiceProxy proxy2 = new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", 2000), null, 0); proxy2.getFlow().add(new SampleSoapServiceInterceptor()); - router2 = new HttpRouter(); - router2.getRuleManager().addProxyAndOpenPortIfNew(proxy2); - router2.init(); + router2 = new TestRouter(); + router2.add(proxy2); + ServiceProxy proxy = new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", 3000), "localhost", 2000); - router = new HttpRouter(); - router.getRuleManager().addProxyAndOpenPortIfNew(proxy); - router.init(); + router = new TestRouter(); + router.add(proxy); + + router2.start(); + router.start(); } @AfterAll public static void tearDown() { - router2.shutdown(); - router.shutdown(); + router2.stop(); + router.stop(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/http/Http11Test.java b/core/src/test/java/com/predic8/membrane/core/http/Http11Test.java index 74eea0a0d7..bd4ceeca97 100644 --- a/core/src/test/java/com/predic8/membrane/core/http/Http11Test.java +++ b/core/src/test/java/com/predic8/membrane/core/http/Http11Test.java @@ -30,8 +30,8 @@ public class Http11Test { - private static HttpRouter router; - private static HttpRouter router2; + private static Router router; + private static Router router2; private static int port4k; @BeforeAll @@ -40,19 +40,19 @@ public static void setUp() throws Exception { int port5k = getFreePortEqualAbove(5000); ServiceProxy proxy2 = new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", port5k), null, 0); proxy2.getFlow().add(new SampleSoapServiceInterceptor()); - router2 = new HttpRouter(); - router2.getRuleManager().addProxyAndOpenPortIfNew(proxy2); - router2.init(); + router2 = new TestRouter(); + router2.add(proxy2); + router2.start(); ServiceProxy proxy = new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", port4k), "localhost", port5k); - router = new HttpRouter(); - router.getRuleManager().addProxyAndOpenPortIfNew(proxy); - router.init(); + router = new TestRouter(); + router.add(proxy); + router.start(); } @AfterAll public static void tearDown() { - router2.shutdown(); - router.shutdown(); + router2.stop(); + router.stop(); } /** diff --git a/core/src/test/java/com/predic8/membrane/core/http/MethodTest.java b/core/src/test/java/com/predic8/membrane/core/http/MethodTest.java index baabe75daf..0346bd2d47 100644 --- a/core/src/test/java/com/predic8/membrane/core/http/MethodTest.java +++ b/core/src/test/java/com/predic8/membrane/core/http/MethodTest.java @@ -27,7 +27,7 @@ public class MethodTest { - private static HttpRouter router; + private static Router router; @BeforeAll public static void setUp() throws Exception { @@ -43,14 +43,14 @@ public Outcome handleRequest(Exchange exc) { } }); proxy.getFlow().add(new ExceptionTestInterceptor()); // Cause exception - router = new HttpRouter(); - router.getRuleManager().addProxyAndOpenPortIfNew(proxy); - router.init(); + router = new TestRouter(); + router.add(proxy); + router.start(); } @AfterAll public static void tearDown() { - router.shutdown(); + router.stop(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/AdjustContentLengthTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/AdjustContentLengthTest.java index f07822ae75..1750688145 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/AdjustContentLengthTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/AdjustContentLengthTest.java @@ -30,15 +30,15 @@ public class AdjustContentLengthTest { @BeforeAll public static void setUp() throws Exception { - router = new HttpRouter(); - router.getRuleManager().addProxyAndOpenPortIfNew(createMonitorRule()); - router.getRuleManager().addProxyAndOpenPortIfNew(createEndpointRule()); - router.init(); + router = new TestRouter(); + router.add(createMonitorRule()); + router.add(createEndpointRule()); + router.start(); } @AfterAll public static void tearDown() { - router.shutdown(); + router.stop(); } private static ServiceProxy createMonitorRule() { diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/ApisJsonInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/ApisJsonInterceptorTest.java index c193729924..06310ba187 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/ApisJsonInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/ApisJsonInterceptorTest.java @@ -14,8 +14,8 @@ package com.predic8.membrane.core.interceptor; import com.fasterxml.jackson.databind.JsonNode; -import com.predic8.membrane.core.Router; -import com.predic8.membrane.core.RuleManager; +import com.predic8.membrane.core.*; +import com.predic8.membrane.core.DefaultRouter; import com.predic8.membrane.core.config.Path; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Request.Builder; @@ -51,7 +51,7 @@ static void setUp() throws ParseException { @Test void responseTest() throws Exception { Exchange exc = new Builder().buildExchange(); - Router r = mock(Router.class); + DefaultRouter r = mock(DefaultRouter.class); RuleManager rm = mock(RuleManager.class); APIProxy apiProxy = new APIProxy() {{ setPath(new Path(false, "/baz")); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/DispatchingInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/DispatchingInterceptorTest.java index 326153d35a..c3bc1210d3 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/DispatchingInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/DispatchingInterceptorTest.java @@ -40,7 +40,7 @@ class DispatchingInterceptorTest { @BeforeEach void setUp() { - Router router = new Router(); + DefaultRouter router = new DefaultRouter(); dispatcher = new DispatchingInterceptor(); dispatcher.init(router); exc = new Exchange(null); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/HTTPClientInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/HTTPClientInterceptorTest.java index 99181ba0a1..41e5e77b2b 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/HTTPClientInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/HTTPClientInterceptorTest.java @@ -36,7 +36,7 @@ void setUp() { @Test void protocolUpgradeRejected() throws URISyntaxException { - Router r = new Router(); + DefaultRouter r = new DefaultRouter(); hci.init(r); @@ -53,14 +53,14 @@ void protocolUpgradeRejected() throws URISyntaxException { @Test void passFailOverOn500Default() { - hci.init(new Router()); + hci.init(new DefaultRouter()); assertFalse(hci.getHttpClientConfig().getRetryHandler().isFailOverOn5XX()); } @Test void passFailOverOn500() { hci.setFailOverOn5XX(true); - hci.init(new Router()); + hci.init(new DefaultRouter()); assertTrue(hci.getHttpClientConfig().getRetryHandler().isFailOverOn5XX()); } diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/InternalInvocationTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/InternalInvocationTest.java index a2b4e7ecc7..cab1540c38 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/InternalInvocationTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/InternalInvocationTest.java @@ -22,11 +22,11 @@ public class InternalInvocationTest { - private Router router; + private DefaultRouter router; @BeforeEach public void setUp() throws Exception { - router = Router.init("classpath:/internal-invocation/proxies.xml"); + router = RouterXmlBootstrap.initByXML("classpath:/internal-invocation/proxies.xml"); MockInterceptor.clear(); } @@ -52,7 +52,7 @@ void returnedChain() throws Exception { @AfterEach public void tearDown() throws Exception { - router.shutdown(); + router.stop(); } private void callService(int port) throws IOException { diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/RegExReplaceInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/RegExReplaceInterceptorTest.java index 53ecdd7a78..5ca0788fec 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/RegExReplaceInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/RegExReplaceInterceptorTest.java @@ -34,7 +34,7 @@ void setUp() { interceptor = new RegExReplaceInterceptor(); interceptor.setRegex("\\bb.*?\\b"); interceptor.setReplace("boo"); - interceptor.init(new Router()); + interceptor.init(new DefaultRouter()); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/UserFeatureTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/UserFeatureTest.java index f89ac993cf..36bde9948f 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/UserFeatureTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/UserFeatureTest.java @@ -30,13 +30,13 @@ class UserFeatureTest { public static final String MOCK_5 = "mock5"; public static final String MOCK_6 = "mock6"; public static final String MOCK_2 = "mock2"; - private static Router router; + private static DefaultRouter router; static List labels, inverseLabels, inversAbortLabels; @BeforeAll static void setUp() { - router = Router.init("classpath:/userFeature/proxies.xml"); + router = RouterXmlBootstrap.initByXML("classpath:/userFeature/proxies.xml"); MockInterceptor.clear(); } @@ -49,8 +49,8 @@ void beforeEach() { } @AfterAll - static void tearDown() throws Exception { - router.shutdown(); + static void tearDown() { + router.stop(); } private void callService(String s) { @@ -60,19 +60,19 @@ private void callService(String s) { } @Test - void testInvocation() throws Exception { + void testInvocation() { callService("ok"); MockInterceptor.assertContent(labels, inverseLabels, new ArrayList<>()); } @Test - void testAbort() throws Exception { + void testAbort() { callService("abort"); MockInterceptor.assertContent(labels, new ArrayList<>(), inversAbortLabels); } @Test - void testFailInRequest() throws Exception { + void testFailInRequest() { labels.add("mock8"); callService("failinrequest"); @@ -80,7 +80,7 @@ void testFailInRequest() throws Exception { } @Test - void testFailInResponse() throws Exception { + void testFailInResponse() { labels.add("mock9"); callService("failinresponse"); @@ -88,9 +88,9 @@ void testFailInResponse() throws Exception { } @Test - void testFailInAbort() throws Exception { + void testFailInAbort() { labels.add("mock10"); - inversAbortLabels.add(0, "mock10"); + inversAbortLabels.addFirst("mock10"); callService("failinabort"); MockInterceptor.assertContent(labels, new ArrayList<>(), inversAbortLabels); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/acl/AccessControlParserTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/acl/AccessControlParserTest.java index 4a54f9743e..e82de42f07 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/acl/AccessControlParserTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/acl/AccessControlParserTest.java @@ -18,7 +18,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import com.predic8.membrane.core.HttpRouter; +import com.predic8.membrane.core.DummyTestRouter; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -34,7 +34,7 @@ public class AccessControlParserTest { @BeforeAll protected static void setUp() throws Exception { - resources = new AccessControlInterceptor().parse(FILE_NAME, new HttpRouter()).getResources(); + resources = new AccessControlInterceptor().parse(FILE_NAME, new DummyTestRouter()).getResources(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/acl/HostnameTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/acl/HostnameTest.java index fca0675f0d..316682c02b 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/acl/HostnameTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/acl/HostnameTest.java @@ -20,14 +20,14 @@ public class HostnameTest { - static Router router; + static DefaultRouter router; static Hostname h1; static Hostname h2; @BeforeAll public static void setUp() throws Exception { - router = new Router(); + router = new DefaultRouter(); h1 = new Hostname(router); h1.setSchema("^localhost$"); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/adminapi/AdminApiInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/adminapi/AdminApiInterceptorTest.java index faf46879c2..3f9e7e1a7b 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/adminapi/AdminApiInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/adminapi/AdminApiInterceptorTest.java @@ -13,46 +13,40 @@ limitations under the License. */ package com.predic8.membrane.core.interceptor.adminapi; -import com.predic8.membrane.core.HttpRouter; -import com.predic8.membrane.core.exchange.Exchange; -import com.predic8.membrane.core.http.Request; -import com.predic8.membrane.core.interceptor.AbstractInterceptor; -import com.predic8.membrane.core.interceptor.Outcome; -import com.predic8.membrane.core.proxies.NullProxy; -import com.predic8.membrane.core.proxies.ServiceProxy; -import com.predic8.membrane.core.proxies.ServiceProxyKey; -import com.predic8.membrane.core.transport.http.FakeHttpHandler; -import com.predic8.membrane.core.transport.http.HttpClient; -import com.predic8.membrane.core.transport.http.TwoWayStreaming; -import com.predic8.membrane.core.transport.ws.WebSocketFrameAssembler; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; +import com.predic8.membrane.core.*; +import com.predic8.membrane.core.exchange.*; +import com.predic8.membrane.core.exchangestore.*; +import com.predic8.membrane.core.http.*; +import com.predic8.membrane.core.interceptor.*; +import com.predic8.membrane.core.proxies.*; +import com.predic8.membrane.core.transport.http.*; +import com.predic8.membrane.core.transport.ws.*; +import org.junit.jupiter.api.*; import java.io.*; -import java.net.SocketException; -import java.net.URISyntaxException; -import java.util.concurrent.atomic.AtomicBoolean; +import java.net.*; +import java.util.concurrent.atomic.*; -import static com.predic8.membrane.core.exchange.Exchange.ALLOW_WEBSOCKET; +import static com.predic8.membrane.core.exchange.Exchange.*; import static com.predic8.membrane.core.http.Header.*; -import static com.predic8.membrane.core.transport.ws.WebSocketConnection.WEBSOCKET_CLOSED_POLL_INTERVAL_MILLISECONDS; +import static com.predic8.membrane.core.interceptor.Outcome.CONTINUE; +import static com.predic8.membrane.core.transport.ws.WebSocketConnection.*; import static org.junit.jupiter.api.Assertions.*; class AdminApiInterceptorTest { - private static HttpRouter router; + private static Router router; @BeforeAll - static void setUp() { - router = new HttpRouter(); - router.getConfig().setHotDeploy(false); + static void setUp() throws IOException { + router = new TestRouter(); + router.setExchangeStore(new LimitedMemoryExchangeStore()); // Needed by the AdminApiInterceptor ServiceProxy sp = new ServiceProxy(new ServiceProxyKey(3065), null, 0); sp.getFlow().add(new FastWebSocketClosingInterceptor()); // speeds up test execution AdminApiInterceptor e = new AdminApiInterceptor(); e.getMemoryWatcher().setIntervalMilliseconds(50); // speeds up test execution sp.getFlow().add(e); - router.getRules().add(sp); + router.add(sp); router.start(); } @@ -62,7 +56,7 @@ static void tearDown() { } @Test - public void testWebSocket() throws Exception { + void webSocket() throws Exception { try (HttpClient client = new HttpClient()) { var testHandler = new TestHandler(); var exc = createWSRequest(testHandler); @@ -120,7 +114,7 @@ private static class TestHandler extends FakeHttpHandler implements TwoWayStream private final NotifyingByteArrayOutputStream outputStream = new NotifyingByteArrayOutputStream(); private InputStream inputStream = new InputStream() { @Override - public int read() throws IOException { + public int read() { while (!closed) { synchronized (TestHandler.this) { try { @@ -154,7 +148,7 @@ public String getRemoteDescription() { } @Override - public void removeSocketSoTimeout() throws SocketException { + public void removeSocketSoTimeout() { // do nothing } @@ -164,7 +158,7 @@ public boolean isClosed() { } @Override - public void close() throws IOException { + public void close() { closed = true; synchronized (this) { notifyAll(); @@ -176,7 +170,7 @@ private static class FastWebSocketClosingInterceptor extends AbstractInterceptor @Override public Outcome handleRequest(Exchange exc) { exc.setProperty(WEBSOCKET_CLOSED_POLL_INTERVAL_MILLISECONDS, 10); // speeds up test execution - return Outcome.CONTINUE; + return CONTINUE; } } } \ No newline at end of file diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/apikey/ApiKeysInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/apikey/ApiKeysInterceptorTest.java index e3a4f3c8f5..4e31e2d004 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/apikey/ApiKeysInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/apikey/ApiKeysInterceptorTest.java @@ -13,7 +13,7 @@ limitations under the License. */ package com.predic8.membrane.core.interceptor.apikey; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.interceptor.apikey.extractors.ApiKeyExpressionExtractor; import com.predic8.membrane.core.interceptor.apikey.extractors.ApiKeyHeaderExtractor; @@ -57,17 +57,17 @@ public class ApiKeysInterceptorTest { static void setup() { store = new ApiKeyFileStore(); store.setLocation(getKeyfilePath("apikeys/keys.txt")); - store.init(new Router()); + store.init(new DummyTestRouter()); mergeStore = new ApiKeyFileStore(); mergeStore.setLocation(getKeyfilePath("apikeys/merge-keys.txt")); - mergeStore.init(new Router()); + mergeStore.init(new DummyTestRouter()); ahe = new ApiKeyHeaderExtractor(); aqe = new ApiKeyQueryParamExtractor(); aee = new ApiKeyExpressionExtractor(); aee.setExpression("json['api-key']"); - aee.init(new Router()); + aee.init(new DummyTestRouter()); akiWithProp = new ApiKeysInterceptor(); akiWithProp.setExtractors(of(ahe)); @@ -169,7 +169,7 @@ void handleUnauthorizedKey() { void handleDuplicateApiKeys() { var dupeStore = new ApiKeyFileStore(); dupeStore.setLocation(getKeyfilePath("apikeys/duplicate-api-keys.txt")); - assertThrows(RuntimeException.class, () -> dupeStore.init(new Router())); + assertThrows(RuntimeException.class, () -> dupeStore.init(new DummyTestRouter())); } private static String getKeyfilePath(String name) { diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/apikey/stores/ApiKeyFileStoreTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/apikey/stores/ApiKeyFileStoreTest.java index a701d45012..6eedee2630 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/apikey/stores/ApiKeyFileStoreTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/apikey/stores/ApiKeyFileStoreTest.java @@ -100,7 +100,7 @@ void parseValues() { private static void loadFromFile(ApiKeyFileStore store, String path) { store.setLocation(requireNonNull(ApiKeyFileStoreTest.class.getClassLoader().getResource(path)).getPath()); - store.init(new Router()); + store.init(new DummyTestRouter()); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/authentication/BasicAuthenticationInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/authentication/BasicAuthenticationInterceptorTest.java index 586212d4d7..c7f4416640 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/authentication/BasicAuthenticationInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/authentication/BasicAuthenticationInterceptorTest.java @@ -39,7 +39,7 @@ static void setup() { new User("admin", "admin"), new User("admin", "$6$12345678$jwCsYagMo/KNcTDqnrWL25Dy3AfAT5U94abA5a/iPFO.Cx2zAkMpPxZBNKY/P/xiRrCfCFDxdBp7pvNEMoBcr0") )); - bai.init(new Router()); + bai.init(new DefaultRouter()); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/ClusterBalancerTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/ClusterBalancerTest.java index 7b303929ed..bc3f919ec5 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/ClusterBalancerTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/ClusterBalancerTest.java @@ -33,13 +33,13 @@ public class ClusterBalancerTest { private static Router r; @BeforeAll - public static void setUp() throws Exception { + static void setUp() throws Exception { extractor = new XMLElementSessionIdExtractor(); extractor.setLocalName("session"); extractor.setNamespace("http://predic8.com/session/"); - r = new HttpRouter(); + r = new DummyTestRouter(); lb = new LoadBalancingInterceptor(); lb.setSessionIdExtractor(extractor); @@ -47,7 +47,7 @@ public static void setUp() throws Exception { ServiceProxy sp = new ServiceProxy(new ServiceProxyKey(3011), "predic8.com", 80); sp.getFlow().add(lb); - r.getRuleManager().addProxyAndOpenPortIfNew(sp); + r.add(sp); r.init(); BalancerUtil.up(r, "Default", "Default", "localhost", 2000); @@ -55,12 +55,12 @@ public static void setUp() throws Exception { } @AfterAll - public static void tearDown() throws Exception { - r.shutdown(); + static void tearDown() { + r.stop(); } @Test - public void testClusterBalancerRequest() throws Exception { + void clusterBalancerRequest() throws Exception { Exchange exc = getExchangeWithSession(); lb.handleRequest(exc); @@ -108,7 +108,7 @@ public void testClusterBalancerNoSessionRequestResponse() throws Exception { } @Test - public void testNoNodeFound() throws Exception { + void noNodeFound() throws Exception { Exchange exc = getExchangeWithOutSession(); BalancerUtil.down(r, "Default", "Default", "localhost", 2000); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/ClusterNotificationInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/ClusterNotificationInterceptorTest.java index 0c0e47fdfe..4a306b92cb 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/ClusterNotificationInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/ClusterNotificationInterceptorTest.java @@ -14,6 +14,7 @@ package com.predic8.membrane.core.interceptor.balancer; import com.predic8.membrane.core.*; +import com.predic8.membrane.core.interceptor.*; import com.predic8.membrane.core.proxies.*; import org.apache.commons.codec.*; import org.apache.commons.codec.binary.*; @@ -21,6 +22,7 @@ import org.apache.commons.httpclient.methods.*; import org.jetbrains.annotations.*; import org.junit.jupiter.api.*; +import org.mockito.internal.configuration.*; import javax.crypto.*; import javax.crypto.spec.*; @@ -35,29 +37,31 @@ import static org.junit.jupiter.api.Assertions.*; public class ClusterNotificationInterceptorTest { - private HttpRouter router; + private TestRouter router; private ClusterNotificationInterceptor interceptor; @BeforeEach public void setUp() throws Exception { ServiceProxy proxy = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", 3002), "thomas-bayer.com", 80); - router = new HttpRouter(); - router.getRuleManager().addProxyAndOpenPortIfNew(proxy); + router = new TestRouter(); + router.add(proxy); interceptor = new ClusterNotificationInterceptor(); - router.addUserFeatureInterceptor(interceptor); + var global = new GlobalInterceptor(); + global.getFlow().add(interceptor); + router.getRegistry().register("global", global); LoadBalancingInterceptor lbi = new LoadBalancingInterceptor(); lbi.setName("Default"); ServiceProxy proxy2 = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", 3003), "thomas-bayer.com", 80); - router.getRuleManager().addProxyAndOpenPortIfNew(proxy2); + router.add(proxy2); proxy2.getFlow().add(lbi); - router.init(); + router.start(); } @AfterEach public void tearDown() { - router.shutdown(); + router.stop(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/LoadBalancingWithClusterManagerAndNoSessionTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/LoadBalancingWithClusterManagerAndNoSessionTest.java index 0fe2649d4d..5836a04b50 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/LoadBalancingWithClusterManagerAndNoSessionTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/LoadBalancingWithClusterManagerAndNoSessionTest.java @@ -16,8 +16,7 @@ import com.predic8.membrane.interceptor.LoadBalancingInterceptorTest; import org.junit.jupiter.api.BeforeEach; -public class LoadBalancingWithClusterManagerAndNoSessionTest extends -LoadBalancingInterceptorTest { +public class LoadBalancingWithClusterManagerAndNoSessionTest extends LoadBalancingInterceptorTest { @BeforeEach public void setUp() throws Exception { diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/LoadBalancingWithClusterManagerTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/LoadBalancingWithClusterManagerTest.java index 12612e0667..0c81fa871a 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/LoadBalancingWithClusterManagerTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/LoadBalancingWithClusterManagerTest.java @@ -14,10 +14,12 @@ package com.predic8.membrane.core.interceptor.balancer; import com.predic8.membrane.core.*; +import com.predic8.membrane.core.interceptor.*; import com.predic8.membrane.core.proxies.*; import com.predic8.membrane.core.services.*; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.*; +import org.jetbrains.annotations.*; import org.junit.jupiter.api.*; import java.io.*; @@ -30,122 +32,129 @@ public class LoadBalancingWithClusterManagerTest { - private static HttpRouter lb; - private static HttpRouter node1; - private static HttpRouter node2; - private static HttpRouter node3; - - @Test - void nodesTest() throws Exception { - node1 = new HttpRouter(); - node2 = new HttpRouter(); - node3 = new HttpRouter(); - - DummyWebServiceInterceptor service1 = startNode(node1, 2000); - DummyWebServiceInterceptor service2 = startNode(node2, 3000); - DummyWebServiceInterceptor service3 = startNode(node3, 4000); - - startLB(); - - sendNotification("up", 2000); - sendNotification("up", 3000); - - assertEquals(200, post("/getBankwithSession555555.xml"));// goes to service one - assertEquals(1, service1.getCount()); - assertEquals(0, service2.getCount()); - - assertEquals(200, post("/getBankwithSession555555.xml"));// goes to service 1 again - assertEquals(2, service1.getCount()); - assertEquals(0, service2.getCount()); - - assertEquals(200, post("/getBankwithSession444444.xml")); // goes to service 2 - assertEquals(2, service1.getCount()); - assertEquals(1, service2.getCount()); - - sendNotification("down", 2000); - - assertEquals(200, post("/getBankwithSession555555.xml")); // goes to service 2 because service 1 is down - assertEquals(2, service1.getCount()); - assertEquals(2, service2.getCount()); - - sendNotification("up", 4000); - - assertEquals(0, service3.getCount()); - assertEquals(200, post("/getBankwithSession666666.xml")); // goes to service 3 - assertEquals(2, service1.getCount()); - assertEquals(2, service2.getCount()); - assertEquals(1, service3.getCount()); - - assertEquals(200, post("/getBankwithSession555555.xml")); // goes to service 2 - assertEquals(200, post("/getBankwithSession444444.xml")); // goes to service 2 - assertEquals(200, post("/getBankwithSession666666.xml")); // goes to service 3 - assertEquals(2, service1.getCount()); - assertEquals(4, service2.getCount()); - assertEquals(2, service3.getCount()); - } - - @AfterAll - public static void tearDown() { - lb.shutdown(); - node1.shutdown(); - node2.shutdown(); - node3.shutdown(); - } - - private void startLB() throws Exception { - - LoadBalancingInterceptor lbi = new LoadBalancingInterceptor(); - lbi.setName("Default"); - XMLElementSessionIdExtractor extractor = new XMLElementSessionIdExtractor(); - extractor.setLocalName("session"); - extractor.setNamespace("http://predic8.com/session/"); - lbi.setSessionIdExtractor(extractor); - - ServiceProxy lbiRule = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", 3017), "thomas-bayer.com", 80); - lbiRule.getFlow().add(lbi); - - ClusterNotificationInterceptor cni = new ClusterNotificationInterceptor(); - - ServiceProxy cniRule = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", 3012), "thomas-bayer.com", 80); - cniRule.getFlow().add(cni); - - lb = new HttpRouter(); - lb.getRuleManager().addProxyAndOpenPortIfNew(lbiRule); - lb.getRuleManager().addProxyAndOpenPortIfNew(cniRule); - lb.init(); - } - - private DummyWebServiceInterceptor startNode(HttpRouter node, int port) throws Exception { - DummyWebServiceInterceptor service1 = new DummyWebServiceInterceptor(); - node.addUserFeatureInterceptor(service1); - node.getRuleManager().addProxyAndOpenPortIfNew(new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", port), "thomas-bayer.com", 80)); - node.init(); - return service1; - } - - private HttpClient getClient() { - HttpClient client = new HttpClient(); - client.getParams().setParameter(PROTOCOL_VERSION, HttpVersion.HTTP_1_1); - return client; - } - - private PostMethod getPostMethod(String request) { - PostMethod post = new PostMethod("http://localhost:3017/axis2/services/BLZService"); - post.setRequestEntity(new InputStreamRequestEntity(this.getClass().getResourceAsStream(request))); - post.setRequestHeader(CONTENT_TYPE, TEXT_XML_UTF8); - post.setRequestHeader(SOAP_ACTION, ""); - return post; - } - - private void sendNotification(String cmd, int port) throws IOException { - PostMethod post = new PostMethod("http://localhost:3012/clustermanager/"+cmd+"?"+ - createQueryString("host", "localhost", - "port", String.valueOf(port))); - new HttpClient().executeMethod(post); - } - - private int post(String req) throws IOException { - return getClient().executeMethod(getPostMethod(req)); - } + private Router lb; + private DefaultRouter node1; + private DefaultRouter node2; + private DefaultRouter node3; + + @AfterEach + public void tearDown() { + lb.stop(); + node1.stop(); + node2.stop(); + node3.stop(); + } + + @Test + void nodesTest() throws Exception { + node1 = createRouter(); + node2 = createRouter(); + node3 = createRouter(); + + DummyWebServiceInterceptor service1 = startNode(node1, 2000); + DummyWebServiceInterceptor service2 = startNode(node2, 3000); + DummyWebServiceInterceptor service3 = startNode(node3, 4000); + + startLB(); + + sendNotification("up", 2000); + sendNotification("up", 3000); + + assertEquals(200, post("/getBankwithSession555555.xml"));// goes to service one + assertEquals(1, service1.getCount()); + assertEquals(0, service2.getCount()); + + assertEquals(200, post("/getBankwithSession555555.xml"));// goes to service 1 again + assertEquals(2, service1.getCount()); + assertEquals(0, service2.getCount()); + + assertEquals(200, post("/getBankwithSession444444.xml")); // goes to service 2 + assertEquals(2, service1.getCount()); + assertEquals(1, service2.getCount()); + + sendNotification("down", 2000); + + assertEquals(200, post("/getBankwithSession555555.xml")); // goes to service 2 because service 1 is down + assertEquals(2, service1.getCount()); + assertEquals(2, service2.getCount()); + + sendNotification("up", 4000); + + assertEquals(0, service3.getCount()); + assertEquals(200, post("/getBankwithSession666666.xml")); // goes to service 3 + assertEquals(2, service1.getCount()); + assertEquals(2, service2.getCount()); + assertEquals(1, service3.getCount()); + + assertEquals(200, post("/getBankwithSession555555.xml")); // goes to service 2 + assertEquals(200, post("/getBankwithSession444444.xml")); // goes to service 2 + assertEquals(200, post("/getBankwithSession666666.xml")); // goes to service 3 + assertEquals(2, service1.getCount()); + assertEquals(4, service2.getCount()); + assertEquals(2, service3.getCount()); + } + + private static @NotNull DefaultRouter createRouter() { + DefaultRouter node1 = new TestRouter(); + node1.getRegistry().register("global", new GlobalInterceptor()); + return node1; + } + + private void startLB() throws Exception { + + LoadBalancingInterceptor lbi = new LoadBalancingInterceptor(); + lbi.setName("Default"); + XMLElementSessionIdExtractor extractor = new XMLElementSessionIdExtractor(); + extractor.setLocalName("session"); + extractor.setNamespace("http://predic8.com/session/"); + lbi.setSessionIdExtractor(extractor); + + ServiceProxy lbiRule = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", 3017), "thomas-bayer.com", 80); + lbiRule.getFlow().add(lbi); + + ClusterNotificationInterceptor cni = new ClusterNotificationInterceptor(); + + ServiceProxy cniRule = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", 3012), "thomas-bayer.com", 80); + cniRule.getFlow().add(cni); + + lb = new DefaultRouter(); + lb.add(lbiRule); + lb.add(cniRule); + lb.start(); + } + + private DummyWebServiceInterceptor startNode(DefaultRouter node, int port) throws Exception { + DummyWebServiceInterceptor service1 = new DummyWebServiceInterceptor(); + var global = node.getRegistry().getBean(GlobalInterceptor.class); + global.orElseThrow().getFlow().add(service1); + node.add(new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", port), "thomas-bayer.com", 80)); + node.start(); + return service1; + } + + private HttpClient getClient() { + HttpClient client = new HttpClient(); + client.getParams().setParameter(PROTOCOL_VERSION, HttpVersion.HTTP_1_1); + return client; + } + + private PostMethod getPostMethod(String request) { + PostMethod post = new PostMethod("http://localhost:3017/axis2/services/BLZService"); + post.setRequestEntity(new InputStreamRequestEntity(this.getClass().getResourceAsStream(request))); + post.setRequestHeader(CONTENT_TYPE, TEXT_XML_UTF8); + post.setRequestHeader(SOAP_ACTION, ""); + return post; + } + + private void sendNotification(String cmd, int port) throws IOException { + PostMethod post = new PostMethod("http://localhost:3012/clustermanager/" + cmd + "?" + + createQueryString("host", "localhost", + "port", String.valueOf(port))); + new HttpClient().executeMethod(post); + } + + private int post(String req) throws IOException { + return getClient().executeMethod(getPostMethod(req)); + } } diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/PolyglotSessionIdExtractorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/PolyglotSessionIdExtractorTest.java index 34f96882c3..d333a0b5b2 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/PolyglotSessionIdExtractorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/balancer/PolyglotSessionIdExtractorTest.java @@ -13,7 +13,7 @@ limitations under the License. */ package com.predic8.membrane.core.interceptor.balancer; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.DefaultRouter; import com.predic8.membrane.core.http.Header; import com.predic8.membrane.core.http.Request; import com.predic8.membrane.core.http.Response; @@ -35,7 +35,7 @@ static void setup() { extractor = new PolyglotSessionIdExtractor(); extractor.setLanguage(SPEL); extractor.setSessionSource("headers['%s']".formatted(X_SESSION)); - extractor.init(new Router()); + extractor.init(new DefaultRouter()); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/flow/ConditionalEvaluationTestContext.java b/core/src/test/java/com/predic8/membrane/core/interceptor/flow/ConditionalEvaluationTestContext.java index fe1c881b43..f3d9ea15b2 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/flow/ConditionalEvaluationTestContext.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/flow/ConditionalEvaluationTestContext.java @@ -40,7 +40,7 @@ static Outcome performEval(String condition, Object builder, Language lang, bool ifInt.setLanguage(lang); ifInt.setFlow(of(mockInt)); ifInt.setTest(condition); - ifInt.init(new HttpRouter()); + ifInt.init(new DummyTestRouter()); Outcome outcome; if (builder instanceof Builder b) { diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/flow/IfInterceptorSpELTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/flow/IfInterceptorSpELTest.java index def12abfb2..e1e547832a 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/flow/IfInterceptorSpELTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/flow/IfInterceptorSpELTest.java @@ -31,16 +31,16 @@ public class IfInterceptorSpELTest extends ConditionalEvaluationTestContext { - static Router router; + static DefaultRouter router; @BeforeAll static void setup() { - router = new Router(); + router = new DefaultRouter(); } @AfterAll static void teardown() { - router.shutdown(); + router.stop(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/flow/invocation/AbstractInterceptorFlowTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/flow/invocation/AbstractInterceptorFlowTest.java index 7551515225..6ececd6032 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/flow/invocation/AbstractInterceptorFlowTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/flow/invocation/AbstractInterceptorFlowTest.java @@ -20,28 +20,26 @@ import com.predic8.membrane.core.interceptor.*; import com.predic8.membrane.core.openapi.serviceproxy.*; import com.predic8.membrane.core.proxies.*; -import com.predic8.membrane.core.transport.http.*; import org.jetbrains.annotations.*; import org.junit.jupiter.api.*; import java.util.*; import static io.restassured.RestAssured.*; -import static java.util.Collections.*; import static org.junit.jupiter.api.Assertions.*; public abstract class AbstractInterceptorFlowTest { - private static Router router; + private Router router; - @BeforeAll - static void setUp() { - router = getRouter(); + @BeforeEach + void setUp() { + router = new TestRouter(); } - @AfterAll - static void tearDown() { - router.shutdown(); + @AfterEach + void tearDown() { + router.stop(); } protected void assertFlow(String expected,Interceptor... interceptors) throws Exception { @@ -55,9 +53,9 @@ protected String getResponse(Interceptor... interceptors) throws Exception { } private void setUpRouter(Interceptor[] interceptors) throws Exception { - router.setRules(EMPTY_LIST); + // router.setRules(EMPTY_LIST); router.add(getApiProxy(interceptors)); - router.init(); + router.start(); } private static @NotNull APIProxy getApiProxy(Interceptor[] interceptors) { @@ -73,11 +71,4 @@ private static APIProxy getServiceProxy() { api.setKey(new ServiceProxyKey("*","*",null,2000)); return api; } - - @NotNull - private static Router getRouter() { - Router r = new Router(); - r.setTransport(new HttpTransport()); - return r; - } } \ No newline at end of file diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/flow/invocation/FlowTestInterceptors.java b/core/src/test/java/com/predic8/membrane/core/interceptor/flow/invocation/FlowTestInterceptors.java index 8a83a7eb22..f47685a6e7 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/flow/invocation/FlowTestInterceptors.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/flow/invocation/FlowTestInterceptors.java @@ -73,7 +73,7 @@ public static Otherwise OTHERWISE(Interceptor... nestedInterceptors) { public static Interceptor GROOVY(String aSrc) { return new GroovyInterceptor() {{ - router = new HttpRouter(); + router = new DummyTestRouter(); setSrc(aSrc); init(); }}; diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/flow/invocation/internalservice/AbstractInternalServiceRoutingInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/flow/invocation/internalservice/AbstractInternalServiceRoutingInterceptorTest.java index 535746c493..41e5ac4c0a 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/flow/invocation/internalservice/AbstractInternalServiceRoutingInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/flow/invocation/internalservice/AbstractInternalServiceRoutingInterceptorTest.java @@ -39,24 +39,21 @@ abstract class AbstractInternalServiceRoutingInterceptorTest { @BeforeEach void setup() throws Exception { - router = new HttpRouter(); - router.getConfig().setHotDeploy(false); - + router = new TestRouter(); + router.getConfiguration().setHotDeploy(false); configure(); - - router.init(); router.start(); } @AfterEach void tearDown() { - router.shutdown(); + router.stop(); } public void api(Consumer c) throws Exception { TestAPIProxy api = new TestAPIProxy(); c.accept(api); - router.getRuleManager().addProxyAndOpenPortIfNew(api); + router.add(api); } protected static class TestAPIProxy extends APIProxy { @@ -69,7 +66,7 @@ public void internal(Consumer c) throws Exception { TestInternalProxy api = new TestInternalProxy(); c.accept(api); api.setKey(new InternalProxyKey()); - router.getRuleManager().addProxyAndOpenPortIfNew(api); + router.add(api); } protected static class TestInternalProxy extends InternalProxy { diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/formvalidation/FormValidationInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/formvalidation/FormValidationInterceptorTest.java index a5047a5c57..8d94325d99 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/formvalidation/FormValidationInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/formvalidation/FormValidationInterceptorTest.java @@ -30,7 +30,7 @@ public class FormValidationInterceptorTest { @Test public void testValidation() throws Exception { FormValidationInterceptor interceptor = new FormValidationInterceptor(); - interceptor.init(new HttpRouter()); + interceptor.init(new DummyTestRouter()); Field article = new Field(); article.setName("article"); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/groovy/GroovyInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/groovy/GroovyInterceptorTest.java index d0c31e10c9..168e5b8a60 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/groovy/GroovyInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/groovy/GroovyInterceptorTest.java @@ -35,12 +35,12 @@ public class GroovyInterceptorTest { private final ApplicationContext applicationContext = mock(ApplicationContext.class); - HttpRouter router; + DummyTestRouter router; Exchange exc; @BeforeEach void setup() { - router = new HttpRouter(); + router = new DummyTestRouter(); router.setApplicationContext(applicationContext); when(applicationContext.getBean("abc")).thenReturn("OK"); exc = new Exchange(null); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/javascript/JavascriptInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/javascript/JavascriptInterceptorTest.java index 613647ea96..49f4ded84d 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/javascript/JavascriptInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/javascript/JavascriptInterceptorTest.java @@ -42,7 +42,7 @@ public class JavascriptInterceptorTest { private final static ObjectMapper om = new ObjectMapper(); - final Router router = new Router(); + final DefaultRouter router = new DefaultRouter(); JavascriptInterceptor interceptor; Exchange exc; diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/json/JsonProtectionInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/json/JsonProtectionInterceptorTest.java index 3d7bcf5b01..9036a0e292 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/json/JsonProtectionInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/json/JsonProtectionInterceptorTest.java @@ -32,8 +32,8 @@ public class JsonProtectionInterceptorTest { static JsonProtectionInterceptor jpiDev; private static JsonProtectionInterceptor buildJPI(boolean prod) { - Router router = new Router(); - router.getConfig().setProduction(prod); + DefaultRouter router = new DefaultRouter(); + router.getConfiguration().setProduction(prod); JsonProtectionInterceptor jpi = new JsonProtectionInterceptor(); jpi.setMaxTokens(4096); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptorTest.java index b092dd1c20..c6f13be199 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptorTest.java @@ -15,7 +15,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Request; import com.predic8.membrane.core.resolver.ResolverMap; @@ -240,7 +240,7 @@ private record TestData( @ParameterizedTest @MethodSource("data") - public void test(TestData data) throws Exception{ + void test(TestData data) throws Exception{ RsaJsonWebKey privateKey = RsaJwkGenerator.generateJwk(2048); privateKey.setKeyId(KID); @@ -261,10 +261,11 @@ private JwtAuthInterceptor prepareInterceptor(RsaJsonWebKey publicOnly) throws E } private JwtAuthInterceptor initInterceptor(JwtAuthInterceptor interceptor) throws Exception { - Router routerMock = mock(Router.class); - when(routerMock.getBaseLocation()).thenReturn(""); - when(routerMock.getResolverMap()).thenReturn(new ResolverMap()); - interceptor.init(routerMock); + DefaultRouter mock = mock(DefaultRouter.class); + when(mock.getBaseLocation()).thenReturn(""); + when(mock.getResolverMap()).thenReturn(new ResolverMap()); + when(mock.getConfiguration()).thenReturn(new Configuration()); + interceptor.init(mock); return interceptor; } diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptorUnitTests.java b/core/src/test/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptorUnitTests.java index 174751eb63..6d1535b5a8 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptorUnitTests.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptorUnitTests.java @@ -16,7 +16,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.predic8.membrane.core.HttpRouter; +import com.predic8.membrane.core.DummyTestRouter; import com.predic8.membrane.core.exchange.*; import com.predic8.membrane.core.http.Request; import org.junit.jupiter.api.*; @@ -62,7 +62,7 @@ void noJwtInHeader() { +"\", \"e\":\"BB\"}"); jwks.getJwks().add(jwk); interceptor.setJwks(jwks); - interceptor.init(new HttpRouter()); + interceptor.init(new DummyTestRouter()); interceptor.handleRequest(exchange); assertEquals(ERROR_JWT_NOT_FOUND, getErrorResponse(exchange)); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/lang/AbstractSetHeaderInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/lang/AbstractSetHeaderInterceptorTest.java index ca68a5d507..137d58ba58 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/lang/AbstractSetHeaderInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/lang/AbstractSetHeaderInterceptorTest.java @@ -28,13 +28,13 @@ abstract class AbstractSetHeaderInterceptorTest { Exchange exchange; Message message; final AbstractSetterInterceptor interceptor = new SetHeaderInterceptor(); - static Router router; + static DefaultRouter router; protected abstract Language getLanguage(); @BeforeEach void setUp() throws Exception { - router = new Router(); + router = new DefaultRouter(); exchange = new Exchange(null) {{ setRequest(new Request.Builder().post("/boo") .header("host", "localhost:8080") diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/lang/AbstractSetPropertyInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/lang/AbstractSetPropertyInterceptorTest.java index faaf5ce284..2dc988df15 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/lang/AbstractSetPropertyInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/lang/AbstractSetPropertyInterceptorTest.java @@ -16,7 +16,6 @@ import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.*; -import com.predic8.membrane.core.http.*; import com.predic8.membrane.core.lang.*; import org.junit.jupiter.api.*; @@ -28,7 +27,7 @@ abstract class AbstractSetPropertyInterceptorTest { - Router router; + DefaultRouter router; Exchange exc; AbstractSetterInterceptor interceptor; @@ -38,7 +37,7 @@ abstract class AbstractSetPropertyInterceptorTest { void setUp() throws URISyntaxException { interceptor = new SetPropertyInterceptor(); interceptor.setLanguage(getLanguage()); - router = new Router(); + router = new DefaultRouter(); exc = get("/dummy") .contentType(APPLICATION_JSON) .body(""" diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/lang/SetBodyInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/lang/SetBodyInterceptorTest.java index e95b8e3c37..7e06878125 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/lang/SetBodyInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/lang/SetBodyInterceptorTest.java @@ -44,7 +44,7 @@ void setup() throws URISyntaxException { @Test void nullResult() { sbi.setValue("null"); - sbi.init(new Router()); + sbi.init(new DefaultRouter()); sbi.handleRequest(exc); assertEquals("null", exc.getRequest().getBodyAsStringDecoded()); } @@ -52,7 +52,7 @@ void nullResult() { @Test void evalOfSimpleExpression() { sbi.setValue("${path}"); - sbi.init(new Router()); + sbi.init(new DefaultRouter()); sbi.handleRequest(exc); assertEquals("/foo", exc.getRequest().getBodyAsStringDecoded()); } @@ -60,7 +60,7 @@ void evalOfSimpleExpression() { @Test void response() { sbi.setValue("SC: ${statusCode}"); - sbi.init(new Router()); + sbi.init(new DefaultRouter()); sbi.handleResponse(exc); assertEquals("SC: 501", exc.getResponse().getBodyAsStringDecoded()); } diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/OAuth2RedirectTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/OAuth2RedirectTest.java index 108b10e3c6..afd5596cb6 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/OAuth2RedirectTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/OAuth2RedirectTest.java @@ -45,9 +45,9 @@ public abstract class OAuth2RedirectTest { static final URI AUTH_SERVER_BASE_URL = URI.create("http://localhost:2002"); static final URI BACKEND_BASE_URL = URI.create("http://localhost:2001"); static final URI CLIENT_BASE_URL = URI.create("http://localhost:2000"); - static Router authorizationServerRouter; - static Router oauth2ResourceRouter; - static Router backendRouter; + static DefaultRouter authorizationServerRouter; + static DefaultRouter oauth2ResourceRouter; + static DefaultRouter backendRouter; static final AtomicReference firstUrlHit = new AtomicReference<>(); static final AtomicReference targetUrlHit = new AtomicReference<>(); static final AtomicReference interceptorChainHit = new AtomicReference<>(); @@ -61,9 +61,9 @@ void init() throws Exception { @AfterEach void shutdown() { - authorizationServerRouter.shutdown(); - oauth2ResourceRouter.shutdown(); - backendRouter.shutdown(); + authorizationServerRouter.stop(); + oauth2ResourceRouter.stop(); + backendRouter.stop(); } @Test @@ -162,12 +162,12 @@ private static IfInterceptor createConditionalInterceptorWithReturnMessage(Strin }}; } - private static Router startProxyRule(SSLableProxy azureRule) throws Exception { - Router router = new Router(); + private static DefaultRouter startProxyRule(SSLableProxy azureRule) throws Exception { + DefaultRouter router = new DefaultRouter(); router.setExchangeStore(new ForgetfulExchangeStore()); router.setTransport(new HttpTransport()); - router.getRuleManager().addProxyAndOpenPortIfNew(azureRule); - router.init(); + router.add(azureRule); + router.start(); return router; } diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/authorizationservice/MembraneAuthorizationServiceTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/authorizationservice/MembraneAuthorizationServiceTest.java index 2928ce55ba..9642fa0540 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/authorizationservice/MembraneAuthorizationServiceTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/authorizationservice/MembraneAuthorizationServiceTest.java @@ -114,7 +114,7 @@ void configQuery() throws Exception { MembraneAuthorizationService mas = Mockito.spy(new MembraneAuthorizationService()); doReturn(new ByteArrayInputStream(CONFIG.getBytes())).when(mas).resolve(any(), Mockito.nullable(String.class), anyString()); mas.setSrc("dummy"); - mas.router = new Router(); + mas.router = new DefaultRouter(); return mas; } diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/AuthServerMock.java b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/AuthServerMock.java index 493c24fcb5..9b6b9103ba 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/AuthServerMock.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/AuthServerMock.java @@ -13,16 +13,16 @@ limitations under the License. */ package com.predic8.membrane.core.interceptor.oauth2.client; -import com.predic8.membrane.core.HttpRouter; +import com.predic8.membrane.core.DummyTestRouter; import com.predic8.membrane.core.proxies.ServiceProxy; import java.io.IOException; -public abstract class AuthServerMock extends HttpRouter { +public abstract class AuthServerMock extends DummyTestRouter { public AuthServerMock() throws IOException { getTransport().setBacklog(10_000); getTransport().setSocketTimeout(10_000); - getConfig().setHotDeploy(false); + getConfiguration().setHotDeploy(false); getTransport().setConcurrentConnectionLimitPerIp(500); getRuleManager().addProxyAndOpenPortIfNew(mockServiceProxy()); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/OAuth2ResourceErrorForwardingTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/OAuth2ResourceErrorForwardingTest.java index 56f80ff4fd..4fabd88b9a 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/OAuth2ResourceErrorForwardingTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/OAuth2ResourceErrorForwardingTest.java @@ -34,7 +34,6 @@ import java.util.*; import java.util.concurrent.atomic.*; -import static com.predic8.membrane.core.RuleManager.RuleDefinitionSource.*; import static com.predic8.membrane.core.http.MimeType.*; import static org.junit.jupiter.api.Assertions.*; @@ -42,12 +41,12 @@ public class OAuth2ResourceErrorForwardingTest { protected final BrowserMock browser = new BrowserMock(); private final int limit = 500; - protected HttpRouter mockAuthServer; + protected TestRouter mockAuthServer; protected final ObjectMapper om = new ObjectMapper(); final int serverPort = 3062; private final String serverHost = "localhost"; private final int clientPort = 31337; - private HttpRouter oauth2Resource; + private TestRouter oauth2Resource; private final AtomicReference error = new AtomicReference<>(); private final AtomicReference errorDescription = new AtomicReference<>(); @@ -64,22 +63,21 @@ public void init() throws IOException { error.set(null); errorDescription.set(null); - mockAuthServer = new HttpRouter(); + mockAuthServer = new TestRouter(); + mockAuthServer.add(getMockAuthServiceProxy()); + mockAuthServer.start(); mockAuthServer.getTransport().setBacklog(10000); mockAuthServer.getTransport().setSocketTimeout(10000); - mockAuthServer.getConfig().setHotDeploy(false); mockAuthServer.getTransport().setConcurrentConnectionLimitPerIp(limit); - mockAuthServer.getRuleManager().addProxyAndOpenPortIfNew(getMockAuthServiceProxy()); - mockAuthServer.start(); - oauth2Resource = new HttpRouter(); + oauth2Resource = new TestRouter(); + + oauth2Resource.add(getErrorCaptor()); + oauth2Resource.add(getConfiguredOAuth2Resource()); + oauth2Resource.start(); oauth2Resource.getTransport().setBacklog(10000); oauth2Resource.getTransport().setSocketTimeout(10000); - oauth2Resource.getConfig().setHotDeploy(false); oauth2Resource.getTransport().setConcurrentConnectionLimitPerIp(limit); - oauth2Resource.getRuleManager().addProxy(getErrorCaptor(), MANUAL); - oauth2Resource.getRuleManager().addProxy(getConfiguredOAuth2Resource(), MANUAL); - oauth2Resource.start(); } @AfterEach @@ -127,9 +125,9 @@ public synchronized Outcome handleRequest(Exchange exc) { throw new RuntimeException(e); } exc.setResponse(new FormPostGenerator(getClientAddress() + "/oauth2callback") - .withParameter("error", "DEMO-123") - .withParameter("error_description", "This is a demo error.") - .withParameter("state", params.get("state")).build()); + .withParameter("error", "DEMO-123") + .withParameter("error_description", "This is a demo error.") + .withParameter("state", params.get("state")).build()); } if (exc.getResponse() == null) diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/OAuth2ResourceRpIniLogoutTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/OAuth2ResourceRpIniLogoutTest.java index e907475ef3..5920bdb029 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/OAuth2ResourceRpIniLogoutTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/OAuth2ResourceRpIniLogoutTest.java @@ -14,7 +14,7 @@ package com.predic8.membrane.core.interceptor.oauth2.client; import com.fasterxml.jackson.databind.ObjectMapper; -import com.predic8.membrane.core.HttpRouter; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Header; import com.predic8.membrane.core.http.Request; @@ -59,12 +59,12 @@ public class OAuth2ResourceRpIniLogoutTest { protected final BrowserMock browser = new BrowserMock(); - protected HttpRouter mockAuthServer; + protected Router mockAuthServer; protected final ObjectMapper om = new ObjectMapper(); final int serverPort = 3062; private final String serverHost = "localhost"; private final int clientPort = 31337; - private HttpRouter oauth2Resource; + private Router oauth2Resource; private final AtomicBoolean isLoggedOutAtOP = new AtomicBoolean(false); private RsaJsonWebKey rsaJsonWebKey; private String jwksResponse; @@ -81,14 +81,14 @@ protected String getClientAddress() { public void init() throws IOException, JoseException { createKey(); - mockAuthServer = new HttpRouter(); - mockAuthServer.getConfig().setHotDeploy(false); - mockAuthServer.getRuleManager().addProxyAndOpenPortIfNew(getMockAuthServiceProxy()); + mockAuthServer = new TestRouter(); + mockAuthServer.getConfiguration().setHotDeploy(false); + mockAuthServer.add(getMockAuthServiceProxy()); mockAuthServer.start(); - oauth2Resource = new HttpRouter(); - oauth2Resource.getConfig().setHotDeploy(false); - oauth2Resource.getRuleManager().addProxyAndOpenPortIfNew(getConfiguredOAuth2Resource()); + oauth2Resource = new TestRouter(); + oauth2Resource.getConfiguration().setHotDeploy(false); + oauth2Resource.add(getConfiguredOAuth2Resource()); oauth2Resource.start(); } diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/OAuth2ResourceTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/OAuth2ResourceTest.java index 4f5ab3953f..58719d3a90 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/OAuth2ResourceTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/OAuth2ResourceTest.java @@ -13,9 +13,9 @@ package com.predic8.membrane.core.interceptor.oauth2.client; -import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.core.type.*; import com.fasterxml.jackson.databind.*; -import com.google.code.yanf4j.util.ConcurrentHashSet; +import com.google.code.yanf4j.util.*; import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.*; import com.predic8.membrane.core.http.*; @@ -37,51 +37,48 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import java.util.stream.IntStream; +import java.util.stream.*; import static com.predic8.membrane.core.http.MimeType.*; -import static com.predic8.membrane.core.http.Request.get; -import static com.predic8.membrane.core.http.Request.post; -import static com.predic8.membrane.core.interceptor.oauth2client.rf.OAuth2CallbackRequestHandler.MEMBRANE_MISSING_SESSION_DESCRIPTION; +import static com.predic8.membrane.core.http.Request.*; +import static com.predic8.membrane.core.interceptor.oauth2client.rf.OAuth2CallbackRequestHandler.*; import static org.junit.jupiter.api.Assertions.*; public abstract class OAuth2ResourceTest { protected final BrowserMock browser = new BrowserMock(); private final int limit = 100; - protected HttpRouter mockAuthServer; + protected TestRouter mockAuthServer; protected final ObjectMapper om = new ObjectMapper(); final Logger LOG = LoggerFactory.getLogger(OAuth2ResourceTest.class); final int serverPort = 3062; private final String serverHost = "localhost"; private final int clientPort = 31337; - private HttpRouter oauth2Resource; + private TestRouter oauth2Resource; private String getServerAddress() { - return "http://" + serverHost + ":" + serverPort; + return "http://%s:%d".formatted(serverHost, serverPort); } protected String getClientAddress() { - return "http://" + serverHost + ":" + clientPort; + return "http://%s:%d".formatted(serverHost, clientPort); } @BeforeEach public void init() throws IOException { - mockAuthServer = new HttpRouter(); + mockAuthServer = new TestRouter(); + mockAuthServer.add(getMockAuthServiceProxy()); + mockAuthServer.start(); mockAuthServer.getTransport().setBacklog(10000); mockAuthServer.getTransport().setSocketTimeout(10000); - mockAuthServer.getConfig().setHotDeploy(false); - mockAuthServer.getTransport().setConcurrentConnectionLimitPerIp(limit+1); - mockAuthServer.getRuleManager().addProxyAndOpenPortIfNew(getMockAuthServiceProxy()); - mockAuthServer.start(); + mockAuthServer.getTransport().setConcurrentConnectionLimitPerIp(limit + 1); - oauth2Resource = new HttpRouter(); + oauth2Resource = new TestRouter(); + oauth2Resource.add(getConfiguredOAuth2Resource()); + oauth2Resource.start(); oauth2Resource.getTransport().setBacklog(10000); oauth2Resource.getTransport().setSocketTimeout(10000); - oauth2Resource.getConfig().setHotDeploy(false); - oauth2Resource.getTransport().setConcurrentConnectionLimitPerIp(limit+1); - oauth2Resource.getRuleManager().addProxyAndOpenPortIfNew(getConfiguredOAuth2Resource()); - oauth2Resource.start(); + oauth2Resource.getTransport().setConcurrentConnectionLimitPerIp(limit + 1); } @AfterEach @@ -96,7 +93,8 @@ public void done() { public void getOriginalRequest() throws Exception { var response = browser.apply(get(getClientAddress() + "/init")).getResponse(); assertEquals(200, response.getStatusCode()); - var body = om.readValue(response.getBodyAsStream(), new TypeReference>() {}); + var body = om.readValue(response.getBodyAsStream(), new TypeReference>() { + }); assertEquals("/init", body.get("path")); assertEquals("", body.get("body")); assertEquals("GET", body.get("method")); @@ -106,7 +104,8 @@ public void getOriginalRequest() throws Exception { public void postOriginalRequest() throws Exception { var response = browser.apply(post(getClientAddress() + "/init").body("demobody")).getResponse(); assertEquals(200, response.getStatusCode()); - var body = om.readValue(response.getBodyAsStream(), new TypeReference>() {}); + var body = om.readValue(response.getBodyAsStream(), new TypeReference>() { + }); assertEquals("/init", body.get("path")); assertEquals("demobody", body.get("body")); assertEquals("POST", body.get("method")); @@ -117,7 +116,8 @@ public void postOriginalRequest() throws Exception { void testUseRefreshTokenOnTokenExpiration() throws Exception { var response = browser.apply(get(getClientAddress() + "/init")).getResponse(); assertEquals(200, response.getStatusCode()); - var body = om.readValue(response.getBodyAsStream(), new TypeReference>() {}); + var body = om.readValue(response.getBodyAsStream(), new TypeReference>() { + }); assertEquals("/init", body.get("path")); CountDownLatch cdl = new CountDownLatch(limit); @@ -135,7 +135,8 @@ private String getToken(CountDownLatch cdl) { cdl.await(); String path = "/" + UUID.randomUUID(); var response = browser.apply(get(getClientAddress() + path)).getResponse(); - var body = om.readValue(response.getBodyAsStringDecoded(), new TypeReference>() {}); + var body = om.readValue(response.getBodyAsStringDecoded(), new TypeReference>() { + }); assertEquals(path, body.get("path")); return body.get("accessToken"); } catch (Exception e) { @@ -283,9 +284,9 @@ public synchronized Response handleRequestInternal(Exchange exc) throws URISynta } else if (exc.getRequestURI().startsWith("/auth?")) { Map params = URLParamUtil.getParams(new URIFactory(), exc, URLParamUtil.DuplicateKeyOrInvalidFormStrategy.ERROR); return new FormPostGenerator(getClientAddress() + "/oauth2callback") - .withParameter("state", params.get("state")) - .withParameter("code", params.get("1234")) - .build(); + .withParameter("state", params.get("state")) + .withParameter("code", params.get("1234")) + .build(); } else if (exc.getRequestURI().startsWith("/token")) { ObjectMapper om = new ObjectMapper(); var responseData = Map.ofEntries( diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/B2CMembrane.java b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/B2CMembrane.java index 149a5b9842..3f46e0be38 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/B2CMembrane.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/B2CMembrane.java @@ -30,10 +30,9 @@ import java.util.*; import java.util.function.*; -import static com.predic8.membrane.core.RuleManager.RuleDefinitionSource.*; import static com.predic8.membrane.core.http.MimeType.*; import static com.predic8.membrane.core.http.Response.*; -import static com.predic8.membrane.core.interceptor.Outcome.RETURN; +import static com.predic8.membrane.core.interceptor.Outcome.*; /** * A locally running Membrane with various B2C features to test (1 ServiceProxy per feature). Primarily: @@ -52,7 +51,7 @@ public class B2CMembrane { private final ObjectMapper om = new ObjectMapper(); - private HttpRouter oauth2Resource; + private TestRouter oauth2Resource; private OAuth2Resource2Interceptor oAuth2Resource2Interceptor; public RequireAuth requireAuth; @@ -62,18 +61,14 @@ public B2CMembrane(B2CTestConfig tc, SessionManager sessionManager) { this.sessionManager = sessionManager; } - public void init() { - oauth2Resource = new HttpRouter(); - oauth2Resource.getTransport().setConcurrentConnectionLimitPerIp(10000); - oauth2Resource.getTransport().setBacklog(10000); - oauth2Resource.getTransport().setSocketTimeout(10000); - oauth2Resource.getConfig().setHotDeploy(false); - oauth2Resource.getTransport().setConcurrentConnectionLimitPerIp(tc.limit * 100); + public void init() throws IOException { + oauth2Resource = new TestRouter(); ServiceProxy sp1_oauth2resource2 = createOAuth2Resource2ServiceProxy(); ServiceProxy sp2_flowInitiator_logoutBeforeFlow = createFlowInitiatorServiceProxy("/pe/", tc.peFlowId, true); ServiceProxy sp3_flowInitiator_noLogout = createFlowInitiatorServiceProxy("/pe2/", tc.pe2FlowId, false); sp1_oauth2resource2.init(oauth2Resource); + ServiceProxy sp4_requireAuth = createRequireAuthServiceProxy(tc.api1Id, "/api/", ra -> { requireAuth = ra; ra.setScope("https://localhost/" + tc.api1Id + "/Read"); @@ -89,16 +84,21 @@ public void init() { ServiceProxy sp7_requireAuth = createRequireAuthServiceProxy(tc.api2Id, "/api2/", ra -> ra.setScope("https://localhost/" + tc.api2Id + "/Read")); ServiceProxy sp8_afterLogout = createAfterLogoutServiceProxy(); - oauth2Resource.getRuleManager().addProxy(sp8_afterLogout, MANUAL); - oauth2Resource.getRuleManager().addProxy(sp7_requireAuth, MANUAL); - oauth2Resource.getRuleManager().addProxy(sp6_requireAuth_ErrorStatus403, MANUAL); - oauth2Resource.getRuleManager().addProxy(sp5_requireAuth_AuthNotRequired, MANUAL); - oauth2Resource.getRuleManager().addProxy(sp4_requireAuth, MANUAL); - oauth2Resource.getRuleManager().addProxy(sp3_flowInitiator_noLogout, MANUAL); - oauth2Resource.getRuleManager().addProxy(sp2_flowInitiator_logoutBeforeFlow, MANUAL); - oauth2Resource.getRuleManager().addProxy(sp1_oauth2resource2, MANUAL); + oauth2Resource.add(sp8_afterLogout); + oauth2Resource.add(sp7_requireAuth); + oauth2Resource.add(sp6_requireAuth_ErrorStatus403); + oauth2Resource.add(sp5_requireAuth_AuthNotRequired); + oauth2Resource.add(sp4_requireAuth); + oauth2Resource.add(sp3_flowInitiator_noLogout); + oauth2Resource.add(sp2_flowInitiator_logoutBeforeFlow); + oauth2Resource.add(sp1_oauth2resource2); oauth2Resource.start(); + oauth2Resource.getTransport().setConcurrentConnectionLimitPerIp(10000); + oauth2Resource.getTransport().setBacklog(10000); + oauth2Resource.getTransport().setSocketTimeout(10000); + oauth2Resource.getTransport().setConcurrentConnectionLimitPerIp(tc.limit * 100); + } public void stop() { diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/MockAuthorizationServer.java b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/MockAuthorizationServer.java index 15b56638a1..538f96d7a2 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/MockAuthorizationServer.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/MockAuthorizationServer.java @@ -34,15 +34,14 @@ import java.math.*; import java.security.*; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import static com.predic8.membrane.core.RuleManager.RuleDefinitionSource.*; import static com.predic8.membrane.core.http.MimeType.*; import static com.predic8.membrane.core.interceptor.oauth2.ParamNames.*; -import static com.predic8.membrane.core.util.URLParamUtil.DuplicateKeyOrInvalidFormStrategy.ERROR; -import static java.net.URLEncoder.encode; -import static java.nio.charset.StandardCharsets.UTF_8; +import static com.predic8.membrane.core.util.URLParamUtil.DuplicateKeyOrInvalidFormStrategy.*; +import static java.net.URLEncoder.*; +import static java.nio.charset.StandardCharsets.*; import static org.junit.jupiter.api.Assertions.*; public class MockAuthorizationServer { @@ -53,7 +52,7 @@ public class MockAuthorizationServer { private final SecureRandom rand = new SecureRandom(); private final ObjectMapper om = new ObjectMapper(); - private HttpRouter mockAuthServer; + private TestRouter mockAuthServer; private RsaJsonWebKey rsaJsonWebKey; private String jwksResponse; @@ -78,15 +77,14 @@ public void init() throws IOException, JoseException { issuer = baseServerAddr + "/v2.0/"; createKey(); - mockAuthServer = new HttpRouter(); + mockAuthServer = new TestRouter(); + mockAuthServer.add(getMockAuthServiceProxy(SERVER_PORT, tc.susiFlowId)); + mockAuthServer.add(getMockAuthServiceProxy(SERVER_PORT, tc.peFlowId)); + mockAuthServer.add(getMockAuthServiceProxy(SERVER_PORT, tc.pe2FlowId)); + mockAuthServer.start(); mockAuthServer.getTransport().setBacklog(10000); mockAuthServer.getTransport().setSocketTimeout(10000); - mockAuthServer.getConfig().setHotDeploy(false); mockAuthServer.getTransport().setConcurrentConnectionLimitPerIp(tc.limit * 100); - mockAuthServer.getRuleManager().addProxy(getMockAuthServiceProxy(SERVER_PORT, tc.susiFlowId), MANUAL); - mockAuthServer.getRuleManager().addProxy(getMockAuthServiceProxy(SERVER_PORT, tc.peFlowId), MANUAL); - mockAuthServer.getRuleManager().addProxy(getMockAuthServiceProxy(SERVER_PORT, tc.pe2FlowId), MANUAL); - mockAuthServer.start(); } public void stop() { @@ -149,7 +147,7 @@ public synchronized Response handleRequestInternal(Exchange exc) throws Exceptio return handleTokenRequest(flowId, exc); } else if (requestURI.contains("/logout")) { onLogout.run(); - return Response.redirect( params.get("post_logout_redirect_uri"), 302).build(); + return Response.redirect(params.get("post_logout_redirect_uri"), 302).build(); } else { return Response.notFound().build(); } diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/OAuth2ResourceB2CTestSetup.java b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/OAuth2ResourceB2CTestSetup.java index c99f16e43d..6dc6c46f56 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/OAuth2ResourceB2CTestSetup.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/OAuth2ResourceB2CTestSetup.java @@ -24,7 +24,7 @@ import java.util.concurrent.atomic.AtomicBoolean; public abstract class OAuth2ResourceB2CTestSetup { - protected final Logger LOG = LoggerFactory.getLogger(OAuth2ResourceB2CTestSetup.class); + protected final Logger log = LoggerFactory.getLogger(OAuth2ResourceB2CTestSetup.class); protected final B2CTestConfig tc = new B2CTestConfig(); protected final ObjectMapper om = new ObjectMapper(); protected final AtomicBoolean didLogIn = new AtomicBoolean(); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/OAuth2ResourceB2CUnitTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/OAuth2ResourceB2CUnitTest.java index 3a169271ec..488a8f8e9e 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/OAuth2ResourceB2CUnitTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/oauth2/client/b2c/OAuth2ResourceB2CUnitTest.java @@ -90,7 +90,7 @@ public Outcome handleRequest(Exchange exc) { Exchange excCallResource = get(tc.getClientAddress() + "/malicious").buildExchange(); - LOG.debug("getting {}", excCallResource.getDestinations().getFirst()); + log.debug("getting {}", excCallResource.getDestinations().getFirst()); browser.apply(excCallResource); // will be aborted browser.clearCookies(); @@ -110,7 +110,7 @@ private List getLinesContaining(String haystackLines, String needle) { // this should avoid session fixation attacks @Test - public void newSessionCookieAfterLogin() throws URISyntaxException { + void newSessionCookieAfterLogin() throws URISyntaxException { // this initializes the session, but does not login the user (because redirects are not followed) browser.applyWithoutRedirect(get(tc.getClientAddress() + "/init")); @@ -136,7 +136,7 @@ public void newSessionCookieAfterLogin() throws URISyntaxException { } @Test - public void logout() throws Exception { + void logout() throws Exception { browser.apply(get(tc.getClientAddress() + "/init")); var ili = browser.apply(get(tc.getClientAddress() + "/is-logged-in")); @@ -161,7 +161,7 @@ public void logout() throws Exception { } @Test - public void logoutClearsOldCookie() throws Exception { + void logoutClearsOldCookie() throws Exception { browser.apply(get(tc.getClientAddress() + "/init")); var ili = browser.apply(get(tc.getClientAddress() + "/is-logged-in")); @@ -190,7 +190,7 @@ public void logoutClearsOldCookie() throws Exception { } @Test - public void staleSessionLogout() throws Exception { + void staleSessionLogout() throws Exception { var ili = browser.apply(get(tc.getClientAddress() + "/is-logged-in")); assertTrue(ili.getResponse().getBodyAsStringDecoded().contains("false")); @@ -206,7 +206,7 @@ public void staleSessionLogout() throws Exception { } @Test - public void requestAuth() throws Exception { + void requestAuth() throws Exception { var exc = browser.apply(get(tc.getClientAddress() + "/api/init")); assertEquals(200, exc.getResponse().getStatusCode()); @@ -218,7 +218,7 @@ public void requestAuth() throws Exception { } @Test - public void userFlowTest() throws Exception { + void userFlowTest() throws Exception { var exc = browser.apply(get(tc.getClientAddress() + "/init")); assertNull(getAccessToken(exc)); @@ -231,7 +231,7 @@ public void userFlowTest() throws Exception { } @Test - public void userFlowViaInitiatorTest() throws Exception { + void userFlowViaInitiatorTest() throws Exception { browser.apply(get(tc.getClientAddress() + "/init")); var exc = browser.apply(get(tc.getClientAddress() + "/pe/init")); @@ -250,7 +250,7 @@ private String getAccessToken(Exchange exc) throws JsonProcessingException { } @Test - public void multipleUserFlowsTest() throws Exception { + void multipleUserFlowsTest() throws Exception { var exc = browser.apply(get(tc.getClientAddress() + "/init")); browser.apply(get(tc.getClientAddress() + "/pe2/init")); @@ -264,7 +264,7 @@ public void multipleUserFlowsTest() throws Exception { } @Test - public void startingUserFlowButContinueToUseOldRefreshToken() throws Exception { + void startingUserFlowButContinueToUseOldRefreshToken() throws Exception { var exc = browser.apply(get(tc.getClientAddress() + "/init")); mockAuthorizationServer.abortSignIn.set(true); @@ -292,7 +292,7 @@ public void startingUserFlowButContinueToUseOldRefreshToken() throws Exception { } @Test - public void multipleUserFlowsWithErrorTest() throws Exception { + void multipleUserFlowsWithErrorTest() throws Exception { browser.apply(get(tc.getClientAddress() + "/init")); mockAuthorizationServer.returnOAuth2ErrorFromSignIn.set(true); @@ -308,7 +308,7 @@ public void multipleUserFlowsWithErrorTest() throws Exception { } @Test - public void stayLoggedInAfterProfileEditing2() throws Exception { + void stayLoggedInAfterProfileEditing2() throws Exception { browser.apply(get(tc.getClientAddress() + "/init")); mockAuthorizationServer.abortSignIn.set(true); @@ -327,7 +327,7 @@ public void stayLoggedInAfterProfileEditing2() throws Exception { } @Test - public void notLoggedInAfterProfileEditing() throws Exception { + void notLoggedInAfterProfileEditing() throws Exception { browser.apply(get(tc.getClientAddress() + "/init")); mockAuthorizationServer.abortSignIn.set(true); @@ -343,9 +343,8 @@ public void notLoggedInAfterProfileEditing() throws Exception { assertEquals("null", a2); // no access token, because user is logged out. } - @Test - public void loginParams() throws Exception { + void loginParams() throws Exception { var exc = browser.applyWithoutRedirect(get(tc.getClientAddress() + "/init?login_hint=def&illegal=true")); String location = exc.getResponse().getHeader().getFirstValue("Location"); @@ -366,7 +365,7 @@ public void loginParams() throws Exception { } @Test - public void loginParamsPerFlow() throws Exception { + void loginParamsPerFlow() throws Exception { var exc = browser.applyWithoutRedirect(get(tc.getClientAddress() + "/pe/init?domain_hint=flow&illegal=true")); var params = parseQueryString(new URIFactory().create(exc.getResponse().getHeader().getLocation()).getRawQuery(), ERROR); @@ -379,7 +378,7 @@ public void loginParamsPerFlow() throws Exception { } @Test - public void loginNotRequired() throws Exception { + void loginNotRequired() throws Exception { // access 1: not authenticated, expecting no token var exc = browser.applyWithoutRedirect(get(tc.getClientAddress() + "/api-no-auth-needed/")); @@ -399,7 +398,7 @@ public void loginNotRequired() throws Exception { } @Test - public void returning4xx() throws Exception { + void returning4xx() throws Exception { // access 1: not authenticated, expecting 4xx var exc = browser.applyWithoutRedirect(get(tc.getClientAddress() + "/api-no-redirect/")); @@ -418,7 +417,7 @@ public void returning4xx() throws Exception { } @Test - public void requireAuthRedirects() throws Exception { + void requireAuthRedirects() throws Exception { var excCallResource = browser.applyWithoutRedirect(get(tc.getClientAddress() + "/api/")); assertEquals(302, excCallResource.getResponse().getStatusCode()); assertTrue(excCallResource.getResponse().getHeader().getFirstValue(Header.LOCATION).contains( @@ -427,7 +426,7 @@ public void requireAuthRedirects() throws Exception { } @Test - public void errorDuringSignIn() throws Exception { + void errorDuringSignIn() throws Exception { mockAuthorizationServer.returnOAuth2ErrorFromSignIn.set(true); var exc = browser.apply(get(tc.getClientAddress() + "/api/")); @@ -437,7 +436,7 @@ public void errorDuringSignIn() throws Exception { } @Test - public void errorDuringSecondOAuth2FlowLogsUserOut() throws Exception { + void errorDuringSecondOAuth2FlowLogsUserOut() throws Exception { browser.apply(get(tc.getClientAddress() + "/init")); var ili = browser.apply(get(tc.getClientAddress() + "/is-logged-in")); @@ -451,7 +450,7 @@ public void errorDuringSecondOAuth2FlowLogsUserOut() throws Exception { } @Test - public void api1and2() throws Exception { + void api1and2() throws Exception { var exc = browser.apply(get(tc.getClientAddress() + "/api/")); Map body = om.readValue(exc.getResponse().getBodyAsStream(), Map.class); assertEquals("/api/", body.get("path")); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/opentelemetry/OpenTelemetryInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/opentelemetry/OpenTelemetryInterceptorTest.java index 10b41ee202..0f673dca18 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/opentelemetry/OpenTelemetryInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/opentelemetry/OpenTelemetryInterceptorTest.java @@ -13,24 +13,28 @@ limitations under the License. */ package com.predic8.membrane.core.interceptor.opentelemetry; -import com.predic8.membrane.core.HttpRouter; -import com.predic8.membrane.core.proxies.Proxy; -import com.predic8.membrane.core.proxies.ServiceProxy; -import com.predic8.membrane.core.proxies.ServiceProxyKey; -import org.junit.jupiter.api.Test; +import com.predic8.membrane.core.*; +import com.predic8.membrane.core.proxies.*; +import org.junit.jupiter.api.*; -import static com.predic8.membrane.core.RuleManager.RuleDefinitionSource.SPRING; +import java.io.*; class OpenTelemetryInterceptorTest { + private Router router; + @Test - void initTest() throws Exception { + void initTest() throws IOException { Proxy r = new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", 3141), null, 0); r.getFlow().add(new OpenTelemetryInterceptor()); - HttpRouter rtr = new HttpRouter(); - rtr.getRuleManager().addProxy(r, SPRING); + router = new DummyTestRouter(); + router.add(r); + router.init(); + } - rtr.init(); + @AfterEach + void tearDown() { + router.stop(); } } \ No newline at end of file diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/rewrite/ReverseProxyingInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/rewrite/ReverseProxyingInterceptorTest.java index ff7db9535c..7f11dbd771 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/rewrite/ReverseProxyingInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/rewrite/ReverseProxyingInterceptorTest.java @@ -32,7 +32,7 @@ public class ReverseProxyingInterceptorTest { @Test public void localRedirect() { - rp.init(new Router()); + rp.init(new DefaultRouter()); // invalid by spec, redirection location should not be rewritten assertEquals("/local", getRewrittenRedirectionLocation("membrane", 2000, "http://target/foo", "/local")); } diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/rewrite/RewriteInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/rewrite/RewriteInterceptorTest.java index b3c5a82da2..36d99912d8 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/rewrite/RewriteInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/rewrite/RewriteInterceptorTest.java @@ -41,7 +41,7 @@ public class RewriteInterceptorTest { @BeforeEach void setUp() { - HttpRouter router = new HttpRouter(); + DummyTestRouter router = new DummyTestRouter(); di = new DispatchingInterceptor(); di.init(router); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/rewrite/RewriterTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/rewrite/RewriterTest.java index d39794667e..4a657d0669 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/rewrite/RewriterTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/rewrite/RewriterTest.java @@ -35,7 +35,7 @@ void setUp() { mappings.add(new Mapping("/hello/(.*)", "/$1", null)); rewriter.setMappings(mappings); - rewriter.init(new HttpRouter()); + rewriter.init(new DummyTestRouter()); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/schemavalidation/SOAPFaultTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/schemavalidation/SOAPFaultTest.java index c647754eaf..0c769e2c83 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/schemavalidation/SOAPFaultTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/schemavalidation/SOAPFaultTest.java @@ -13,7 +13,7 @@ limitations under the License. */ package com.predic8.membrane.core.interceptor.schemavalidation; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.util.SOAPUtil; import org.junit.jupiter.api.Test; @@ -32,7 +32,7 @@ public class SOAPFaultTest { public static final String ARTICLE_SERVICE_WSDL = getPathFromResource( "/validation/ArticleService.wsdl"); - final Router r = new Router(); + final Router r = new DummyTestRouter(); @Test public void testValidateFaults() { diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/schemavalidation/SOAPMessageValidatorInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/schemavalidation/SOAPMessageValidatorInterceptorTest.java index 0f1cdd6b2a..7ccb95a1ef 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/schemavalidation/SOAPMessageValidatorInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/schemavalidation/SOAPMessageValidatorInterceptorTest.java @@ -39,7 +39,7 @@ public class SOAPMessageValidatorInterceptorTest { @BeforeAll static void setup() { - router = new Router(); + router = new DummyTestRouter(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/schemavalidation/ValidatorInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/schemavalidation/ValidatorInterceptorTest.java index 7c4c25160c..5df75ec123 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/schemavalidation/ValidatorInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/schemavalidation/ValidatorInterceptorTest.java @@ -14,7 +14,7 @@ package com.predic8.membrane.core.interceptor.schemavalidation; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Request; import com.predic8.membrane.core.http.Response; @@ -29,6 +29,7 @@ import java.nio.file.Files; import java.nio.file.Path; +import static com.predic8.membrane.core.http.Request.post; import static com.predic8.membrane.core.interceptor.Outcome.ABORT; import static com.predic8.membrane.core.interceptor.Outcome.CONTINUE; import static com.predic8.membrane.test.TestUtil.getPathFromResource; @@ -56,10 +57,10 @@ public class ValidatorInterceptorTest { @BeforeAll public static void setUp() throws URISyntaxException { - requestTB = Request.post("http://thomas-bayer.com").build(); - requestXService = Request.post("http://ws.xwebservices.com").build(); + requestTB = post("http://thomas-bayer.com").build(); + requestXService = post("http://ws.xwebservices.com").build(); exc = new Exchange(null); - router = new Router(); + router = new DummyTestRouter(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/server/WSDLPublisherInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/server/WSDLPublisherInterceptorTest.java index 1013c203a8..6d77a1a5b1 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/server/WSDLPublisherInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/server/WSDLPublisherInterceptorTest.java @@ -26,7 +26,7 @@ public class WSDLPublisherInterceptorTest { - private HttpRouter router; + private Router router; static List getPorts() { return Arrays.asList(new Object[][] { @@ -36,18 +36,18 @@ static List getPorts() { } void before(String wsdlLocation, int port) throws Exception { - router = new HttpRouter(); + router = new TestRouter(); ServiceProxy sp2 = new ServiceProxy(new ServiceProxyKey("*", "*", ".*", port), "", -1); WSDLPublisherInterceptor wi = new WSDLPublisherInterceptor(); wi.setWsdl(wsdlLocation); wi.init(router); sp2.getFlow().add(wi); - router.getRuleManager().addProxyAndOpenPortIfNew(sp2); - router.init(); + router.add(sp2); + router.start(); } void after() { - router.shutdown(); + router.stop(); } @ParameterizedTest(name = "{0} {1}") diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/server/WebServerInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/server/WebServerInterceptorTest.java index c4fa5130a7..c3fb97b47c 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/server/WebServerInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/server/WebServerInterceptorTest.java @@ -32,7 +32,7 @@ class WebServerInterceptorTest { @BeforeEach void init() { - r = new Router(); + r = new DummyTestRouter(); ws = new WebServerInterceptor(r) {{ setDocBase(Objects.requireNonNull(this.getClass().getResource("/html/")).toString()); @@ -56,13 +56,10 @@ void noIndex() { } @Test - void generateIndex() throws Exception { + void generateIndex() { ws.setGenerateIndex(true); ws.handleRequest(exc); // No index file is set, but index page is being generated. Body lists the page.html resource. - String body = exc.getResponse().getBodyAsStringDecoded(); - // System.out.println("body = " + body); - assertTrue(exc.getResponse().getBodyAsStringDecoded().contains("page.html")); } } \ No newline at end of file diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/session/FakeSyncSessionStoreManager.java b/core/src/test/java/com/predic8/membrane/core/interceptor/session/FakeSyncSessionStoreManager.java index 8a52e8915e..a38fe756a5 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/session/FakeSyncSessionStoreManager.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/session/FakeSyncSessionStoreManager.java @@ -13,7 +13,7 @@ limitations under the License. */ package com.predic8.membrane.core.interceptor.session; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import java.util.*; diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/session/SessionInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/session/SessionInterceptorTest.java index a79a289156..84f71e763e 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/session/SessionInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/session/SessionInterceptorTest.java @@ -36,51 +36,52 @@ import java.util.concurrent.atomic.*; import java.util.stream.*; -import static com.predic8.membrane.core.interceptor.Outcome.CONTINUE; -import static com.predic8.membrane.core.interceptor.Outcome.RETURN; +import static com.predic8.membrane.core.RuleManager.RuleDefinitionSource.*; +import static com.predic8.membrane.core.interceptor.Outcome.*; import static java.nio.charset.StandardCharsets.*; import static org.junit.jupiter.api.Assertions.*; public class SessionInterceptorTest { - private HttpRouter router; + private Router router; private CloseableHttpClient httpClient; @BeforeEach public void setUp() { - router = new HttpRouter(); + router = new TestRouter(); httpClient = createHttpClient(); } @AfterEach void shutDown() throws IOException { - router.shutdown(); + router.stop(); httpClient.close(); } @Test - public void generalSessionUsageTest() throws Exception { + public void generalSessionUsageTest() throws IOException { ServiceProxy sp = createTestServiceProxy(); - router.getRuleManager().addProxyAndOpenPortIfNew(sp); + AtomicLong counter = new AtomicLong(0); List vals = new ArrayList<>(); - AbstractInterceptorWithSession interceptor = defineInterceptor(counter,vals); + AbstractInterceptorWithSession interceptor = defineInterceptor(counter, vals); sp.getFlow().add(interceptor); sp.getFlow().add(testResponseInterceptor()); - router.init(); + router.add(sp); + router.start(); IntStream.range(0, 50).forEach(i -> sendRequest()); assertNull(vals.getFirst()); - for(int i = 1; i < 98; i+=2){ - int index = Math.round((i-1)/2f); - assertEquals(index,vals.get(i).intValue()); + for (int i = 1; i < 98; i += 2) { + int index = Math.round((i - 1) / 2f); + assertEquals(index, vals.get(i).intValue()); } - assertEquals(49,vals.get(99).intValue()); + assertEquals(49, vals.get(99).intValue()); } private ServiceProxy createTestServiceProxy() { @@ -88,61 +89,58 @@ private ServiceProxy createTestServiceProxy() { } @Test - public void expirationTest() throws Exception{ - ServiceProxy sp = createTestServiceProxy(); - router.getRuleManager().addProxyAndOpenPortIfNew(sp); - - AtomicLong counter = new AtomicLong(0); + public void expirationTest() throws IOException { List vals = new ArrayList<>(); - AbstractInterceptorWithSession interceptor = defineInterceptor(counter, vals); + AbstractInterceptorWithSession interceptor = defineInterceptor(new AtomicLong(0), vals); + ServiceProxy sp = createTestServiceProxy(); sp.getFlow().add(interceptor); sp.getFlow().add(testResponseInterceptor()); - router.init(); - + router.add(sp); + router.start(); interceptor.getSessionManager().setExpiresAfterSeconds(0); IntStream.range(0, 50).forEach(i -> sendRequest()); - for(int i = 0; i < 100; i+=2) + for (int i = 0; i < 100; i += 2) assertNull(vals.get(i)); } @Test - public void noUnneededRenewalOnReadOnlySession() throws Exception{ + public void noUnneededRenewalOnReadOnlySession() { ServiceProxy sp = createTestServiceProxy(); - router.getRuleManager().addProxyAndOpenPortIfNew(sp); + router.getRuleManager().addProxy(sp, MANUAL); sp.getFlow().add(createAndReadOnlySessionInterceptor()); sp.getFlow().add(testResponseInterceptor()); - router.init(); + router.start(); - List> bodies = new ArrayList<>(); + List> bodies = new ArrayList<>(); int lowerBound = 0; int upperBound = 1000; IntStream.range(lowerBound, upperBound).forEach(i -> bodies.add(sendRequest())); - IntStream.range(lowerBound+1,upperBound-1).forEach(i -> assertEquals(bodies.get(i),bodies.get(i+1))); + IntStream.range(lowerBound + 1, upperBound - 1).forEach(i -> assertEquals(bodies.get(i), bodies.get(i + 1))); } @Disabled @Test - public void renewalOnReadOnlySession() throws Exception{ + public void renewalOnReadOnlySession() { ServiceProxy sp = createTestServiceProxy(); AbstractInterceptorWithSession createAndReadOnlySessionInterceptor = createAndReadOnlySessionInterceptor(); sp.getFlow().add(createAndReadOnlySessionInterceptor); sp.getFlow().add(testResponseInterceptor()); - router.getRuleManager().addProxyAndOpenPortIfNew(sp); - router.init(); + router.getRuleManager().addProxy(sp, MANUAL); + router.start(); - List> bodies = new ArrayList<>(); + List> bodies = new ArrayList<>(); int lowerBound = 0; int upperBound = 10; @@ -151,15 +149,15 @@ public void renewalOnReadOnlySession() throws Exception{ bodies.forEach(this::printCookie); - IntStream.range(lowerBound+1,upperBound-1).forEach(i -> assertEquals(getCookieKey(bodies.get(i)),getCookieKey(bodies.get(i+1)))); + IntStream.range(lowerBound + 1, upperBound - 1).forEach(i -> assertEquals(getCookieKey(bodies.get(i)), getCookieKey(bodies.get(i + 1)))); - String cookieOne = getCookieKey(bodies.get(upperBound-1)); + String cookieOne = getCookieKey(bodies.get(upperBound - 1)); - Duration origRenewalTime = ((JwtSessionManager)createAndReadOnlySessionInterceptor.getSessionManager()).getRenewalTime(); + Duration origRenewalTime = ((JwtSessionManager) createAndReadOnlySessionInterceptor.getSessionManager()).getRenewalTime(); - ((JwtSessionManager)createAndReadOnlySessionInterceptor.getSessionManager()).setRenewalTime(Duration.ofMillis(0)); + ((JwtSessionManager) createAndReadOnlySessionInterceptor.getSessionManager()).setRenewalTime(Duration.ofMillis(0)); sendRequest(); - ((JwtSessionManager)createAndReadOnlySessionInterceptor.getSessionManager()).setRenewalTime(origRenewalTime); + ((JwtSessionManager) createAndReadOnlySessionInterceptor.getSessionManager()).setRenewalTime(origRenewalTime); bodies.clear(); @@ -167,19 +165,19 @@ public void renewalOnReadOnlySession() throws Exception{ bodies.forEach(this::printCookie); - IntStream.range(lowerBound+1,upperBound-1).forEach(i -> assertEquals(getCookieKey(bodies.get(i)),getCookieKey(bodies.get(i+1)))); + IntStream.range(lowerBound + 1, upperBound - 1).forEach(i -> assertEquals(getCookieKey(bodies.get(i)), getCookieKey(bodies.get(i + 1)))); - String cookieTwo = getCookieKey(bodies.get(upperBound-1)); - assertNotEquals(cookieOne,cookieTwo); + String cookieTwo = getCookieKey(bodies.get(upperBound - 1)); + assertNotEquals(cookieOne, cookieTwo); } - public void printCookie(Map body){ + public void printCookie(Map body) { System.out.println(getCookieKey(body)); } - public String getCookieKey(Map cookie){ - String raw = ((Map)cookie.get("request")).get("Cookie").toString(); + public String getCookieKey(Map cookie) { + String raw = ((Map) cookie.get("request")).get("Cookie").toString(); return raw.split("=")[0]; } @@ -187,7 +185,7 @@ private AbstractInterceptor testResponseInterceptor() { return new AbstractInterceptor() { @Override public Outcome handleRequest(Exchange exc) { - if(exc.getResponse() == null) + if (exc.getResponse() == null) exc.setResponse(Response.ok().build()); try { exc.getResponse().setBodyContent(createTestResponseBody(exc).getBytes()); @@ -224,24 +222,24 @@ private String createTestResponseBody(Exchange exc) throws JsonProcessingExcepti Map response = new HashMap(); Stream.of("Cookie") - .forEach(cookieName -> addJoinedHeaderTo(request,cookieName,exc.getRequest())); + .forEach(cookieName -> addJoinedHeaderTo(request, cookieName, exc.getRequest())); Stream.of("Set-Cookie") - .forEach(cookieName -> addJoinedHeaderTo(response,cookieName,exc.getResponse())); + .forEach(cookieName -> addJoinedHeaderTo(response, cookieName, exc.getResponse())); ImmutableMap value = ImmutableMap.of("request", request, "response", response); return new ObjectMapper().writeValueAsString(value); } - private Stream getHeader(String name, Message msg){ - if(msg == null) + private Stream getHeader(String name, Message msg) { + if (msg == null) return Stream.empty(); return Stream.of(msg.getHeader().getAllHeaderFields()) .filter(hf -> hf.getHeaderName().getName().equalsIgnoreCase(name)); } - private void addJoinedHeaderTo(Map cache, String name, Message msg){ - cache.put(name, getHeader(name,msg) + private void addJoinedHeaderTo(Map cache, String name, Message msg) { + cache.put(name, getHeader(name, msg) .map(HeaderField::getValue) .collect(Collectors.joining(";"))); } @@ -250,13 +248,14 @@ private static CloseableHttpClient createHttpClient() { return HttpClients.custom().setConnectionManager(new BasicHttpClientConnectionManager()).setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()).build(); } - private Map sendRequest() { + private Map sendRequest() { Map result; HttpGet httpGet = new HttpGet("http://localhost:3001"); try { try (CloseableHttpResponse response = httpClient.execute(httpGet)) { String string = IOUtils.toString(response.getEntity().getContent(), UTF_8); - result = new ObjectMapper().readValue(string, new TypeReference<>() {}); + result = new ObjectMapper().readValue(string, new TypeReference<>() { + }); EntityUtils.consume(response.getEntity()); } } catch (Exception e) { @@ -267,20 +266,20 @@ private Map sendRequest() { private AbstractInterceptorWithSession defineInterceptor(AtomicLong counter, List vals) { return new AbstractInterceptorWithSession() { - @Override - public Outcome handleRequestInternal(Exchange exc) { - Session s = getSessionManager().getSession(exc); - vals.add(s.get("value")); - long nextVal = counter.getAndIncrement(); - s.put("value", nextVal); - vals.add(s.get("value")); - return CONTINUE; - } + @Override + public Outcome handleRequestInternal(Exchange exc) { + Session s = getSessionManager().getSession(exc); + vals.add(s.get("value")); + long nextVal = counter.getAndIncrement(); + s.put("value", nextVal); + vals.add(s.get("value")); + return CONTINUE; + } - @Override - protected Outcome handleResponseInternal(Exchange exc) { - return CONTINUE; - } - }; + @Override + protected Outcome handleResponseInternal(Exchange exc) { + return CONTINUE; + } + }; } } diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/shadowing/ShadowingInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/shadowing/ShadowingInterceptorTest.java index 093af82b2e..4d9ef73f07 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/shadowing/ShadowingInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/shadowing/ShadowingInterceptorTest.java @@ -37,8 +37,8 @@ class ShadowingInterceptorTest { Exchange exc; Header header; - static Router interceptorRouter; - static Router shadowingRouter; + static DefaultRouter interceptorRouter; + static DefaultRouter shadowingRouter; static ServiceProxy interceptorProxy; static ShadowingInterceptor shadowingInterceptor; @@ -67,8 +67,8 @@ void setUp() throws Exception { @BeforeAll static void startup() throws Exception { - interceptorRouter = new Router(); - interceptorRouter.getConfig().setHotDeploy(false); + interceptorRouter = new DefaultRouter(); + interceptorRouter.getConfiguration().setHotDeploy(false); interceptorRouter.setExchangeStore(new ForgetfulExchangeStore()); interceptorRouter.setTransport(new HttpTransport()); @@ -87,22 +87,20 @@ static void startup() throws Exception { new ReturnInterceptor() )); - interceptorRouter.getRuleManager().addProxyAndOpenPortIfNew(interceptorProxy); - interceptorRouter.init(); + interceptorRouter.add(interceptorProxy); interceptorRouter.start(); - shadowingRouter = new Router(); - shadowingRouter.getConfig().setHotDeploy(false); + shadowingRouter = new DefaultRouter(); + shadowingRouter.getConfiguration().setHotDeploy(false); shadowingRouter.setExchangeStore(new ForgetfulExchangeStore()); shadowingRouter.setTransport(new HttpTransport()); shadowingProxy = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", 3000), null, 0); returnInterceptorMock = Mockito.spy(new ReturnInterceptor()); - returnInterceptorMock.setStatusCode(200); + returnInterceptorMock.setStatus(200); shadowingProxy.setFlow(List.of(returnInterceptorMock)); - shadowingRouter.getRuleManager().addProxyAndOpenPortIfNew(shadowingProxy); - shadowingRouter.init(); + shadowingRouter.add(shadowingProxy); shadowingRouter.start(); } @@ -117,7 +115,7 @@ static void shutdown() { * and ensures that the ReturnInterceptor's handleRequest() is invoked once. */ @Test - void testIfShadowTargetIsCalled() throws Exception { + void testIfShadowTargetIsCalled() { given().when().get("http://localhost:2000").then().statusCode(200); verify(returnInterceptorMock, timeout(10000).times(1)).handleRequest(any(Exchange.class)); } @@ -127,7 +125,7 @@ void testIfShadowTargetIsCalled() throws Exception { * handleRequest() is invoked with an Exchange object not containing the "foo" header. */ @Test - void testIfShadowTargetHasFooHeader() throws Exception { + void testIfShadowTargetHasFooHeader() { given().when().get("http://localhost:2000").then().statusCode(200); ArgumentCaptor exchangeCaptor = ArgumentCaptor.forClass(Exchange.class); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/soap/SoapAndInternalProxyTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/soap/SoapAndInternalProxyTest.java index f42317aa16..f722d85f3d 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/soap/SoapAndInternalProxyTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/soap/SoapAndInternalProxyTest.java @@ -16,14 +16,13 @@ import com.predic8.membrane.core.*; import com.predic8.membrane.core.interceptor.*; import com.predic8.membrane.core.interceptor.server.*; -import com.predic8.membrane.core.proxies.*; import com.predic8.membrane.core.proxies.AbstractServiceProxy.*; +import com.predic8.membrane.core.proxies.*; import org.jetbrains.annotations.*; import org.junit.jupiter.api.*; import java.io.*; -import static com.google.common.collect.Lists.*; import static io.restassured.RestAssured.*; import static java.nio.charset.StandardCharsets.*; import static java.util.Objects.*; @@ -35,26 +34,23 @@ */ public class SoapAndInternalProxyTest { - HttpRouter router; + Router router; @BeforeEach void setup() { - router = new HttpRouter(); - router.getConfig().setHotDeploy(false); + router = new TestRouter(); } @AfterEach void teardown() { - router.shutdown(); + router.stop(); } @Test void test() throws Exception { - router.setRules(newArrayList(createInternalProxy())); + router.add(createInternalProxy()); + router.add(createServiceProxyWithWSDLInterceptors()); router.start(); - Proxy soapProxy = createServiceProxyWithWSDLInterceptors(); - soapProxy.init(router); - router.add(soapProxy); runCheck(); } @@ -82,7 +78,7 @@ private Proxy createInternalProxy() { InternalProxy ip = new InternalProxy(); ip.setName("int"); ip.getFlow().add(new SampleSoapServiceInterceptor()); - ip.setTarget(new Target("localhost",9501)); + ip.setTarget(new Target("localhost", 9501)); return ip; } diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/templating/StaticInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/templating/StaticInterceptorTest.java index 01bb33c7dd..93c9cd1fd8 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/templating/StaticInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/templating/StaticInterceptorTest.java @@ -41,7 +41,7 @@ void beforeAll() throws URISyntaxException { @Test void readContentFromLocationPath() { - i.init(new Router()); + i.init(new DummyTestRouter()); i.handleRequest(exc); assertEquals(27, exc.getRequest().getBodyAsStringDecoded().length()); } @@ -50,7 +50,7 @@ void readContentFromLocationPath() { void pretty() { i.setPretty(TRUE); i.setContentType(APPLICATION_JSON); - i.init(new Router()); + i.init(new DummyTestRouter()); i.handleRequest(exc); @@ -81,7 +81,7 @@ void utf_16() throws Exception { private void checkWithCharset(String charset) throws Exception { i.setLocation(getAbsolutePath("/charsets/%s.txt".formatted(charset))); i.setCharset(charset); - i.init(new Router()); + i.init(new DummyTestRouter()); i.handleRequest(exc); assertEquals(REF_CHARS, exc.getRequest().getBodyAsStringDecoded()); } diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/templating/TemplateInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/templating/TemplateInterceptorTest.java index b5a3f5cefd..1f86d3472e 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/templating/TemplateInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/templating/TemplateInterceptorTest.java @@ -49,12 +49,12 @@ public class TemplateInterceptorTest { TemplateInterceptor ti; Exchange exc = new Exchange(null); Request req; - static Router router; + static DefaultRouter router; static ResolverMap map; @BeforeAll static void setupFiles() { - router = mock(Router.class); + router = mock(DefaultRouter.class); map = new ResolverMap(); when(router.getResolverMap()).thenReturn(map); when(router.getUriFactory()).thenReturn(new URIFactory()); diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/tunnel/WebsocketStompTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/tunnel/WebsocketStompTest.java index dd3d040869..df132f6aa9 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/tunnel/WebsocketStompTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/tunnel/WebsocketStompTest.java @@ -22,7 +22,7 @@ public class WebsocketStompTest { @Test - public void testWebsocketStomp() throws Exception{ + void websocketStomp() throws Exception{ // Preparation: Start the Websocket-Stomp example from an external source // Starts embedded ActiveMQ and places "Hello world!" into the "foo" queue diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/xml/Json2XmlInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/xml/Json2XmlInterceptorTest.java index 3d6620d5cb..c1380ca6c5 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/xml/Json2XmlInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/xml/Json2XmlInterceptorTest.java @@ -62,7 +62,7 @@ public class Json2XmlInterceptorTest { @BeforeEach void setUp() { interceptor = new Json2XmlInterceptor(); - interceptor.init(new Router()); + interceptor.init(new DefaultRouter()); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/xml/Xml2JsonInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/xml/Xml2JsonInterceptorTest.java index 0b278c863e..acf9ad9fa6 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/xml/Xml2JsonInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/xml/Xml2JsonInterceptorTest.java @@ -36,7 +36,7 @@ public class Xml2JsonInterceptorTest { @BeforeAll static void setup() { interceptor = new Xml2JsonInterceptor(); - interceptor.init(new Router()); + interceptor.init(new DefaultRouter()); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/xmlprotection/XMLProtectionInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/xmlprotection/XMLProtectionInterceptorTest.java index 29d68e1d85..a6977af59e 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/xmlprotection/XMLProtectionInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/xmlprotection/XMLProtectionInterceptorTest.java @@ -38,7 +38,7 @@ static void setUp() throws Exception { exc.setOriginalHostHeader("thomas-bayer.com:80"); interceptor = new XMLProtectionInterceptor(); - interceptor.init(new Router()); + interceptor.init(new DefaultRouter()); } private void runOn(String resource, boolean expectSuccess) throws Exception { diff --git a/core/src/test/java/com/predic8/membrane/core/interceptor/xslt/XSLTInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/interceptor/xslt/XSLTInterceptorTest.java index 4ad78bf191..8117fe7da2 100644 --- a/core/src/test/java/com/predic8/membrane/core/interceptor/xslt/XSLTInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/interceptor/xslt/XSLTInterceptorTest.java @@ -22,7 +22,7 @@ import org.junit.jupiter.api.Test; import org.xml.sax.InputSource; -import com.predic8.membrane.core.HttpRouter; +import com.predic8.membrane.core.DummyTestRouter; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Response; @@ -40,7 +40,7 @@ public void testRequest() throws Exception { XSLTInterceptor i = new XSLTInterceptor(); i.setXslt("classpath:/customer2person.xsl"); - i.init(new HttpRouter()); + i.init(new DummyTestRouter()); i.handleResponse(exc); //printBodyContent(); @@ -60,7 +60,7 @@ public void testXSLTParameter() throws Exception { XSLTInterceptor i = new XSLTInterceptor(); i.setXslt("classpath:/customer2personAddCompany.xsl"); - i.init(new HttpRouter()); + i.init(new DummyTestRouter()); i.handleResponse(exc); //printBodyContent(); diff --git a/core/src/test/java/com/predic8/membrane/core/kubernetes/GenericYamlParserTest.java b/core/src/test/java/com/predic8/membrane/core/kubernetes/GenericYamlParserTest.java index e0216123fd..26e03653fc 100644 --- a/core/src/test/java/com/predic8/membrane/core/kubernetes/GenericYamlParserTest.java +++ b/core/src/test/java/com/predic8/membrane/core/kubernetes/GenericYamlParserTest.java @@ -10,45 +10,39 @@ package com.predic8.membrane.core.kubernetes; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; -import com.predic8.membrane.annot.Grammar; -import com.predic8.membrane.annot.beanregistry.BeanCollector; -import com.predic8.membrane.annot.beanregistry.BeanDefinition; -import com.predic8.membrane.annot.beanregistry.BeanRegistry; -import com.predic8.membrane.annot.beanregistry.ChangeEvent; +import com.fasterxml.jackson.core.*; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.dataformat.yaml.*; +import com.predic8.membrane.annot.*; +import com.predic8.membrane.annot.beanregistry.*; import com.predic8.membrane.annot.yaml.*; -import com.predic8.membrane.core.config.spring.GrammarAutoGenerated; -import com.predic8.membrane.core.interceptor.authentication.BasicAuthenticationInterceptor; -import com.predic8.membrane.core.interceptor.authentication.session.StaticUserDataProvider; -import com.predic8.membrane.core.interceptor.balancer.LoadBalancingInterceptor; -import com.predic8.membrane.core.interceptor.beautifier.BeautifierInterceptor; -import com.predic8.membrane.core.interceptor.flow.ResponseInterceptor; -import com.predic8.membrane.core.interceptor.lang.SetCookiesInterceptor; -import com.predic8.membrane.core.interceptor.log.LogInterceptor; -import com.predic8.membrane.core.interceptor.oauth2client.MemcachedOriginalExchangeStore; -import com.predic8.membrane.core.interceptor.oauth2client.OAuth2Resource2Interceptor; -import com.predic8.membrane.core.interceptor.ratelimit.RateLimitInterceptor; -import com.predic8.membrane.core.interceptor.rewrite.RewriteInterceptor; -import com.predic8.membrane.core.interceptor.xml.Xml2JsonInterceptor; -import com.predic8.membrane.core.openapi.serviceproxy.APIProxy; +import com.predic8.membrane.core.config.spring.*; +import com.predic8.membrane.core.interceptor.authentication.*; +import com.predic8.membrane.core.interceptor.authentication.session.*; +import com.predic8.membrane.core.interceptor.balancer.*; +import com.predic8.membrane.core.interceptor.beautifier.*; +import com.predic8.membrane.core.interceptor.flow.*; +import com.predic8.membrane.core.interceptor.lang.*; +import com.predic8.membrane.core.interceptor.log.*; +import com.predic8.membrane.core.interceptor.oauth2client.*; +import com.predic8.membrane.core.interceptor.ratelimit.*; +import com.predic8.membrane.core.interceptor.rewrite.*; +import com.predic8.membrane.core.interceptor.xml.*; +import com.predic8.membrane.core.openapi.serviceproxy.*; import com.predic8.membrane.core.proxies.AbstractServiceProxy.*; -import com.predic8.membrane.core.util.MemcachedConnector; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.TestInstance; -import org.junit.jupiter.api.TestInstance.Lifecycle; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; - -import java.io.IOException; -import java.io.InputStream; +import com.predic8.membrane.core.util.*; +import org.jetbrains.annotations.*; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.TestInstance.*; +import org.junit.jupiter.params.*; +import org.junit.jupiter.params.provider.*; + +import java.io.*; import java.util.*; -import java.util.stream.Stream; +import java.util.function.*; +import java.util.stream.*; -import static com.predic8.membrane.core.openapi.serviceproxy.OpenAPISpec.YesNoOpenAPIOption.NO; -import static com.predic8.membrane.core.openapi.serviceproxy.OpenAPISpec.YesNoOpenAPIOption.YES; +import static com.predic8.membrane.core.openapi.serviceproxy.OpenAPISpec.YesNoOpenAPIOption.*; import static org.junit.jupiter.api.Assertions.*; @TestInstance(Lifecycle.PER_CLASS) @@ -374,6 +368,11 @@ public Optional getBean(Class clazz) { @Override public void register(String beanName, Object object) {} + + @Override + public T registerIfAbsent(Class type, Supplier supplier) { + return type.cast(null); + } } private static APIProxy parse(String yaml, BeanRegistry reg) { diff --git a/core/src/test/java/com/predic8/membrane/core/kubernetes/client/KubernetesClientTest.java b/core/src/test/java/com/predic8/membrane/core/kubernetes/client/KubernetesClientTest.java index b51289b797..6df0bfa913 100644 --- a/core/src/test/java/com/predic8/membrane/core/kubernetes/client/KubernetesClientTest.java +++ b/core/src/test/java/com/predic8/membrane/core/kubernetes/client/KubernetesClientTest.java @@ -14,7 +14,7 @@ package com.predic8.membrane.core.kubernetes.client; import com.google.common.io.Resources; -import com.predic8.membrane.core.HttpRouter; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Response; import com.predic8.membrane.core.interceptor.AbstractInterceptor; @@ -37,12 +37,11 @@ public class KubernetesClientTest { - private static HttpRouter router; + private static Router router; @BeforeAll - public static void prepare() { - router = new HttpRouter(); - router.getConfig().setHotDeploy(false); + public static void prepare() throws IOException { + router = new TestRouter(); ServiceProxy sp = new ServiceProxy(new ServiceProxyKey(3053), null, 0); sp.getFlow().add(new AbstractInterceptor() { @Override @@ -99,7 +98,7 @@ public Outcome handleRequestInternal(Exchange exc) throws IOException { return RETURN; } }); - router.getRules().add(sp); + router.add(sp); router.start(); } diff --git a/core/src/test/java/com/predic8/membrane/core/lang/AbstractExchangeExpressionTest.java b/core/src/test/java/com/predic8/membrane/core/lang/AbstractExchangeExpressionTest.java index 8089eb10ff..f73de88193 100644 --- a/core/src/test/java/com/predic8/membrane/core/lang/AbstractExchangeExpressionTest.java +++ b/core/src/test/java/com/predic8/membrane/core/lang/AbstractExchangeExpressionTest.java @@ -30,13 +30,13 @@ public abstract class AbstractExchangeExpressionTest { - protected static Router router; + protected static DefaultRouter router; protected static Exchange exchange; protected static Flow flow; @BeforeEach void setUp() throws URISyntaxException { - router = new Router(); + router = new DefaultRouter(); exchange = getRequestBuilder() .header("name","Jelly Fish") .header("foo","42") @@ -61,7 +61,7 @@ void setUp() throws URISyntaxException { @AfterAll static void tearDown() { - router.shutdown(); + router.stop(); } protected abstract Request.Builder getRequestBuilder() throws URISyntaxException; diff --git a/core/src/test/java/com/predic8/membrane/core/lang/TemplateExchangeExpressionTest.java b/core/src/test/java/com/predic8/membrane/core/lang/TemplateExchangeExpressionTest.java index 886472d2d1..528e4c8add 100644 --- a/core/src/test/java/com/predic8/membrane/core/lang/TemplateExchangeExpressionTest.java +++ b/core/src/test/java/com/predic8/membrane/core/lang/TemplateExchangeExpressionTest.java @@ -26,18 +26,18 @@ class TemplateExchangeExpressionTest { - static Exchange exc; - static Language language; - static Router router; + Exchange exc; + Language language; + DefaultRouter router; - @BeforeAll - static void setUp() throws Exception { + @BeforeEach + void setUp() throws Exception { exc = Request.get("/foo") .header("bar", "42") .buildExchange(); exc.setProperty("prop1", "Mars"); language = Language.SPEL; - router = new Router(); + router = new DefaultRouter(); } @Test @@ -65,7 +65,7 @@ void multiple() { assertEquals("Mars - 42 - 6 7", eval("${property.prop1} - ${header.bar} - ${2*3} ${7}")); } - private static String eval(String expr) { + private String eval(String expr) { return new TemplateExchangeExpression(new InterceptorAdapter(router), language, expr).evaluate(exc, REQUEST,String.class); } } \ No newline at end of file diff --git a/core/src/test/java/com/predic8/membrane/core/lang/jsonpath/JsonpathExchangeExpressionTest.java b/core/src/test/java/com/predic8/membrane/core/lang/jsonpath/JsonpathExchangeExpressionTest.java index 10dcccad82..70e8cdb5e4 100644 --- a/core/src/test/java/com/predic8/membrane/core/lang/jsonpath/JsonpathExchangeExpressionTest.java +++ b/core/src/test/java/com/predic8/membrane/core/lang/jsonpath/JsonpathExchangeExpressionTest.java @@ -160,7 +160,7 @@ void number() throws URISyntaxException { assertEquals(314, expr.evaluate(post("/foo").json("314").buildExchange(), REQUEST, Integer.class)); } - private static T evaluateWithEmptyBodyFor(Class type) throws URISyntaxException { + private T evaluateWithEmptyBodyFor(Class type) throws URISyntaxException { return expression(new InterceptorAdapter(router), JSONPATH, "$").evaluate(get("/foo").buildExchange(), REQUEST, type); } } \ No newline at end of file diff --git a/core/src/test/java/com/predic8/membrane/core/lang/xpath/SetPropertyInterceptorXPathTest.java b/core/src/test/java/com/predic8/membrane/core/lang/xpath/SetPropertyInterceptorXPathTest.java index 915149fb6e..7a7a47ea40 100644 --- a/core/src/test/java/com/predic8/membrane/core/lang/xpath/SetPropertyInterceptorXPathTest.java +++ b/core/src/test/java/com/predic8/membrane/core/lang/xpath/SetPropertyInterceptorXPathTest.java @@ -17,7 +17,6 @@ import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.xml.*; import com.predic8.membrane.core.exchange.*; -import com.predic8.membrane.core.interceptor.*; import com.predic8.membrane.core.interceptor.lang.*; import org.jetbrains.annotations.*; import org.junit.jupiter.api.*; @@ -114,7 +113,7 @@ void unknownPrefix() { i.setLanguage(XPATH); i.setFieldName("firstname"); i.setValue(value); - i.init(new Router()); + i.init(new DefaultRouter()); return i; } diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxyOpenAPITest.java b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxyOpenAPITest.java index b05a0a575c..66b466570a 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxyOpenAPITest.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxyOpenAPITest.java @@ -42,7 +42,7 @@ public class APIProxyOpenAPITest { @BeforeEach public void setUp() { - router = new Router(); + router = new DummyTestRouter(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxySpringConfigurationTest.java b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxySpringConfigurationTest.java index 2dee805714..fe036da966 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxySpringConfigurationTest.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxySpringConfigurationTest.java @@ -19,7 +19,7 @@ import com.predic8.membrane.core.interceptor.log.*; import org.junit.jupiter.api.*; -import static com.predic8.membrane.test.TestUtil.getPathFromResource; +import static com.predic8.membrane.test.TestUtil.*; import static org.junit.jupiter.api.Assertions.*; class APIProxySpringConfigurationTest extends AbstractProxySpringConfigurationTest { @@ -54,31 +54,20 @@ class APIProxySpringConfigurationTest extends AbstractProxySpringConfigurationTe @Test void interceptorSequenceFromSpringConfiguration() { - Router router = startSpringContextAndReturnRouter(publisherSeparate); + DefaultRouter router = startSpringContextAndReturnRouter(publisherSeparate); APIProxy ap = getApiProxy(router); - assertEquals(4, ap.getFlow().size()); - assertInstanceOf(ApiKeysInterceptor.class, ap.getFlow().get(0)); - assertInstanceOf(HeaderFilterInterceptor.class, ap.getFlow().get(1)); - assertInstanceOf(OpenAPIPublisherInterceptor.class, ap.getFlow().get(2)); - assertInstanceOf(LogInterceptor.class, ap.getFlow().get(3)); - } - - @Test - void interceptorSequenceAferInit() { - Router router = startSpringContextAndReturnRouter(publisherSeparate); - APIProxy ap = getApiProxy(router); - ap.init(router); assertEquals(5, ap.getFlow().size()); - assertInstanceOf(OpenAPIInterceptor.class, ap.getFlow().get(0)); // Got added + assertInstanceOf(OpenAPIInterceptor.class, ap.getFlow().get(0)); // Should be added after init() is called on router (Inside bootstrap) assertInstanceOf(ApiKeysInterceptor.class, ap.getFlow().get(1)); assertInstanceOf(HeaderFilterInterceptor.class, ap.getFlow().get(2)); assertInstanceOf(OpenAPIPublisherInterceptor.class, ap.getFlow().get(3)); assertInstanceOf(LogInterceptor.class, ap.getFlow().get(4)); + } @Test void noPublisherNoOpenAPIInterceptor() { - Router router = startSpringContextAndReturnRouter(noPublisherNoOpenAPIInterceptor); + DefaultRouter router = startSpringContextAndReturnRouter(noPublisherNoOpenAPIInterceptor); APIProxy ap = getApiProxy(router); ap.init(router); assertEquals(5, ap.getFlow().size()); diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/AbstractProxySpringConfigurationTest.java b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/AbstractProxySpringConfigurationTest.java index 538c85afc1..7172a33122 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/AbstractProxySpringConfigurationTest.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/AbstractProxySpringConfigurationTest.java @@ -32,14 +32,16 @@ abstract class AbstractProxySpringConfigurationTest { """; - protected static Router startSpringContextAndReturnRouter(String api) { + protected static DefaultRouter startSpringContextAndReturnRouter(String api) { GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(); ctx.load(new ByteArrayResource(config.formatted(api).getBytes())); ctx.refresh(); - return ctx.getBean("router", Router.class); + var router = ctx.getBean("router", DefaultRouter.class); + router.init(); + return router; } - protected static APIProxy getApiProxy(Router router) { + protected static APIProxy getApiProxy(DefaultRouter router) { return router.getRuleManager().getRuleByName("bool-api",APIProxy.class); } } diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/ApiDocsInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/ApiDocsInterceptorTest.java index a4284d77bc..c637fd6fd9 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/ApiDocsInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/ApiDocsInterceptorTest.java @@ -18,8 +18,6 @@ import com.predic8.membrane.core.exchange.*; import com.predic8.membrane.core.exchangestore.*; import com.predic8.membrane.core.http.*; -import com.predic8.membrane.core.transport.http.*; -import com.predic8.membrane.core.util.*; import org.junit.jupiter.api.*; import java.io.*; @@ -38,15 +36,14 @@ class ApiDocsInterceptorTest { private final ObjectMapper om = new ObjectMapper(); - Router router; + DummyTestRouter router; final Exchange exc = new Exchange(null); ApiDocsInterceptor interceptor; APIProxy rule; @BeforeEach public void setUp() throws Exception { - router = new Router(); - router.getConfig().setUriFactory(new URIFactory()); + router = new DummyTestRouter(); exc.setRequest(new Request.Builder().get("/foo").build()); exc.setOriginalRequestUri("/foo"); @@ -56,7 +53,6 @@ public void setUp() throws Exception { rule = createProxy(router, spec); router.setExchangeStore(new ForgetfulExchangeStore()); - router.setTransport(new HttpTransport()); router.add(rule); router.init(); @@ -71,7 +67,7 @@ void tearDown() { @AfterAll void tearDownAll() { - router.shutdown(); + router.stop(); } @Test @@ -93,7 +89,7 @@ void initializeRuleApiSpecsTest() { @Test void initializeEmptyRuleApiSpecsTest() { ApiDocsInterceptor adi = new ApiDocsInterceptor(); - adi.init(new Router()); + adi.init(new DummyTestRouter()); assertEquals(new HashMap<>(), adi.initializeRuleApiSpecs()); } diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPI31ReferencesTest.java b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPI31ReferencesTest.java index a6ee16e7d0..28cd672cca 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPI31ReferencesTest.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPI31ReferencesTest.java @@ -40,8 +40,8 @@ public class OpenAPI31ReferencesTest { @BeforeAll public static void setUp() throws Exception { - router = new HttpRouter(); - router.getConfig().setUriFactory(new URIFactory()); + router = new TestRouter(); + router.getConfiguration().setUriFactory(new URIFactory()); OpenAPISpec spec = new OpenAPISpec(); spec.location = getPathFromResource( "openapi/specs/oas31/request-reference.yaml"); @@ -50,19 +50,19 @@ public static void setUp() throws Exception { api = new APIProxy(); api.setPort(2000); api.setSpecs(List.of(spec)); - router.getRuleManager().addProxyAndOpenPortIfNew(api); + router.add(api); APIProxy backend = new APIProxy(); backend.setPort(3000); backend.getFlow().add(new ReturnInterceptor()); - router.getRuleManager().addProxyAndOpenPortIfNew(backend); + router.add(backend); - router.init(); + router.start(); } @AfterAll public static void shutdown() { - router.shutdown(); + router.stop(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPI31Test.java b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPI31Test.java index 22584d01b3..ae5a84442f 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPI31Test.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPI31Test.java @@ -18,11 +18,12 @@ import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.*; -import com.predic8.membrane.core.http.*; -import com.predic8.membrane.core.interceptor.*; -import com.predic8.membrane.core.util.*; import org.junit.jupiter.api.*; +import java.net.*; + +import static com.predic8.membrane.core.http.Request.get; +import static com.predic8.membrane.core.interceptor.Outcome.RETURN; import static com.predic8.membrane.core.openapi.util.OpenAPITestUtils.createProxy; import static com.predic8.membrane.test.TestUtil.getPathFromResource; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -36,14 +37,13 @@ public class OpenAPI31Test { final Exchange exc = new Exchange(null); @BeforeEach - public void setUp() { - Router router = new Router(); - router.getConfig().setUriFactory(new URIFactory()); + void setUp() throws URISyntaxException { + Router router = new DummyTestRouter(); petstore_v3_1 = new OpenAPISpec(); petstore_v3_1.location = getPathFromResource("openapi/specs/petstore-v3.1.json"); - exc.setRequest(new Request.Builder().method("GET").build()); + exc.setRequest(get("/foo").build()); interceptor = new OpenAPIInterceptor(createProxy(router, petstore_v3_1)); interceptor.init(router); @@ -52,7 +52,6 @@ public void setUp() { @Test void simple() { exc.getRequest().setUri("/pets"); - Outcome actual = interceptor.handleRequest(exc); - assertEquals(Outcome.RETURN, actual); + assertEquals(RETURN, interceptor.handleRequest(exc)); } } diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIInterceptorTest.java index 2bd3a7da01..38e2cd8b9a 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIInterceptorTest.java @@ -47,9 +47,8 @@ class OpenAPIInterceptorTest { OpenAPIInterceptor interceptor3Server; @BeforeEach - public void setUp() { - router = new Router(); - router.getConfig().setUriFactory(new URIFactory()); + void setUp() { + router = new DummyTestRouter(); specInfoServers = new OpenAPISpec(); specInfoServers.location = getPathFromResource("openapi/specs/info-servers.yml"); @@ -68,6 +67,11 @@ public void setUp() { interceptor3Server.init(router); } + @AfterEach + void tearDown() { + router.stop(); + } + @Test void getMatchingBasePathOneServer() { exc.getRequest().setUri("/base/v2/foo"); diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIPublisherInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIPublisherInterceptorTest.java index f055f13b62..990bd508fc 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIPublisherInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIPublisherInterceptorTest.java @@ -51,8 +51,8 @@ public class OpenAPIPublisherInterceptorTest { @BeforeEach void setUp() { - Router router = new Router(); - router.getConfig().setUriFactory(new URIFactory()); + DefaultRouter router = new DefaultRouter(); + router.getConfiguration().setUriFactory(new URIFactory()); router.setBaseLocation(""); openAPIRecordFactory = new OpenAPIRecordFactory(router); OpenAPISpec spec = new OpenAPISpec(); diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIRecordFactoryTest.java b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIRecordFactoryTest.java index 7b44dcd5c5..f9da9b6d6d 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIRecordFactoryTest.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIRecordFactoryTest.java @@ -30,7 +30,7 @@ class OpenAPIRecordFactoryTest { @BeforeAll static void setUp() { - Router router = new Router(); + DummyTestRouter router = new DummyTestRouter(); router.setBaseLocation("src/test/resources/openapi/specs/"); factory = new OpenAPIRecordFactory(router); } diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIRecordTest.java b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIRecordTest.java index ab081d8576..5e25854db9 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIRecordTest.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIRecordTest.java @@ -16,7 +16,7 @@ package com.predic8.membrane.core.openapi.serviceproxy; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.DefaultRouter; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.Request; import com.predic8.membrane.core.proxies.NullProxy; @@ -29,8 +29,8 @@ class OpenAPIRecordTest { @BeforeEach void setUp() { - Router router = new Router(); - router.getConfig().setUriFactory(new URIFactory()); + DefaultRouter router = new DefaultRouter(); + router.getConfiguration().setUriFactory(new URIFactory()); router.setBaseLocation(""); get.setRequest(new Request.Builder().method("GET").build()); diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/RewriteTest.java b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/RewriteTest.java index d47e8faedf..0bc0444ae1 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/RewriteTest.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/RewriteTest.java @@ -49,8 +49,8 @@ void setUp() { rewriteAll.protocol = "https"; rewriteAll.basePath = "/foo"; - Router router = new Router(); - router.getConfig().setUriFactory(new URIFactory()); + DefaultRouter router = new DefaultRouter(); + router.getConfiguration().setUriFactory(new URIFactory()); router.setBaseLocation(""); OpenAPIRecordFactory openAPIRecordFactory = new OpenAPIRecordFactory(router); diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/Swagger20Test.java b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/Swagger20Test.java index bb8bef51db..6cb0bc605f 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/Swagger20Test.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/Swagger20Test.java @@ -19,10 +19,7 @@ import com.predic8.membrane.core.*; import com.predic8.membrane.core.interceptor.flow.*; import com.predic8.membrane.core.interceptor.templating.*; -import com.predic8.membrane.core.proxies.*; import com.predic8.membrane.core.proxies.AbstractServiceProxy.*; -import com.predic8.membrane.core.transport.http.*; -import com.predic8.membrane.core.util.*; import org.hamcrest.*; import org.jetbrains.annotations.*; import org.junit.jupiter.api.*; @@ -38,14 +35,10 @@ public class Swagger20Test { @BeforeEach public void setUp() throws Exception { - - router = new Router(); - router.setTransport(new HttpTransport()); - router.getConfig().setUriFactory(new URIFactory()); - - router.getRuleManager().addProxyAndOpenPortIfNew(getApiProxy()); - router.getRuleManager().addProxyAndOpenPortIfNew(getTargetProxy()); - router.init(); + router = new TestRouter(); + router.add(getApiProxy()); + router.add(getTargetProxy()); + router.start(); } private @NotNull APIProxy getApiProxy() { @@ -73,7 +66,7 @@ public void setUp() throws Exception { @AfterEach public void tearDown() { - router.shutdown(); + router.stop(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/XMembraneExtensionSecurityTest.java b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/XMembraneExtensionSecurityTest.java index b6fc81409c..7af285c62b 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/XMembraneExtensionSecurityTest.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/XMembraneExtensionSecurityTest.java @@ -32,7 +32,7 @@ public class XMembraneExtensionSecurityTest { @BeforeEach void setUp() { - Router router = new Router(); + DummyTestRouter router = new DummyTestRouter(); router.setBaseLocation(""); OpenAPIRecordFactory factory = new OpenAPIRecordFactory(router); OpenAPISpec spec = new OpenAPISpec(); diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/validators/security/AbstractSecurityValidatorTest.java b/core/src/test/java/com/predic8/membrane/core/openapi/validators/security/AbstractSecurityValidatorTest.java index 90cd11bb06..4946268c59 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/validators/security/AbstractSecurityValidatorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/validators/security/AbstractSecurityValidatorTest.java @@ -42,8 +42,6 @@ protected Exchange getExchange(String method, String path, SecurityScheme scheme } protected static Router getRouter() { - Router router = new Router(); - router.getConfig().setUriFactory(new URIFactory()); - return router; + return new DummyTestRouter(); } } diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/validators/security/BasicAuthSecurityValidationTest.java b/core/src/test/java/com/predic8/membrane/core/openapi/validators/security/BasicAuthSecurityValidationTest.java index a07a7e3999..41007fee43 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/validators/security/BasicAuthSecurityValidationTest.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/validators/security/BasicAuthSecurityValidationTest.java @@ -18,16 +18,15 @@ import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.*; -import com.predic8.membrane.core.http.*; import com.predic8.membrane.core.interceptor.*; import com.predic8.membrane.core.interceptor.authentication.*; import com.predic8.membrane.core.interceptor.authentication.session.*; import com.predic8.membrane.core.openapi.serviceproxy.*; -import com.predic8.membrane.core.util.*; import org.junit.jupiter.api.*; import java.util.*; +import static com.predic8.membrane.core.http.Request.get; import static com.predic8.membrane.core.interceptor.Outcome.*; import static com.predic8.membrane.core.openapi.serviceproxy.OpenAPISpec.YesNoOpenAPIOption.*; import static com.predic8.membrane.core.openapi.util.OpenAPITestUtils.*; @@ -42,8 +41,7 @@ public class BasicAuthSecurityValidationTest { @BeforeEach void setUpSpec() { - Router router = new Router(); - router.getConfig().setUriFactory(new URIFactory()); + Router router = new DummyTestRouter(); OpenAPISpec spec = new OpenAPISpec(); spec.location = getPathFromResource("openapi/specs/security/http-basic.yml"); @@ -64,7 +62,7 @@ void setUpSpec() { @Test void noAuthHeader() throws Exception { - Exchange exc = Request.get("/v1/foo").buildExchange(); + Exchange exc = get("/v1/foo").buildExchange(); exc.setOriginalRequestUri("/v1/foo"); assertEquals(ABORT, baInterceptor.handleRequest(exc)); // TODO Should we return RETURN instead. How is it in OAuth2? } @@ -72,15 +70,13 @@ void noAuthHeader() throws Exception { @Test void withAuthorizationHeader() throws Exception { - Exchange exc = Request.get("/v1/foo").authorization("alice","secret").buildExchange(); + Exchange exc = get("/v1/foo").authorization("alice","secret").buildExchange(); exc.setOriginalRequestUri("/v1/foo"); Outcome outcome = baInterceptor.handleRequest(exc); - assertEquals(CONTINUE,outcome); outcome = oasInterceptor.handleRequest(exc); - assertEquals(CONTINUE, outcome); } } diff --git a/core/src/test/java/com/predic8/membrane/core/openapi/validators/security/JWTInterceptorAndSecurityValidatorTest.java b/core/src/test/java/com/predic8/membrane/core/openapi/validators/security/JWTInterceptorAndSecurityValidatorTest.java index daed523211..9f080e6685 100644 --- a/core/src/test/java/com/predic8/membrane/core/openapi/validators/security/JWTInterceptorAndSecurityValidatorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/openapi/validators/security/JWTInterceptorAndSecurityValidatorTest.java @@ -18,12 +18,10 @@ import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.*; -import com.predic8.membrane.core.exchangestore.*; import com.predic8.membrane.core.http.Request; import com.predic8.membrane.core.interceptor.jwt.*; import com.predic8.membrane.core.openapi.serviceproxy.*; import com.predic8.membrane.core.security.*; -import com.predic8.membrane.core.transport.http.*; import org.jetbrains.annotations.*; import org.jose4j.jwk.*; import org.jose4j.jws.*; @@ -34,37 +32,38 @@ import java.util.*; import static com.predic8.membrane.core.exchange.Exchange.SECURITY_SCHEMES; +import static com.predic8.membrane.core.http.Request.get; import static com.predic8.membrane.core.openapi.util.OpenAPITestUtils.*; import static com.predic8.membrane.test.TestUtil.getPathFromResource; import static org.junit.jupiter.api.Assertions.*; public class JWTInterceptorAndSecurityValidatorTest { - public static final String SPEC_LOCATION = getPathFromResource( "openapi/openapi-proxy/no-extensions.yml"); - APIProxy proxy; + private static final String SPEC_LOCATION = getPathFromResource( "openapi/openapi-proxy/no-extensions.yml"); + private Router router; + private APIProxy proxy; RsaJsonWebKey privateKey; - @BeforeEach - public void setUp() throws Exception { - - Router router = new Router(); + void setUp() throws Exception { + router = new DummyTestRouter(); proxy = createProxy(router, getSpec()); privateKey = RsaJwkGenerator.generateJwk(2048); privateKey.setKeyId("membrane"); proxy.getFlow().add(getJwtAuthInterceptor(router)); + } - router.setTransport(new HttpTransport()); - router.setExchangeStore(new ForgetfulExchangeStore()); - router.init(); + @AfterEach + void tearDown() { + router.stop(); } @Test - public void checkIfScopesAreStoredInProperty() throws Exception { - Exchange exc = new Request.Builder().get("/foo").header("Authorization", "bearer " + getSignedJwt(privateKey, getJwtClaimsStringScopesList())).buildExchange(); + void checkIfScopesAreStoredInProperty() throws Exception { + Exchange exc = get("/foo").header("Authorization", "bearer " + getSignedJwt(privateKey, getJwtClaimsStringScopesList())).buildExchange(); callInterceptorChain(exc); //noinspection unchecked @@ -72,7 +71,7 @@ public void checkIfScopesAreStoredInProperty() throws Exception { } @Test - public void checkIfScopesCanBeReadFromListType() throws Exception { + void checkIfScopesCanBeReadFromListType() throws Exception { Exchange exc = new Request.Builder().get("/foo").header("Authorization", "bearer " + getSignedJwt(privateKey, getJwtClaimsArrayScopesList())).buildExchange(); callInterceptorChain(exc); diff --git a/core/src/test/java/com/predic8/membrane/core/proxies/APIProxyKeyTest.java b/core/src/test/java/com/predic8/membrane/core/proxies/APIProxyKeyTest.java index fdb26947a5..3db31d67e8 100644 --- a/core/src/test/java/com/predic8/membrane/core/proxies/APIProxyKeyTest.java +++ b/core/src/test/java/com/predic8/membrane/core/proxies/APIProxyKeyTest.java @@ -30,20 +30,20 @@ public class APIProxyKeyTest { private static Router router; - @BeforeAll - public static void setup() { - router = new HttpRouter(); + @BeforeEach + public void setup() { + router = new TestRouter(); } - @AfterAll - public static void shutdown() { - router.shutdown(); + @AfterEach + public void shutdown() { + router.stop(); } @Test void serviceProxyPathSubpath() throws Exception { registerApiProxy("/foo", "Baz"); - router.init(); + router.start(); // @formatter:off when() @@ -57,7 +57,7 @@ void serviceProxyPathSubpath() throws Exception { @Test void apiProxyPathSubpath() throws Exception { registerApiProxy("/foo", "Baz"); - router.init(); + router.start(); when() .get("http://localhost:3000/foo/bar") .then() @@ -67,7 +67,7 @@ void apiProxyPathSubpath() throws Exception { @Test void apiProxyPathMatch() throws Exception { registerApiProxy("/foo", "Baz"); - router.init(); + router.start(); when() .get("http://localhost:3000/foo") .then() @@ -78,7 +78,7 @@ void apiProxyPathMatch() throws Exception { void apiProxyPathFallthrough() throws Exception { registerApiProxy("/foo", "Baz"); registerApiProxy(null, "Foobar"); - router.init(); + router.start(); when() .get("http://localhost:3000") .then() @@ -86,7 +86,7 @@ void apiProxyPathFallthrough() throws Exception { } private static void registerApiProxy(String path, String body) throws IOException { - router.getRuleManager().addProxyAndOpenPortIfNew(new APIProxy() {{ + router.add(new APIProxy() {{ setKey(new APIProxyKey("127.0.0.1", "localhost", 3000, path, "*", null,false)); getFlow().add(new TemplateInterceptor() {{ setSrc(body); diff --git a/core/src/test/java/com/predic8/membrane/core/proxies/AbstractServiceProxyExpressionTest.java b/core/src/test/java/com/predic8/membrane/core/proxies/AbstractServiceProxyExpressionTest.java deleted file mode 100644 index 0ea1f3c3ff..0000000000 --- a/core/src/test/java/com/predic8/membrane/core/proxies/AbstractServiceProxyExpressionTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright 2025 predic8 GmbH, www.predic8.com - - 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 com.predic8.membrane.core.proxies; - -import com.predic8.membrane.AbstractTestWithRouter; -import com.predic8.membrane.core.HttpRouter; -import com.predic8.membrane.core.config.Path; -import com.predic8.membrane.core.exchange.Exchange; -import com.predic8.membrane.core.http.Request; -import com.predic8.membrane.core.interceptor.DispatchingInterceptor; -import com.predic8.membrane.core.interceptor.flow.ReturnInterceptor; -import com.predic8.membrane.core.interceptor.log.LogInterceptor; -import com.predic8.membrane.core.openapi.serviceproxy.APIProxy; -import com.predic8.membrane.core.openapi.serviceproxy.APIProxyKey; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.net.URISyntaxException; - -import static com.predic8.membrane.core.interceptor.flow.invocation.FlowTestInterceptors.A; -import static io.restassured.RestAssured.given; -import static org.hamcrest.Matchers.equalToIgnoringCase; -import static org.junit.jupiter.api.Assertions.assertEquals; - -class AbstractServiceProxyExpressionTest extends AbstractTestWithRouter { - - @Test - void targetWithExpression() throws IOException, URISyntaxException { - HttpRouter r = new HttpRouter(); - Exchange rq = new Request.Builder().get("http://localhost:2000/").buildExchange(); - APIProxy api = new APIProxy() {{ - setTarget(new Target() {{ - setUrl("http://localhost:${2000 + 1000}"); - }}); - }}; - rq.setProxy(api); - api.init(r); - - DispatchingInterceptor di = new DispatchingInterceptor() {{ - router = r; - }}; - di.handleRequest(rq); - - assertEquals("http://localhost:3000/", rq.getDestinations().getFirst()); - } -} \ No newline at end of file diff --git a/core/src/test/java/com/predic8/membrane/core/proxies/InternalProxyTest.java b/core/src/test/java/com/predic8/membrane/core/proxies/InternalProxyTest.java index 92b3b6b7cd..8d1279dbc2 100644 --- a/core/src/test/java/com/predic8/membrane/core/proxies/InternalProxyTest.java +++ b/core/src/test/java/com/predic8/membrane/core/proxies/InternalProxyTest.java @@ -14,25 +14,22 @@ package com.predic8.membrane.core.proxies; import com.predic8.membrane.core.*; -import com.predic8.membrane.core.interceptor.flow.ResponseInterceptor; -import com.predic8.membrane.core.interceptor.flow.ReturnInterceptor; -import com.predic8.membrane.core.interceptor.groovy.GroovyInterceptor; -import com.predic8.membrane.core.interceptor.log.LogInterceptor; +import com.predic8.membrane.core.interceptor.flow.*; +import com.predic8.membrane.core.interceptor.groovy.*; import com.predic8.membrane.core.openapi.serviceproxy.*; -import org.hamcrest.*; import org.junit.jupiter.api.*; import static com.predic8.membrane.core.interceptor.flow.invocation.FlowTestInterceptors.*; import static io.restassured.RestAssured.*; -import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.*; class InternalProxyTest { - private static Router router; + private Router router; - @BeforeAll - public static void setup() throws Exception { - router = new HttpRouter(); + @BeforeEach + void setup() throws Exception { + router = new TestRouter(); router.add(new APIProxy() {{ key = new APIProxyKey(2001); @@ -108,13 +105,13 @@ public static void setup() throws Exception { interceptors.add(RETURN); }}); - router.init(); + router.start(); } - @AfterAll - public static void teardown() { - router.shutdown(); + @AfterEach + void teardown() { + router.stop(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/proxies/ProxyRuleTest.java b/core/src/test/java/com/predic8/membrane/core/proxies/ProxyRuleTest.java index 3bad491115..c991f743f0 100644 --- a/core/src/test/java/com/predic8/membrane/core/proxies/ProxyRuleTest.java +++ b/core/src/test/java/com/predic8/membrane/core/proxies/ProxyRuleTest.java @@ -25,12 +25,12 @@ public class ProxyRuleTest { - private static Router router; + private static DefaultRouter router; private static ProxyRule proxy; @BeforeAll public static void setUp() { - router = Router.init("src/test/resources/proxy-rules-test-monitor-beans.xml"); + router = RouterXmlBootstrap.initByXML("src/test/resources/proxy-rules-test-monitor-beans.xml"); proxy = new ProxyRule(new ProxyRuleKey(8888)); proxy.setName("Rule 1"); // TODO: this is not possible anymore rule.setInboundTLS(true); @@ -40,7 +40,7 @@ public static void setUp() { @AfterAll public static void tearDown() { - router.shutdown(); + router.stop(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/proxies/ProxySSLTest.java b/core/src/test/java/com/predic8/membrane/core/proxies/ProxySSLTest.java index b5ee17935c..0fcd8c41c1 100644 --- a/core/src/test/java/com/predic8/membrane/core/proxies/ProxySSLTest.java +++ b/core/src/test/java/com/predic8/membrane/core/proxies/ProxySSLTest.java @@ -13,31 +13,25 @@ limitations under the License. */ package com.predic8.membrane.core.proxies; -import com.predic8.membrane.core.Router; -import com.predic8.membrane.core.RuleManager; -import com.predic8.membrane.core.config.security.KeyStore; -import com.predic8.membrane.core.config.security.SSLParser; -import com.predic8.membrane.core.config.security.TrustStore; -import com.predic8.membrane.core.exchange.Exchange; -import com.predic8.membrane.core.http.Request; -import com.predic8.membrane.core.interceptor.AbstractInterceptor; -import com.predic8.membrane.core.interceptor.CountInterceptor; -import com.predic8.membrane.core.interceptor.Outcome; -import com.predic8.membrane.core.resolver.ResolverMap; -import com.predic8.membrane.core.transport.http.HttpClient; -import com.predic8.membrane.core.transport.http.client.HttpClientConfiguration; -import com.predic8.membrane.core.transport.http.client.ProxyConfiguration; -import com.predic8.membrane.core.transport.ssl.StaticSSLContext; +import com.predic8.membrane.core.*; +import com.predic8.membrane.core.config.security.*; +import com.predic8.membrane.core.exchange.*; +import com.predic8.membrane.core.http.*; +import com.predic8.membrane.core.interceptor.*; +import com.predic8.membrane.core.resolver.*; +import com.predic8.membrane.core.transport.http.*; +import com.predic8.membrane.core.transport.http.client.*; +import com.predic8.membrane.core.transport.ssl.*; import org.jetbrains.annotations.*; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.*; +import org.junit.jupiter.params.provider.*; -import java.util.Arrays; -import java.util.Collection; -import java.util.concurrent.atomic.AtomicInteger; +import java.io.*; +import java.util.*; +import java.util.concurrent.atomic.*; -import static com.predic8.membrane.core.exchange.Exchange.SSL_CONTEXT; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static com.predic8.membrane.core.exchange.Exchange.*; +import static org.junit.jupiter.api.Assertions.*; public class ProxySSLTest { public static Collection data() { @@ -49,21 +43,21 @@ public static Collection data() { @ParameterizedTest @MethodSource("data") void test(boolean backendUsesSSL, boolean proxyUsesSSL, int backendPort, int proxyPort) throws Exception { - Router backend = createBackend(backendUsesSSL, backendPort); + DefaultRouter backend = createBackend(backendUsesSSL, backendPort); AtomicInteger proxyCounter = new AtomicInteger(); - Router proxy = createProxy(proxyUsesSSL, proxyPort, proxyCounter); + DefaultRouter proxy = createProxy(proxyUsesSSL, proxyPort, proxyCounter); testClient(backendUsesSSL, backendPort, createAndConfigureClient(proxyUsesSSL, proxyPort), proxyCounter); - proxy.shutdown(); - backend.shutdown(); + proxy.stop(); + backend.stop(); } - private static @NotNull Router createProxy(boolean proxyUsesSSL, int proxyPort, AtomicInteger proxyCounter) { - Router proxy = new Router(); - proxy.getConfig().setHotDeploy(false); + private static @NotNull DefaultRouter createProxy(boolean proxyUsesSSL, int proxyPort, AtomicInteger proxyCounter) throws IOException { + DefaultRouter proxy = new DefaultRouter(); + proxy.getConfiguration().setHotDeploy(false); ProxyRule rule = new ProxyRule(new ProxyRuleKey(proxyPort)); rule.getFlow().add(new AbstractInterceptor() { @Override @@ -75,7 +69,7 @@ public Outcome handleRequest(Exchange exc) { if (proxyUsesSSL) { rule.setSslInboundParser(getSslParser("classpath:/ssl-rsa2.keystore")); } - proxy.getRuleManager().addProxy(rule, RuleManager.RuleDefinitionSource.MANUAL); + proxy.add(rule); proxy.start(); return proxy; } @@ -115,16 +109,16 @@ private static void testClient(boolean backendUsesSSL, int backendPort, HttpClie return new HttpClient(httpClientConfiguration); } - private static @NotNull Router createBackend(boolean backendUsesSSL, int backendPort) { + private static @NotNull DefaultRouter createBackend(boolean backendUsesSSL, int backendPort) throws IOException { // Step 1: create the backend - Router backend = new Router(); - backend.getConfig().setHotDeploy(false); + DefaultRouter backend = new DefaultRouter(); + backend.getConfiguration().setHotDeploy(false); ServiceProxy sp = new ServiceProxy(new ServiceProxyKey(backendPort), null, 0); if (backendUsesSSL) { sp.setSslInboundParser(getSslParser("classpath:/ssl-rsa.keystore")); } sp.getFlow().add(new CountInterceptor()); - backend.getRuleManager().addProxy(sp, RuleManager.RuleDefinitionSource.MANUAL); + backend.add(sp); backend.start(); return backend; } diff --git a/core/src/test/java/com/predic8/membrane/core/proxies/ProxyTest.java b/core/src/test/java/com/predic8/membrane/core/proxies/ProxyTest.java index 8283516eee..f9f75bc195 100644 --- a/core/src/test/java/com/predic8/membrane/core/proxies/ProxyTest.java +++ b/core/src/test/java/com/predic8/membrane/core/proxies/ProxyTest.java @@ -14,47 +14,37 @@ package com.predic8.membrane.core.proxies; -import com.predic8.membrane.core.HttpRouter; +import com.predic8.membrane.core.*; +import com.predic8.membrane.core.config.security.*; import com.predic8.membrane.core.config.security.KeyStore; -import com.predic8.membrane.core.config.security.SSLParser; -import com.predic8.membrane.core.exchange.Exchange; -import com.predic8.membrane.core.http.Response; -import com.predic8.membrane.core.interceptor.AbstractInterceptor; -import com.predic8.membrane.core.interceptor.Outcome; -import org.apache.http.HttpHost; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.conn.scheme.Scheme; -import org.apache.http.conn.ssl.AllowAllHostnameVerifier; -import org.apache.http.conn.ssl.SSLSocketFactory; -import org.apache.http.conn.ssl.TrustAllStrategy; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.util.EntityUtils; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.util.concurrent.atomic.AtomicReference; - +import com.predic8.membrane.core.exchange.*; +import com.predic8.membrane.core.http.*; +import com.predic8.membrane.core.interceptor.*; +import org.apache.http.*; +import org.apache.http.client.config.*; +import org.apache.http.client.methods.*; +import org.apache.http.conn.ssl.*; +import org.apache.http.impl.client.*; +import org.apache.http.util.*; +import org.junit.jupiter.api.*; + +import java.io.*; +import java.security.*; +import java.util.concurrent.atomic.*; + +import static com.predic8.membrane.core.interceptor.Outcome.*; import static org.junit.jupiter.api.Assertions.*; public class ProxyTest { - static HttpRouter router; + static Router router; static final AtomicReference lastMethod = new AtomicReference<>(); @BeforeAll - public static void init() { + public static void init() throws IOException { - router = new HttpRouter(); - router.getConfig().setHotDeploy(false); + router = new TestRouter(); + router.getConfiguration().setHotDeploy(false); ProxyRule rule = new ProxyRule(new ProxyRuleKey(3055)); rule.getFlow().add(new AbstractInterceptor() { @@ -64,17 +54,17 @@ public Outcome handleRequest(Exchange exc) { return super.handleRequest(exc); } }); - router.getRules().add(rule); + router.add(rule); ServiceProxy sp = new ServiceProxy(new ServiceProxyKey(3056), null, 0); sp.getFlow().add(new AbstractInterceptor() { @Override public Outcome handleRequest(Exchange exc) { exc.setResponse(Response.ok("secret1").build()); - return Outcome.RETURN; + return RETURN; } }); - router.getRules().add(sp); + router.add(sp); SSLParser sslParser = new SSLParser(); sslParser.setKeyStore(new KeyStore()); @@ -86,17 +76,17 @@ public Outcome handleRequest(Exchange exc) { @Override public Outcome handleRequest(Exchange exc) { exc.setResponse(Response.ok("secret2").build()); - return Outcome.RETURN; + return RETURN; } }); - router.getRules().add(sp2); + router.add(sp2); router.start(); } @AfterAll public static void done() { - router.shutdown(); + router.stop(); } @Test @@ -119,7 +109,6 @@ public void runHTTP() throws IOException { public void runHTTPS() throws IOException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, InterruptedException { SSLSocketFactory sslsf = new SSLSocketFactory("TLS", null, null, null, null, new TrustAllStrategy(), new AllowAllHostnameVerifier()); - Scheme https = new Scheme("https", 3057, sslsf); CloseableHttpClient hc = HttpClientBuilder.create() .setSSLSocketFactory(sslsf) diff --git a/core/src/test/java/com/predic8/membrane/core/proxies/SOAPProxyTest.java b/core/src/test/java/com/predic8/membrane/core/proxies/SOAPProxyTest.java index 5f421c6b40..7288ff0221 100644 --- a/core/src/test/java/com/predic8/membrane/core/proxies/SOAPProxyTest.java +++ b/core/src/test/java/com/predic8/membrane/core/proxies/SOAPProxyTest.java @@ -14,12 +14,10 @@ package com.predic8.membrane.core.proxies; import com.predic8.membrane.core.*; -import com.predic8.membrane.core.exchangestore.*; import com.predic8.membrane.core.interceptor.flow.*; import com.predic8.membrane.core.interceptor.templating.*; import com.predic8.membrane.core.openapi.serviceproxy.*; import com.predic8.membrane.core.openapi.util.*; -import com.predic8.membrane.core.transport.http.*; import org.junit.jupiter.api.*; import java.io.*; @@ -39,9 +37,7 @@ public class SOAPProxyTest { void setUp() throws IOException { proxy = new SOAPProxy(); proxy.setPort(2000); - router = new Router(); - router.setTransport(new HttpTransport()); - router.setExchangeStore(new ForgetfulExchangeStore()); + router = new DefaultRouter(); APIProxy backend = new APIProxy(); backend.setKey(new APIProxyKey(2001)); @@ -55,21 +51,21 @@ void setUp() throws IOException { @AfterEach void shutDown() { - router.shutdown(); + router.stop(); } @Test void parseWSDL() throws Exception { proxy.setWsdl("classpath:/ws/cities.wsdl"); router.add(proxy); - router.init(); + router.start(); } @Test void parseWSDLWithMultiplePortsPerService() throws Exception { proxy.setWsdl("classpath:/blz-service.wsdl"); router.add(proxy); - router.init(); + router.start(); } @Test @@ -77,7 +73,7 @@ void parseWSDLWithMultipleServices() throws Exception { proxy.setWsdl("classpath:/ws/cities-2-services.wsdl"); proxy.setServiceName("CityServiceA"); router.add(proxy); - router.init(); + router.start(); } @Test @@ -85,7 +81,7 @@ void parseWSDLWithMultipleServicesForAGivenServiceA() throws Exception { proxy.setServiceName("CityServiceA"); proxy.setWsdl("classpath:/ws/cities-2-services.wsdl"); router.add(proxy); - router.init(); + router.start(); } @Test @@ -93,7 +89,7 @@ void parseWSDLWithMultipleServicesForAGivenServiceB() throws Exception { proxy.setServiceName("CityServiceB"); proxy.setWsdl("classpath:/ws/cities-2-services.wsdl"); router.add(proxy); - router.init(); + router.start(); // @formatter: off given().when() @@ -107,10 +103,11 @@ void parseWSDLWithMultipleServicesForAGivenServiceB() throws Exception { } @Test - void parseWSDLWithMultipleServicesForAWrongService() throws Exception { + void parseWSDLWithMultipleServicesForAWrongService() { proxy.setServiceName("WrongService"); proxy.setWsdl("classpath:/ws/cities-2-services.wsdl"); - router.add(proxy); - assertThrows(IllegalArgumentException.class, () -> router.init()); + + assertThrows(IllegalArgumentException.class, () -> {router.add(proxy); router.start(); + }); } } \ No newline at end of file diff --git a/core/src/test/java/com/predic8/membrane/core/proxies/SOAPProxyWSDLPublisherInterceptorTest.java b/core/src/test/java/com/predic8/membrane/core/proxies/SOAPProxyWSDLPublisherInterceptorTest.java index dae0c8f08a..805d9919d7 100644 --- a/core/src/test/java/com/predic8/membrane/core/proxies/SOAPProxyWSDLPublisherInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/core/proxies/SOAPProxyWSDLPublisherInterceptorTest.java @@ -28,8 +28,7 @@ public class SOAPProxyWSDLPublisherInterceptorTest { @BeforeAll static void setUp() { - router = new HttpRouter(); - router.getConfig().setHotDeploy(false); + router = new TestRouter(); } @AfterAll diff --git a/core/src/test/java/com/predic8/membrane/core/proxies/ServiceProxyTest.java b/core/src/test/java/com/predic8/membrane/core/proxies/ServiceProxyTest.java index c7b7d57d51..29b6329cf0 100644 --- a/core/src/test/java/com/predic8/membrane/core/proxies/ServiceProxyTest.java +++ b/core/src/test/java/com/predic8/membrane/core/proxies/ServiceProxyTest.java @@ -30,17 +30,17 @@ class ServiceProxyTest { @BeforeAll public static void setup() throws Exception { - router = new HttpRouter(); + router = new TestRouter(); APIProxy proxyWithOutTarget = new APIProxy() {{ key = new APIProxyKey(2000); }}; router.add(proxyWithOutTarget); - router.init(); + router.start(); } @AfterAll public static void shutdown() { - router.shutdown(); + router.stop(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/proxies/ServiceProxyWSDLInterceptorsTest.java b/core/src/test/java/com/predic8/membrane/core/proxies/ServiceProxyWSDLInterceptorsTest.java index a3e16c0513..fa2f65df8e 100644 --- a/core/src/test/java/com/predic8/membrane/core/proxies/ServiceProxyWSDLInterceptorsTest.java +++ b/core/src/test/java/com/predic8/membrane/core/proxies/ServiceProxyWSDLInterceptorsTest.java @@ -28,16 +28,16 @@ @SuppressWarnings("HttpUrlsUsage") public class ServiceProxyWSDLInterceptorsTest { - static Router router; + Router router; - @BeforeAll - static void setUp() { - router = new HttpRouter(); - router.getConfig().setHotDeploy(false); + @BeforeEach + void setUp() { + router = new TestRouter(); + router.getConfiguration().setHotDeploy(false); } - @AfterAll - static void teardown() { + @AfterEach + void teardown() { router.stop(); } diff --git a/core/src/test/java/com/predic8/membrane/core/proxies/TargetURLExpressionTest.java b/core/src/test/java/com/predic8/membrane/core/proxies/TargetURLExpressionTest.java new file mode 100644 index 0000000000..dbe6aa5e53 --- /dev/null +++ b/core/src/test/java/com/predic8/membrane/core/proxies/TargetURLExpressionTest.java @@ -0,0 +1,61 @@ +/* Copyright 2025 predic8 GmbH, www.predic8.com + + 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 com.predic8.membrane.core.proxies; + +import com.predic8.membrane.core.*; +import com.predic8.membrane.core.exchange.*; +import com.predic8.membrane.core.interceptor.*; +import com.predic8.membrane.core.openapi.serviceproxy.*; +import org.junit.jupiter.api.*; + +import java.net.*; + +import static com.predic8.membrane.core.http.Request.*; +import static org.junit.jupiter.api.Assertions.*; + +/** + * Verifies that expressions in the target URL are evaluated correctly. + */ +class TargetURLExpressionTest { + + private DefaultRouter router; + + @BeforeEach + void setUp() { + router = new DefaultRouter(); + } + + @AfterEach + void tearDown() { + router.stop(); + } + + @Test + void targetWithExpression() throws URISyntaxException { + Exchange rq = get("http://localhost:2000/").buildExchange(); + APIProxy api = new APIProxy() {{ + setTarget(new Target() {{ + setUrl("http://localhost:${2000 + 1000}"); + }}); + }}; + rq.setProxy(api); + api.init(router); + + DispatchingInterceptor di = new DispatchingInterceptor(); + di.init(router); + di.handleRequest(rq); + + assertEquals("http://localhost:3000/", rq.getDestinations().getFirst()); + } +} \ No newline at end of file diff --git a/core/src/test/java/com/predic8/membrane/core/proxies/UnavailableSoapProxyTest.java b/core/src/test/java/com/predic8/membrane/core/proxies/UnavailableSoapProxyTest.java index 60331a7272..263e881dfb 100644 --- a/core/src/test/java/com/predic8/membrane/core/proxies/UnavailableSoapProxyTest.java +++ b/core/src/test/java/com/predic8/membrane/core/proxies/UnavailableSoapProxyTest.java @@ -20,14 +20,15 @@ import com.predic8.membrane.core.transport.http.client.*; import org.junit.jupiter.api.*; +import java.io.*; import java.util.*; import static org.junit.jupiter.api.Assertions.*; public class UnavailableSoapProxyTest { - private Router r, r2; - private static Router backendRouter; + private static DefaultRouter r, r2; + private static DefaultRouter backendRouter; private SOAPProxy sp; private ServiceProxy sp3; @@ -35,24 +36,26 @@ public class UnavailableSoapProxyTest { static void setup() throws Exception { ServiceProxy cityAPI = new ServiceProxy(new ServiceProxyKey(4000), null, 0); cityAPI.getFlow().add(new SampleSoapServiceInterceptor()); - backendRouter = new HttpRouter(); - backendRouter.getRuleManager().addProxyAndOpenPortIfNew(cityAPI); - backendRouter.init(); + backendRouter = new DefaultRouter(); + backendRouter.add(cityAPI); + backendRouter.start(); } @AfterAll static void teardown() { - backendRouter.shutdown(); + backendRouter.stop(); + r.stop(); + r2.stop(); } @BeforeEach - void startRouter() { - r = new Router(); + void startRouter() throws IOException { + r = new DefaultRouter(); HttpClientConfiguration httpClientConfig = new HttpClientConfiguration(); httpClientConfig.getRetryHandler().setRetries(1); r.setHttpClientConfig(httpClientConfig); - r.getConfig().setHotDeploy(false); - r.getConfig().setRetryInit(true); + r.getConfiguration().setHotDeploy(false); + r.getConfiguration().setRetryInit(true); sp = new SOAPProxy(); sp.setPort(2000); @@ -68,15 +71,15 @@ void startRouter() { SOAPProxy sp2 = new SOAPProxy(); sp2.setPort(2001); sp2.setWsdl("http://localhost:4000?wsdl"); - r2 = new Router(); - r2.getConfig().setHotDeploy(false); - r2.getRules().add(sp2); + r2 = new DefaultRouter(); + r2.getConfiguration().setHotDeploy(false); + r2.add(sp2); } @AfterEach - void shutdownRouter() { - r.shutdown(); - r2.shutdown(); + void teardownEach() { + r.stop(); + r2.stop(); } private void test() { @@ -85,13 +88,13 @@ private void test() { List proxies = r.getRuleManager().getRules(); assertEquals(1, proxies.size()); assertFalse(proxies.getFirst().isActive()); - r.tryReinitialization(); + r.getReinitializer().retry(); proxies = r.getRuleManager().getRules(); assertEquals(1, proxies.size()); assertFalse(proxies.getFirst().isActive()); r2.start(); - r.tryReinitialization(); + r.getReinitializer().retry(); proxies = r.getRuleManager().getRules(); assertEquals(1, proxies.size()); @@ -99,21 +102,21 @@ private void test() { } @Test - void checkWSDLDownloadFailureInSoapProxy() { - r.getRules().add(sp); + void checkWSDLDownloadFailureInSoapProxy() throws IOException { + r.add(sp); test(); } @Test - void checkWSDLDownloadFailureInSoapProxyAndValidator() { + void checkWSDLDownloadFailureInSoapProxyAndValidator() throws IOException { sp.getFlow().add(new ValidatorInterceptor()); - r.getRules().add(sp); + r.add(sp); test(); } @Test - void checkWSDLDownloadFailureInValidatorOfServiceProxy() { - r.getRules().add(sp3); + void checkWSDLDownloadFailureInValidatorOfServiceProxy() throws IOException { + r.add(sp3); test(); } } diff --git a/core/src/test/java/com/predic8/membrane/core/resolver/ResolverTest.java b/core/src/test/java/com/predic8/membrane/core/resolver/ResolverTest.java index 56cc3a4193..189920ecef 100644 --- a/core/src/test/java/com/predic8/membrane/core/resolver/ResolverTest.java +++ b/core/src/test/java/com/predic8/membrane/core/resolver/ResolverTest.java @@ -19,6 +19,7 @@ import com.predic8.membrane.core.interceptor.schemavalidation.*; import com.predic8.membrane.core.interceptor.server.*; import com.predic8.membrane.core.proxies.*; +import com.predic8.membrane.core.util.*; import com.predic8.schema.*; import com.predic8.wsdl.*; import org.junit.jupiter.api.*; @@ -30,247 +31,242 @@ import java.util.*; import static com.predic8.membrane.core.interceptor.Outcome.*; -import static com.predic8.membrane.test.TestUtil.getPathFromResource; +import static com.predic8.membrane.test.TestUtil.*; import static org.junit.jupiter.api.Assertions.*; public class ResolverTest { - /* - * The ResolverTest is a 5-dimensional parametrized test: - * 1. Deployment Type - * 2. Operating System - * 3. Basis URL Type - * 4. Relative URL Type - * 5. Resolver Interface used - * - * Not all combinations exist (or are currently supported). (See #setupLocations()) - */ - - - // DeploymentType (STANDALONE, J2EE, OSGI) is handled differently on the tests setup/execution level - - // OperatingSystemType (WINDOWS, LINUX) is handled by Jenkins - - public enum BasisUrlType { - HTTP, - FILE, - FILE_WINDOWS_DRIVE, - CLASSPATH, - BUNDLE, - NAME, - SAME_DIR, - PARENT_DIR, - ROOT_DIR, - WINDOWS_DRIVE, - WINDOWS_DRIVE_BACKSLASH - } - - // RelativeUrlType (SCHEMA, NAME, SAME_DIR, PARENT_DIR) is handled by the test methods as well as by the test resources - // (WSDL and XSD files referencing other files in these ways) - - // ResolverInterfaceType (MEMBRANE_SERVICE_PROXY, MEMBRANE_SOA_MODEL, LS_RESOURCE_RESOLVER) is handled by - // different test methods below - - public static List getConfigurations() { - List res = new ArrayList<>(); - for (BasisUrlType but : BasisUrlType.values()) - res.add(new Object[] { but }); - return res; - } - - public static final ResolverMap resolverMap = new ResolverMap(); - - private String wsdlLocation; - private String xsdLocation; - - @ParameterizedTest - @MethodSource("getConfigurations") - public void testLSResourceResolver(BasisUrlType basisUrlType) { - if (hit = !setupLocations(basisUrlType)) - return; - - try { - new XMLSchemaValidator(resolverMap, xsdLocation, null); - } catch (Exception e) { - throw new RuntimeException("xsdLocation = " + xsdLocation, e); - } - } - - @ParameterizedTest - @MethodSource("getConfigurations") - public void testMembraneServiceProxyCombine(BasisUrlType basisUrlType) throws IOException { - if (hit = !setupLocations(basisUrlType)) - return; - - assertNotNull(resolverMap.resolve(wsdlLocation)); - for (String relUrl : new String[] { "1.xsd", "./1.xsd", "../resolver/1.xsd", "http://localhost:3029/resolver/1.xsd" }) { - try { - assertNotNull(resolverMap.resolve(ResolverMap.combine(wsdlLocation, relUrl))); - } catch (Exception e) { - throw new RuntimeException("Error during combine(\"" + wsdlLocation + "\", \"" + relUrl + "\"):", e); - } - } - } - - @ParameterizedTest - @MethodSource("getConfigurations") - public void testMembraneSoaModel(BasisUrlType basisUrlType) { - if (hit = !setupLocations(basisUrlType)) - return; - - try { - WSDLParserContext ctx = new WSDLParserContext(); - ctx.setInput(wsdlLocation); - WSDLParser wsdlParser = new WSDLParser(); - wsdlParser.setResourceResolver(resolverMap.toExternalResolver().toExternalResolver()); - Definitions definitions = wsdlParser.parse(ctx); - for (Schema schema : definitions.getSchemas()) - schema.getElements(); // trigger lazy-loading - } catch (Exception e) { - throw new RuntimeException("wsdlLocation = " + xsdLocation, e); - } - } - - @AfterEach - public void postpare() { - // since a.wsdl and 2.xsd reference a HTTP resource, it should get loaded - assertTrue(hit, "No HTTP resource was retrieved (while referenced)"); - } - - /** - * Sets wsdlLocation and xsdLocation, given the current test parameters - * @return whether the current test parameters is supported - */ - private boolean setupLocations(BasisUrlType basisUrlType) { - switch (basisUrlType) { - case BUNDLE: - return false; - case CLASSPATH: - wsdlLocation = "classpath:/resolver/a.wsdl"; - xsdLocation = "classpath:/resolver/2.xsd"; - return true; - case FILE: - if (!deployment.equals(STANDALONE)) - return false; - String current = new File(".").getAbsolutePath().replaceAll("\\\\", "/"); - if (current.endsWith(".")) - current = current.substring(0, current.length()-1); - if (current.startsWith(":/", 1)) - current = current.substring(2); - wsdlLocation = "file://" + current + "src/test/resources/resolver/a.wsdl"; - xsdLocation = "file://" + current + "src/test/resources/resolver/2.xsd"; - return true; - case FILE_WINDOWS_DRIVE: - if (!deployment.equals(STANDALONE)) - return false; - basisUrlType = BasisUrlType.WINDOWS_DRIVE; - if (!setupLocations(basisUrlType)) - return false; - wsdlLocation = "file://" + wsdlLocation; - xsdLocation = "file://" + xsdLocation; - return true; - case WINDOWS_DRIVE: - if (!deployment.equals(STANDALONE)) - return false; - if (!isWindows()) - return false; - String current2 = new File(".").getAbsolutePath().replaceAll("\\\\", "/"); - if (current2.endsWith(".")) - current2 = current2.substring(0, current2.length()-1); - wsdlLocation = current2 + "src/test/resources/resolver/a.wsdl"; - xsdLocation = current2 + "src/test/resources/resolver/2.xsd"; - return true; - case WINDOWS_DRIVE_BACKSLASH: - if (!deployment.equals(STANDALONE)) - return false; - basisUrlType = BasisUrlType.WINDOWS_DRIVE; - if (!setupLocations(basisUrlType)) - return false; - wsdlLocation = wsdlLocation.replaceAll("/", "\\\\"); - xsdLocation = xsdLocation.replaceAll("/", "\\\\"); - return true; - case ROOT_DIR: - String current3; - if (deployment.equals(STANDALONE)) { - current3 = new File(".").getAbsolutePath().replaceAll("\\\\", "/"); - if (current3.endsWith(".")) - current3 = current3.substring(0, current3.length()-1); - if (current3.startsWith(":/", 1)) - current3 = current3.substring(2); - current3 = current3 + "src/test/resources"; - } else { - current3 = "/test"; - } - wsdlLocation = current3 + "/resolver/a.wsdl"; - xsdLocation = current3 + "/resolver/2.xsd"; - return true; - case HTTP: - wsdlLocation = "http://localhost:3029/resolver/a.wsdl"; - xsdLocation = "http://localhost:3029/resolver/2.xsd"; - return true; - case NAME: - if (!deployment.equals(STANDALONE)) - return false; // TODO: could be implemented - wsdlLocation = "src/test/resources/resolver/a.wsdl"; - xsdLocation = "src/test/resources/resolver/2.xsd"; - return true; - case PARENT_DIR: - if (!deployment.equals(STANDALONE)) - return false; // TODO: could be implemented - wsdlLocation = "../core/src/test/resources/resolver/a.wsdl"; - xsdLocation = "../core/src/test/resources/resolver/2.xsd"; - return true; - case SAME_DIR: - if (!deployment.equals(STANDALONE)) - return false; // TODO: could be implemented - wsdlLocation = "./src/test/resources/resolver/a.wsdl"; - xsdLocation = "./src/test/resources/resolver/2.xsd"; - return true; - default: - throw new InvalidParameterException("basisUrlType = " + basisUrlType); - } - } - - public static boolean isWindows() { - return System.getProperty("os.name").contains("Windows"); - } - - static final HttpRouter router = new HttpRouter(); - static volatile boolean hit = false; - - public static final String STANDALONE = "standalone"; - public static final String J2EE = "J2EE"; - - public static final String deployment = STANDALONE; - - @BeforeAll - public static void setup() throws Exception { - ServiceProxy sp = new ServiceProxy(new ServiceProxyKey(3029), "localhost", 8080); - - sp.getFlow().add(new AbstractInterceptor() { - @Override - public Outcome handleRequest(Exchange exc) { - hit = true; - return CONTINUE; - } - }); - - WebServerInterceptor i = new WebServerInterceptor(); - if (deployment.equals(STANDALONE)) - i.setDocBase(getPathFromResource("")); - else { - i.setDocBase("/test"); - router.getResolverMap().addSchemaResolver(resolverMap.getFileSchemaResolver()); - } - sp.getFlow().add(i); - - router.add(sp); - router.init(); - } - - @AfterAll - public static void teardown() { - router.shutdown(); - } - + /* + * The ResolverTest is a 5-dimensional parametrized test: + * 1. Deployment Type + * 2. Operating System + * 3. Basis URL Type + * 4. Relative URL Type + * 5. Resolver Interface used + * + * Not all combinations exist (or are currently supported). (See #setupLocations()) + */ + + + // DeploymentType (STANDALONE, J2EE, OSGI) is handled differently on the tests setup/execution level + + // OperatingSystemType (WINDOWS, LINUX) is handled by Jenkins + + private static Router router; + private static volatile boolean hit = false; + + private static final String STANDALONE = "standalone"; + private static final String deployment = STANDALONE; + + public enum BasisUrlType { + HTTP, + FILE, + FILE_WINDOWS_DRIVE, + CLASSPATH, + BUNDLE, + NAME, + SAME_DIR, + PARENT_DIR, + ROOT_DIR, + WINDOWS_DRIVE, + WINDOWS_DRIVE_BACKSLASH + } + + @BeforeAll + public static void setup() throws Exception { + ServiceProxy sp = new ServiceProxy(new ServiceProxyKey(3029), "localhost", 8080); + + sp.getFlow().add(new AbstractInterceptor() { + @Override + public Outcome handleRequest(Exchange exc) { + hit = true; + return CONTINUE; + } + }); + + WebServerInterceptor i = new WebServerInterceptor(); + if (deployment.equals(STANDALONE)) + i.setDocBase(getPathFromResource("")); + else { + i.setDocBase("/test"); + router.getResolverMap().addSchemaResolver(resolverMap.getFileSchemaResolver()); + } + sp.getFlow().add(i); + + router = new TestRouter(); + router.add(sp); + router.start(); + } + + @AfterAll + public static void teardown() { + router.stop(); + } + + // RelativeUrlType (SCHEMA, NAME, SAME_DIR, PARENT_DIR) is handled by the test methods as well as by the test resources + // (WSDL and XSD files referencing other files in these ways) + + // ResolverInterfaceType (MEMBRANE_SERVICE_PROXY, MEMBRANE_SOA_MODEL, LS_RESOURCE_RESOLVER) is handled by + // different test methods below + + public static List getConfigurations() { + List res = new ArrayList<>(); + for (BasisUrlType but : BasisUrlType.values()) + res.add(new Object[]{but}); + return res; + } + + public static final ResolverMap resolverMap = new ResolverMap(); + + private String wsdlLocation; + private String xsdLocation; + + @ParameterizedTest + @MethodSource("getConfigurations") + public void testLSResourceResolver(BasisUrlType basisUrlType) { + if (hit = !setupLocations(basisUrlType)) + return; + + try { + new XMLSchemaValidator(resolverMap, xsdLocation, null); + } catch (Exception e) { + throw new RuntimeException("xsdLocation = " + xsdLocation, e); + } + } + + @ParameterizedTest + @MethodSource("getConfigurations") + public void testMembraneServiceProxyCombine(BasisUrlType basisUrlType) throws IOException { + if (hit = !setupLocations(basisUrlType)) + return; + + assertNotNull(resolverMap.resolve(wsdlLocation)); + for (String relUrl : new String[]{"1.xsd", "./1.xsd", "../resolver/1.xsd", "http://localhost:3029/resolver/1.xsd"}) { + try { + assertNotNull(resolverMap.resolve(ResolverMap.combine(wsdlLocation, relUrl))); + } catch (Exception e) { + throw new RuntimeException("Error during combine(\"" + wsdlLocation + "\", \"" + relUrl + "\"):", e); + } + } + } + + @ParameterizedTest + @MethodSource("getConfigurations") + public void testMembraneSoaModel(BasisUrlType basisUrlType) { + if (hit = !setupLocations(basisUrlType)) + return; + + try { + WSDLParserContext ctx = new WSDLParserContext(); + ctx.setInput(wsdlLocation); + WSDLParser wsdlParser = new WSDLParser(); + wsdlParser.setResourceResolver(resolverMap.toExternalResolver().toExternalResolver()); + Definitions definitions = wsdlParser.parse(ctx); + for (Schema schema : definitions.getSchemas()) + schema.getElements(); // trigger lazy-loading + } catch (Exception e) { + throw new RuntimeException("wsdlLocation = " + xsdLocation, e); + } + } + + @AfterEach + public void postpare() { + // since a.wsdl and 2.xsd reference a HTTP resource, it should get loaded + assertTrue(hit, "No HTTP resource was retrieved (while referenced)"); + } + + /** + * Sets wsdlLocation and xsdLocation, given the current test parameters + * + * @return whether the current test parameters is supported + */ + private boolean setupLocations(BasisUrlType basisUrlType) { + switch (basisUrlType) { + case BUNDLE: + return false; + case CLASSPATH: + wsdlLocation = "classpath:/resolver/a.wsdl"; + xsdLocation = "classpath:/resolver/2.xsd"; + return true; + case FILE: + if (!deployment.equals(STANDALONE)) + return false; + String current = new File(".").getAbsolutePath().replaceAll("\\\\", "/"); + if (current.endsWith(".")) + current = current.substring(0, current.length() - 1); + if (current.startsWith(":/", 1)) + current = current.substring(2); + wsdlLocation = "file://" + current + "src/test/resources/resolver/a.wsdl"; + xsdLocation = "file://" + current + "src/test/resources/resolver/2.xsd"; + return true; + case FILE_WINDOWS_DRIVE: + if (!deployment.equals(STANDALONE)) + return false; + basisUrlType = BasisUrlType.WINDOWS_DRIVE; + if (!setupLocations(basisUrlType)) + return false; + wsdlLocation = "file://" + wsdlLocation; + xsdLocation = "file://" + xsdLocation; + return true; + case WINDOWS_DRIVE: + if (!deployment.equals(STANDALONE)) + return false; + if (!OSUtil.isWindows()) + return false; + String current2 = new File(".").getAbsolutePath().replaceAll("\\\\", "/"); + if (current2.endsWith(".")) + current2 = current2.substring(0, current2.length() - 1); + wsdlLocation = current2 + "src/test/resources/resolver/a.wsdl"; + xsdLocation = current2 + "src/test/resources/resolver/2.xsd"; + return true; + case WINDOWS_DRIVE_BACKSLASH: + if (!deployment.equals(STANDALONE)) + return false; + basisUrlType = BasisUrlType.WINDOWS_DRIVE; + if (!setupLocations(basisUrlType)) + return false; + wsdlLocation = wsdlLocation.replaceAll("/", "\\\\"); + xsdLocation = xsdLocation.replaceAll("/", "\\\\"); + return true; + case ROOT_DIR: + String current3; + if (deployment.equals(STANDALONE)) { + current3 = new File(".").getAbsolutePath().replaceAll("\\\\", "/"); + if (current3.endsWith(".")) + current3 = current3.substring(0, current3.length() - 1); + if (current3.startsWith(":/", 1)) + current3 = current3.substring(2); + current3 = current3 + "src/test/resources"; + } else { + current3 = "/test"; + } + wsdlLocation = current3 + "/resolver/a.wsdl"; + xsdLocation = current3 + "/resolver/2.xsd"; + return true; + case HTTP: + wsdlLocation = "http://localhost:3029/resolver/a.wsdl"; + xsdLocation = "http://localhost:3029/resolver/2.xsd"; + return true; + case NAME: + if (!deployment.equals(STANDALONE)) + return false; // TODO: could be implemented + wsdlLocation = "src/test/resources/resolver/a.wsdl"; + xsdLocation = "src/test/resources/resolver/2.xsd"; + return true; + case PARENT_DIR: + if (!deployment.equals(STANDALONE)) + return false; // TODO: could be implemented + wsdlLocation = "../core/src/test/resources/resolver/a.wsdl"; + xsdLocation = "../core/src/test/resources/resolver/2.xsd"; + return true; + case SAME_DIR: + if (!deployment.equals(STANDALONE)) + return false; // TODO: could be implemented + wsdlLocation = "./src/test/resources/resolver/a.wsdl"; + xsdLocation = "./src/test/resources/resolver/2.xsd"; + return true; + default: + throw new InvalidParameterException("basisUrlType = " + basisUrlType); + } + } } diff --git a/core/src/test/java/com/predic8/membrane/core/security/JWTSecuritySchemeTest.java b/core/src/test/java/com/predic8/membrane/core/security/JWTSecuritySchemeTest.java index 160e8ba763..1a3a77670f 100644 --- a/core/src/test/java/com/predic8/membrane/core/security/JWTSecuritySchemeTest.java +++ b/core/src/test/java/com/predic8/membrane/core/security/JWTSecuritySchemeTest.java @@ -26,6 +26,7 @@ import java.util.*; +import static com.predic8.membrane.core.http.Request.get; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -45,14 +46,8 @@ public void test() throws Exception{ JwtAuthInterceptor interceptor = prepareInterceptor(publicOnly); - Exchange exc = new Request.Builder() - .get("") - .header("Authorization", "Bearer " + getSignedJwt(privateKey) + "1") - .buildExchange(); - + Exchange exc = get("").header("Authorization", "Bearer " + getSignedJwt(privateKey) + "1").buildExchange(); interceptor.handleRequest(exc); - - // } private JwtAuthInterceptor prepareInterceptor(RsaJsonWebKey publicOnly) throws Exception { @@ -60,10 +55,11 @@ private JwtAuthInterceptor prepareInterceptor(RsaJsonWebKey publicOnly) throws E } private JwtAuthInterceptor initInterceptor(JwtAuthInterceptor interceptor) throws Exception { - Router routerMock = mock(Router.class); - when(routerMock.getBaseLocation()).thenReturn(""); - when(routerMock.getResolverMap()).thenReturn(new ResolverMap()); - interceptor.init(routerMock); + DefaultRouter mock = mock(DefaultRouter.class); + when(mock.getBaseLocation()).thenReturn(""); + when(mock.getResolverMap()).thenReturn(new ResolverMap()); + when(mock.getConfiguration()).thenReturn(new Configuration()); + interceptor.init(mock); return interceptor; } diff --git a/core/src/test/java/com/predic8/membrane/core/security/KeyStoreUtilTest.java b/core/src/test/java/com/predic8/membrane/core/security/KeyStoreUtilTest.java index 43b148a255..ea402e0e46 100644 --- a/core/src/test/java/com/predic8/membrane/core/security/KeyStoreUtilTest.java +++ b/core/src/test/java/com/predic8/membrane/core/security/KeyStoreUtilTest.java @@ -13,8 +13,7 @@ limitations under the License. */ package com.predic8.membrane.core.security; -import com.predic8.membrane.core.HttpRouter; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.security.KeyStore; import com.predic8.membrane.core.config.security.SSLParser; import org.junit.jupiter.api.AfterAll; @@ -44,7 +43,7 @@ class KeyStoreUtilTest { @BeforeAll static void setUp() throws Exception { - router = new HttpRouter(); + router = new DummyTestRouter(); SSLParser sslParser = new SSLParser(); sslParser.setKeyStore(new KeyStore()); sslParser.getKeyStore().setLocation("classpath:/alias-keystore.p12"); diff --git a/core/src/test/java/com/predic8/membrane/core/transport/http/BoundConnectionTest.java b/core/src/test/java/com/predic8/membrane/core/transport/http/BoundConnectionTest.java index e24f20cb37..df36d02b03 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/http/BoundConnectionTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/http/BoundConnectionTest.java @@ -29,15 +29,15 @@ public class BoundConnectionTest { - HttpRouter router; + Router router; volatile long connectionHash = 0; @BeforeEach public void setUp() throws Exception { - router = new HttpRouter(); + router = new TestRouter(); ServiceProxy sp1 = new ServiceProxy(new ServiceProxyKey("*", "*", ".*", 3021), "localhost", 3022); - router.getRuleManager().addProxyAndOpenPortIfNew(sp1); + router.add(sp1); ServiceProxy sp2 = new ServiceProxy(new ServiceProxyKey("*", "*", ".*", 3022), "", -1); sp2.getFlow().add(new AbstractInterceptor(){ @@ -53,13 +53,13 @@ public Outcome handleRequest(Exchange exc) { return Outcome.RETURN; } }); - router.getRuleManager().addProxyAndOpenPortIfNew(sp2); - router.init(); + router.add(sp2); + router.start(); } @AfterEach public void tearDown() { - router.shutdown(); + router.stop(); } diff --git a/core/src/test/java/com/predic8/membrane/core/transport/http/ConcurrentConnectionLimitTest.java b/core/src/test/java/com/predic8/membrane/core/transport/http/ConcurrentConnectionLimitTest.java index de9dd17d54..0211a90b5a 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/http/ConcurrentConnectionLimitTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/http/ConcurrentConnectionLimitTest.java @@ -28,7 +28,7 @@ public class ConcurrentConnectionLimitTest { - private HttpRouter router; + private Router router; private ExecutorService executor; private final int concurrency = 100; private final int concurrentLimit = 10; @@ -40,21 +40,21 @@ public class ConcurrentConnectionLimitTest { public void setup() throws Exception{ executor = Executors.newFixedThreadPool(concurrency); - router = new HttpRouter(); - router.getTransport().setConcurrentConnectionLimitPerIp(concurrentLimit); + router = new TestRouter(); ServiceProxy sp = new ServiceProxy(new ServiceProxyKey("*", "*", ".*", port), "", -1); sp.getFlow().add(GROOVY("Thread.sleep(1000)")); sp.getFlow().add(RETURN); - router.getRuleManager().addProxyAndOpenPortIfNew(sp); - router.init(); + router.add(sp); + router.start(); + router.getTransport().setConcurrentConnectionLimitPerIp(concurrentLimit); } @AfterEach public void tearDown() throws Exception { - router.shutdown(); + router.stop(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/core/transport/http/ConnectionTest.java b/core/src/test/java/com/predic8/membrane/core/transport/http/ConnectionTest.java index b749addd9e..28fd97a0b4 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/http/ConnectionTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/http/ConnectionTest.java @@ -26,32 +26,33 @@ public class ConnectionTest { Connection conLocalhost; Connection con127_0_0_1; - HttpRouter router; + Router router; @BeforeEach - public void setUp() throws Exception { + void setUp() throws Exception { ServiceProxy proxy2000 = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", 2000), "predic8.com", 80); - router = new HttpRouter(); - router.getRuleManager().addProxyAndOpenPortIfNew(proxy2000); + router = new TestRouter(); + router.add(proxy2000); + router.start(); conLocalhost = Connection.open("localhost", 2000, null, null, 30000); con127_0_0_1 = Connection.open("127.0.0.1", 2000, null, null, 30000); } @AfterEach - public void tearDown() throws Exception { + void tearDown() throws Exception { conLocalhost.close(); con127_0_0_1.close(); assertTrue(conLocalhost.isClosed()); assertTrue(con127_0_0_1.isClosed()); - router.shutdown(); + router.stop(); } @Test - public void testIsSame() { + void isSame() { assertTrue(conLocalhost.isSame("127.0.0.1", 2000)); assertTrue(con127_0_0_1.isSame("localhost", 2000)); } diff --git a/core/src/test/java/com/predic8/membrane/core/transport/http/Http2DowngradeTest.java b/core/src/test/java/com/predic8/membrane/core/transport/http/Http2DowngradeTest.java index f9c3ad422d..1cb5fecee5 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/http/Http2DowngradeTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/http/Http2DowngradeTest.java @@ -20,6 +20,8 @@ import com.predic8.membrane.core.proxies.*; import org.junit.jupiter.api.*; +import java.io.*; + import static com.predic8.membrane.core.http.Header.*; import static com.predic8.membrane.core.http.Request.*; import static com.predic8.membrane.core.interceptor.Outcome.*; @@ -28,11 +30,11 @@ public class Http2DowngradeTest { - private static HttpRouter router; + private static Router router; @BeforeAll - public static void beforeAll() { - router = new HttpRouter(); + public static void beforeAll() throws IOException { + router = new TestRouter(); ServiceProxy proxy = new ServiceProxy(new ServiceProxyKey(3064), null, 0); proxy.getFlow().add(new AbstractInterceptor() { @Override @@ -41,7 +43,7 @@ public Outcome handleRequest(Exchange exc) { return RETURN; } }); - router.getRules().add(proxy); + router.add(proxy); router.start(); } diff --git a/core/src/test/java/com/predic8/membrane/core/transport/http/HttpKeepAliveTest.java b/core/src/test/java/com/predic8/membrane/core/transport/http/HttpKeepAliveTest.java index 826359be8e..8972610d24 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/http/HttpKeepAliveTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/http/HttpKeepAliveTest.java @@ -40,14 +40,14 @@ public class HttpKeepAliveTest { private HashSet hashs; // tracks the hashcodes of all connections used - private HttpRouter service1; + private Router service1; private ServiceProxy sp1; @BeforeEach public void setUp() throws Exception { hashs = new HashSet<>(); - service1 = new HttpRouter(); + service1 = new TestRouter(); sp1 = new ServiceProxy(new ServiceProxyKey("localhost", METHOD_POST, ".*", 2003), "thomas-bayer.com", 80); sp1.getFlow().add(new AbstractInterceptor(){ @@ -63,13 +63,13 @@ public Outcome handleRequest(Exchange exc) { return RETURN; } }); - service1.getRuleManager().addProxyAndOpenPortIfNew(sp1); - service1.init(); + service1.add(sp1); + service1.start(); } @AfterEach public void tearDown() { - service1.shutdown(); + service1.stop(); } private HttpClient createHttpClient(int defaultKeepAliveTimeout) { diff --git a/core/src/test/java/com/predic8/membrane/core/transport/http/HttpTimeoutTest.java b/core/src/test/java/com/predic8/membrane/core/transport/http/HttpTimeoutTest.java index e35bf95c61..cb98d76b26 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/http/HttpTimeoutTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/http/HttpTimeoutTest.java @@ -20,6 +20,7 @@ import com.predic8.membrane.core.interceptor.*; import com.predic8.membrane.core.proxies.*; import com.predic8.membrane.core.transport.http.client.*; +import org.jetbrains.annotations.*; import org.junit.jupiter.api.*; import java.io.*; @@ -34,7 +35,7 @@ public class HttpTimeoutTest { public final int BACKEND_DELAY_MILLIS = 300; - HttpRouter slowBackend, proxyRouter; + Router slowBackend, proxyRouter; @BeforeEach public void setUp() throws Exception { @@ -42,26 +43,41 @@ public void setUp() throws Exception { setupSlowBackend(); } - private void setupMembrane() { + @AfterEach + public void tearDown() { + slowBackend.stop(); + proxyRouter.stop(); + } + + private void setupMembrane() throws IOException { HttpClientConfiguration hcc = new HttpClientConfiguration(); hcc.getConnection().setSoTimeout(1); hcc.getRetryHandler().setRetries(1); - proxyRouter = new HttpRouter(); - proxyRouter.getConfig().setHotDeploy(false); - proxyRouter.getTransport().getFirstInterceptorOfType(HTTPClientInterceptor.class).get().setHttpClientConfig(hcc); - ServiceProxy sp2 = new ServiceProxy(new ServiceProxyKey("*", - "*", ".*", 3023), "localhost", 3022); - proxyRouter.getRules().add(sp2); + proxyRouter = new TestRouter(); + ServiceProxy sp2 = getServiceProxy(3023, "localhost", 3022); + proxyRouter.add(sp2); proxyRouter.start(); + var client = proxyRouter.getTransport().getFirstInterceptorOfType(HTTPClientInterceptor.class).orElseThrow(); + client.setHttpClientConfig(hcc); + client.init(); // Copies the config into the HttpClient. It is needed to call because router.start() above already called init() + } + + private static @NotNull ServiceProxy getServiceProxy(int port, String localhost, int targetPort) { + return new ServiceProxy(new ServiceProxyKey("*", + "*", ".*", port), localhost, targetPort); } private void setupSlowBackend() throws Exception { - slowBackend = new HttpRouter(); - slowBackend.getConfig().setHotDeploy(false); - ServiceProxy sp = new ServiceProxy(new ServiceProxyKey("*", - "*", ".*", 3022), "", -1); - sp.getFlow().add(new AbstractInterceptor(){ + slowBackend = new TestRouter(); + ServiceProxy sp = getServiceProxy(3022, "", -1); + sp.getFlow().add(getHandler()); + slowBackend.add(sp); + slowBackend.start(); + } + + private @NotNull AbstractInterceptor getHandler() { + return new AbstractInterceptor() { @Override public Outcome handleRequest(Exchange exc) { try { @@ -77,15 +93,7 @@ public Outcome handleRequest(Exchange exc) { exc.setResponse(ok("OK.").build()); return RETURN; } - }); - slowBackend.getRuleManager().addProxyAndOpenPortIfNew(sp); - slowBackend.init(); - } - - @AfterEach - public void tearDown() { - slowBackend.stop(); - proxyRouter.stop(); + }; } @Test @@ -100,8 +108,6 @@ void httpTimeout() throws Exception { client.call(exc); assertEquals(500, exc.getResponse().getStatusCode()); - System.out.println(exc.getResponse()); - System.out.println(exc.getResponse().getBodyAsStringDecoded()); } watch.stop(); diff --git a/core/src/test/java/com/predic8/membrane/core/transport/http/HttpTransportTest.java b/core/src/test/java/com/predic8/membrane/core/transport/http/HttpTransportTest.java index 5ac41b380c..9f810d6f66 100755 --- a/core/src/test/java/com/predic8/membrane/core/transport/http/HttpTransportTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/http/HttpTransportTest.java @@ -33,7 +33,7 @@ public class HttpTransportTest { private final ResolverMap resolverMap = mock(ResolverMap.class); private final SSLProvider sslProvider = mock(SSLProvider.class); private final RuleManager ruleManager = mock(RuleManager.class); - private final Router router = mock(Router.class); + private final DefaultRouter router = mock(DefaultRouter.class); private final ExchangeStore exchangeStore = mock(ExchangeStore.class); private final Statistics statistics = new Statistics(); private HttpTransport transport; diff --git a/core/src/test/java/com/predic8/membrane/core/transport/http/IllegalCharactersInURLTest.java b/core/src/test/java/com/predic8/membrane/core/transport/http/IllegalCharactersInURLTest.java index 12cb574297..12fc86b8a0 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/http/IllegalCharactersInURLTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/http/IllegalCharactersInURLTest.java @@ -31,12 +31,12 @@ class IllegalCharactersInURLTest { - private HttpRouter r; + private Router r; @BeforeEach void init() throws Exception { - r = new HttpRouter(); - r.getConfig().setHotDeploy(false); + r = new TestRouter(); + r.getConfiguration().setHotDeploy(false); r.add(new ServiceProxy(new ServiceProxyKey(3027), "localhost", 3028)); ServiceProxy sp2 = new ServiceProxy(new ServiceProxyKey(3028), null, 80); sp2.getFlow().add(new AbstractInterceptor() { @@ -53,7 +53,7 @@ public Outcome handleRequest(Exchange exc) { @AfterEach void unInit() { - r.shutdown(); + r.stop(); } @Test @@ -68,13 +68,13 @@ void apacheHttpClient() { @Test void illegal_with_router_tolerant_urifactory() throws Exception { - r.getConfig().setUriFactory(new URIFactory(true)); + r.getConfiguration().setUriFactory(new URIFactory(true)); makeCallWithIllegalCharacters(200); } @Test void illegal_with_router_intolerant_urifactory() throws Exception { - r.getConfig().setUriFactory(new URIFactory(false)); + r.getConfiguration().setUriFactory(new URIFactory(false)); makeCallWithIllegalCharacters(400); } diff --git a/core/src/test/java/com/predic8/membrane/core/transport/http/ServiceInvocationTest.java b/core/src/test/java/com/predic8/membrane/core/transport/http/ServiceInvocationTest.java index 513af03008..4d5bbd91bc 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/http/ServiceInvocationTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/http/ServiceInvocationTest.java @@ -30,16 +30,16 @@ public class ServiceInvocationTest { - private HttpRouter router; + private Router router; @BeforeEach - public void setUp() throws Exception { + void setUp() throws Exception { router = createRouter(); MockInterceptor.clear(); } @Test - public void testInterceptorSequence() throws Exception { + void testInterceptorSequence() throws Exception { callService(); MockInterceptor.assertContent( @@ -48,10 +48,9 @@ public void testInterceptorSequence() throws Exception { new String[] {}); // aborts } - @AfterEach public void tearDown() { - router.shutdown(); + router.stop(); } private ServiceProxy createFirstRule() { @@ -88,13 +87,13 @@ private PostMethod createPostMethod() { return post; } - private HttpRouter createRouter() throws Exception { - HttpRouter router = new HttpRouter(); - router.getRuleManager().addProxyAndOpenPortIfNew(createFirstRule()); - router.getRuleManager().addProxyAndOpenPortIfNew(createServiceRule()); - router.getRuleManager().addProxyAndOpenPortIfNew(createEndpointRule()); + private Router createRouter() throws Exception { + Router router = new TestRouter(); + router.add(createFirstRule()); + router.add(createServiceRule()); + router.add(createEndpointRule()); + router.start(); router.getTransport().getFlow().add(router.getTransport().getFlow().size()-1, new MockInterceptor("transport-log")); - router.init(); return router; } diff --git a/core/src/test/java/com/predic8/membrane/core/transport/http/client/HttpClientConfigurationTest.java b/core/src/test/java/com/predic8/membrane/core/transport/http/client/HttpClientConfigurationTest.java index c75794cabd..08c6e83d05 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/http/client/HttpClientConfigurationTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/http/client/HttpClientConfigurationTest.java @@ -30,7 +30,7 @@ */ class HttpClientConfigurationTest { - Router router; + DefaultRouter router; HttpClientConfiguration configuration; @@ -145,13 +145,13 @@ void outsideRouter() { } private @NotNull Proxy getApi1() { - Proxy api1 = router.getRules().stream().filter(proxy -> proxy.getName().equals("API1")).findFirst().orElseThrow(); + Proxy api1 = router.getRuleManager().getRuleByName("API1", Proxy.class); assertNotNull(api1); return api1; } private void setupRouter(String globalHcc) { - router = Router.initFromXMLString(globalHcc); + router = RouterXmlBootstrap.initFromXMLString(globalHcc); assertNotNull(router.getHttpClientConfig()); assertNotNull(router.getResolverMap().getHTTPSchemaResolver().getHttpClientConfig()); } diff --git a/core/src/test/java/com/predic8/membrane/core/transport/http2/Http2ClientServerTest.java b/core/src/test/java/com/predic8/membrane/core/transport/http2/Http2ClientServerTest.java index 75178273df..4e70f2d1b2 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/http2/Http2ClientServerTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/http2/Http2ClientServerTest.java @@ -23,11 +23,14 @@ import com.predic8.membrane.core.transport.http.client.*; import com.predic8.membrane.core.transport.http.client.protocol.*; import com.predic8.membrane.core.util.*; +import org.jetbrains.annotations.*; import org.junit.jupiter.api.*; +import java.io.*; import java.util.concurrent.*; import java.util.function.*; +import static com.predic8.membrane.core.interceptor.Outcome.RETURN; import static com.predic8.membrane.core.transport.http2.StreamState.*; import static java.util.concurrent.TimeUnit.*; import static org.junit.jupiter.api.Assertions.*; @@ -37,22 +40,16 @@ public class Http2ClientServerTest { private volatile Consumer requestAsserter; private volatile AbstractHttpHandler handler; private HttpClient hc; - private HttpRouter router; + private Router router; private static final ConcurrentHashMap connectionHashes = new ConcurrentHashMap<>(); @BeforeEach - public void setup() { + public void setup() throws IOException { connectionHashes.clear(); - SSLParser sslParser = new SSLParser(); - sslParser.setUseExperimentalHttp2(true); - sslParser.setEndpointIdentificationAlgorithm(""); - sslParser.setShowSSLExceptions(true); - sslParser.setKeyStore(new KeyStore()); - sslParser.getKeyStore().setLocation("classpath:/ssl-rsa.keystore"); - sslParser.getKeyStore().setKeyPassword("secret"); + SSLParser sslParser = getSslParser(); - router = new HttpRouter(); - router.getConfig().setHotDeploy(false); + router = new TestRouter(); + router.getConfiguration().setHotDeploy(false); ServiceProxy sp = new ServiceProxy(new ServiceProxyKey(3049), "localhost", 80); sp.setSslInboundParser(sslParser); sp.getFlow().add(new AbstractInterceptor() { @@ -63,13 +60,12 @@ public Outcome handleRequest(Exchange exc) { if (requestAsserter != null) requestAsserter.accept(exc.getRequest()); exc.setResponse(response); - return Outcome.RETURN; + return RETURN; } }); - router.getRules().add(sp); + router.add(sp); router.start(); - SSLParser sslParser2 = new SSLParser(); sslParser2.setEndpointIdentificationAlgorithm(""); sslParser2.setShowSSLExceptions(true); @@ -87,6 +83,17 @@ public Outcome handleRequest(Exchange exc) { hc = new HttpClient(configuration); } + private static @NotNull SSLParser getSslParser() { + SSLParser sslParser = new SSLParser(); + sslParser.setUseExperimentalHttp2(true); + sslParser.setEndpointIdentificationAlgorithm(""); + sslParser.setShowSSLExceptions(true); + sslParser.setKeyStore(new KeyStore()); + sslParser.getKeyStore().setLocation("classpath:/ssl-rsa.keystore"); + sslParser.getKeyStore().setKeyPassword("secret"); + return sslParser; + } + @AfterEach public void done() { hc.close(); diff --git a/core/src/test/java/com/predic8/membrane/core/transport/ssl/HttpsKeepAliveTest.java b/core/src/test/java/com/predic8/membrane/core/transport/ssl/HttpsKeepAliveTest.java index 23de4682c9..5abe016a4e 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/ssl/HttpsKeepAliveTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/ssl/HttpsKeepAliveTest.java @@ -17,51 +17,54 @@ import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.security.*; import com.predic8.membrane.core.exchange.*; -import com.predic8.membrane.core.http.*; import com.predic8.membrane.core.interceptor.*; import com.predic8.membrane.core.proxies.*; import com.predic8.membrane.core.resolver.*; import com.predic8.membrane.core.transport.http.*; +import org.jetbrains.annotations.*; import org.junit.jupiter.api.*; +import java.io.*; import java.util.concurrent.*; import static com.predic8.membrane.core.exchange.Exchange.*; import static com.predic8.membrane.core.http.Request.*; +import static com.predic8.membrane.core.http.Response.ok; import static com.predic8.membrane.core.interceptor.Outcome.*; import static org.junit.jupiter.api.Assertions.*; public class HttpsKeepAliveTest { - private static HttpRouter server; + private static Router server; private static final ConcurrentHashMap connectionHashes = new ConcurrentHashMap<>(); @BeforeAll - public static void startServer() { - server = new HttpRouter(); - server.getConfig().setHotDeploy(false); + public static void startServer() throws IOException { + server = new TestRouter(); + server.getConfiguration().setHotDeploy(false); ServiceProxy sp = new ServiceProxy(); sp.setPort(3063); SSLParser sslIB = new SSLParser(); - KeyStore ksIB = new KeyStore(); - ksIB.setLocation("classpath:/alias-keystore.p12"); - ksIB.setKeyPassword("secret"); - ksIB.setKeyAlias("key1"); - sslIB.setKeyStore(ksIB); + sslIB.setKeyStore(getKeyStore()); sp.setSslInboundParser(sslIB); sp.getFlow().add(new AbstractInterceptor() { @Override public Outcome handleRequest(Exchange exc) { - exc.setResponse(Response.ok("ssltest").build()); - connectionHashes.put("" + ((HttpServerHandler)exc.getHandler()).getSrcOut().hashCode(), true); + exc.setResponse(ok("ssltest").build()); + connectionHashes.put("" + ((HttpServerHandler) exc.getHandler()).getSrcOut().hashCode(), true); return RETURN; } }); - server.getRules().add(sp); + server.add(sp); server.start(); } + @AfterAll + public static void shutdownServer() { + server.stop(); + } + private static StaticSSLContext createSSLOutboundContext() { SSLParser sslOB = new SSLParser(); sslOB.setEndpointIdentificationAlgorithm(""); @@ -72,11 +75,6 @@ private static StaticSSLContext createSSLOutboundContext() { return new StaticSSLContext(sslOB, new ResolverMap(), "/"); } - @AfterAll - public static void shutdownServer() { - server.stop(); - } - @Test void httpsKeepAlive() throws Exception { SSLContext sslCtxOb = createSSLOutboundContext(); @@ -93,4 +91,12 @@ void httpsKeepAlive() throws Exception { assertEquals(1, connectionHashes.size()); } + + private static @NotNull KeyStore getKeyStore() { + var ks = new KeyStore(); + ks.setLocation("classpath:/alias-keystore.p12"); + ks.setKeyPassword("secret"); + ks.setKeyAlias("key1"); + return ks; + } } diff --git a/core/src/test/java/com/predic8/membrane/core/transport/ssl/SSLContextTest.java b/core/src/test/java/com/predic8/membrane/core/transport/ssl/SSLContextTest.java index 62d95b74d7..a1fc597e1c 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/ssl/SSLContextTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/ssl/SSLContextTest.java @@ -14,8 +14,7 @@ package com.predic8.membrane.core.transport.ssl; import com.google.common.io.Resources; -import com.predic8.membrane.core.HttpRouter; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.config.security.*; import com.predic8.membrane.core.resolver.ResolverMap; import org.jetbrains.annotations.NotNull; @@ -45,7 +44,7 @@ public class SSLContextTest { @BeforeAll public static void before() { - router = new HttpRouter(); + router = new DummyTestRouter(); } @AfterAll diff --git a/core/src/test/java/com/predic8/membrane/core/transport/ssl/SessionResumptionTest.java b/core/src/test/java/com/predic8/membrane/core/transport/ssl/SessionResumptionTest.java index 9405efecb3..086e1083c3 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/ssl/SessionResumptionTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/ssl/SessionResumptionTest.java @@ -18,8 +18,8 @@ import com.predic8.membrane.core.exchange.*; import com.predic8.membrane.core.http.*; import com.predic8.membrane.core.interceptor.*; -import com.predic8.membrane.core.resolver.*; import com.predic8.membrane.core.proxies.*; +import com.predic8.membrane.core.resolver.*; import com.predic8.membrane.core.transport.http.*; import org.junit.jupiter.api.*; @@ -27,9 +27,8 @@ import java.net.*; import java.util.concurrent.atomic.*; -import static com.predic8.membrane.core.exchange.Exchange.SSL_CONTEXT; -import static com.predic8.membrane.core.http.Header.CONTENT_ENCODING; -import static com.predic8.membrane.core.http.Header.CONTENT_TYPE; +import static com.predic8.membrane.core.exchange.Exchange.*; +import static com.predic8.membrane.core.http.Header.*; import static com.predic8.membrane.core.interceptor.Outcome.*; /** @@ -46,14 +45,26 @@ public class SessionResumptionTest { private static SSLContext clientTLSContext; @BeforeAll - public static void init() throws IOException { + static void init() throws IOException { tcpForwarder = startTCPForwarder(3044); router1 = createTLSServer(3042); router2 = createTLSServer(3043); - clientTLSContext = createClientTLSContext(); } + @AfterAll + static void done() throws IOException { + try { + tcpForwarder.close(); + } finally { + try { + router1.stop(); + } finally { + router2.stop(); + } + } + } + private static SSLContext createClientTLSContext() { SSLParser sslParser = new SSLParser(); TrustStore trustStore = new TrustStore(); @@ -64,29 +75,9 @@ private static SSLContext createClientTLSContext() { return new StaticSSLContext(sslParser, new ResolverMap(), "."); } - @AfterAll - public static void done() throws IOException { - tcpForwarder.close(); - router1.shutdown(); - router2.shutdown(); - } - - @Disabled - @Test - public void doit() throws Exception { - try(HttpClient hc = new HttpClient()) { - for (int i = 0; i < 2; i++) { - // the tcp forwarder will forward the first connection to 3042, the second to 3043 - Exchange exc = new Request.Builder().get("https://localhost:3044").buildExchange(); - exc.setProperty(SSL_CONTEXT, clientTLSContext); - hc.call(exc); - } - } - } - private static Router createTLSServer(int port) { - Router router = new HttpRouter(); - router.getConfig().setHotDeploy(false); + Router router = new DummyTestRouter(); + router.getConfiguration().setHotDeploy(false); ServiceProxy rule = new ServiceProxy(new ServiceProxyKey(port), null, 0); SSLParser sslInboundParser = new SSLParser(); KeyStore keyStore = new KeyStore(); @@ -127,35 +118,47 @@ private static Closeable startTCPForwarder(int port) throws IOException { AtomicInteger counter = new AtomicInteger(); StreamPump.StreamPumpStats sps = new StreamPump.StreamPumpStats(); ServiceProxy mock = new ServiceProxy(); - try (ServerSocket ss = new ServerSocket(port)) { - Thread t = new Thread(() -> { - try { - while (true) { - Socket inbound; - try { - inbound = ss.accept(); - } catch (Exception e) { - if (e.getMessage().contains("Socket closed")) - return; - throw e; - } - int port1 = 3042 + counter.incrementAndGet() % 2; - try(Socket outbout = new Socket("localhost", port1)) { - Thread s = new Thread(new StreamPump(inbound.getInputStream(), outbout.getOutputStream(), sps, "a", mock)); - s.start(); - Thread s2 = new Thread(new StreamPump(outbout.getInputStream(), inbound.getOutputStream(), sps, "b", mock)); - s2.start(); - } + ServerSocket ss = new ServerSocket(port); + Thread t = new Thread(() -> { + try { + while (true) { + Socket inbound; + try { + inbound = ss.accept(); + } catch (Exception e) { + if (e.getMessage().contains("Socket closed")) + return; + throw e; + } + int port1 = 3042 + counter.incrementAndGet() % 2; + try (Socket outbound = new Socket("localhost", port1)) { + Thread s = new Thread(new StreamPump(inbound.getInputStream(), outbound.getOutputStream(), sps, "a", mock)); + s.start(); + Thread s2 = new Thread(new StreamPump(outbound.getInputStream(), inbound.getOutputStream(), sps, "b", mock)); + s2.start(); } - } catch (Exception e) { - e.printStackTrace(); } - }); - t.start(); - return () -> { - ss.close(); - t.interrupt(); - }; + } catch (Exception e) { + e.printStackTrace(); + } + }); + t.start(); + return () -> { + ss.close(); + t.interrupt(); + }; + } + + @Disabled + @Test + public void doit() throws Exception { + try (HttpClient hc = new HttpClient()) { + for (int i = 0; i < 2; i++) { + // the tcp forwarder will forward the first connection to 3042, the second to 3043 + Exchange exc = new Request.Builder().get("https://localhost:3044").buildExchange(); + exc.setProperty(SSL_CONTEXT, clientTLSContext); + hc.call(exc); + } } } } diff --git a/core/src/test/java/com/predic8/membrane/core/transport/ssl/acme/AcmeServerSimulator.java b/core/src/test/java/com/predic8/membrane/core/transport/ssl/acme/AcmeServerSimulator.java index 6738c8771c..e904c7721f 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/ssl/acme/AcmeServerSimulator.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/ssl/acme/AcmeServerSimulator.java @@ -17,7 +17,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; import com.google.common.io.Resources; -import com.predic8.membrane.core.HttpRouter; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchange.Exchange; import com.predic8.membrane.core.http.*; import com.predic8.membrane.core.interceptor.AbstractInterceptor; @@ -43,20 +43,21 @@ import static com.predic8.membrane.core.http.Header.USER_AGENT; import static com.predic8.membrane.core.http.MimeType.*; import static com.predic8.membrane.core.http.Request.get; +import static com.predic8.membrane.core.http.Response.ok; import static com.predic8.membrane.core.interceptor.Outcome.*; import static java.nio.charset.StandardCharsets.UTF_8; import static org.jose4j.lang.HashUtil.SHA_256; import static org.junit.jupiter.api.Assertions.*; public class AcmeServerSimulator { - private static final Logger LOG = LoggerFactory.getLogger(AcmeServerSimulator.class); + private static final Logger log = LoggerFactory.getLogger(AcmeServerSimulator.class); private final int port; private final int challengePort; private final boolean actuallyPerformChallenge; private final AtomicReference theNonce = new AtomicReference<>(); private final HttpClient hc = new HttpClient(); private final AtomicBoolean challengeSucceeded = new AtomicBoolean(); - private HttpRouter router; + private Router router; private final AcmeCASimulation ca = new AcmeCASimulation(); private String certificates; private final AtomicReference orderStatus = new AtomicReference<>("pending"); @@ -65,13 +66,11 @@ public AcmeServerSimulator(int port, int challengePort, boolean actuallyPerformC this.port = port; this.challengePort = challengePort; this.actuallyPerformChallenge = actuallyPerformChallenge; - ca.init(); } public void start() throws IOException { - router = new HttpRouter(); - router.getConfig().setHotDeploy(false); + router = new TestRouter(); ServiceProxy sp = new ServiceProxy(new ServiceProxyKey(port), "localhost", 80); sp.getFlow().add(new AbstractInterceptor() { final ObjectMapper om = new ObjectMapper(); @@ -86,16 +85,16 @@ public Outcome handleRequest(Exchange exc) { } public Outcome handleRequestInternal(Exchange exc) throws Exception { - LOG.debug("acme server: got " + exc.getRequest().getUri() + " request"); + log.debug("acme server: got " + exc.getRequest().getUri() + " request"); if ("/directory".equals(exc.getRequest().getUri())) { - exc.setResponse(Response.ok() + exc.setResponse(ok() .contentType(APPLICATION_JSON) .body(Resources.toString(getResource("acme/directory.json"), UTF_8)) .build()); return RETURN; } if ("/acme/new-nonce".equals(exc.getRequest().getUri()) && "HEAD".equals(exc.getRequest().getMethod())) { - exc.setResponse(Response.ok() + exc.setResponse(ok() .header("Replay-Nonce", createNonce()) .body("") .build()); @@ -135,7 +134,7 @@ public Outcome handleRequestInternal(Exchange exc) throws Exception { assertNotNull(jws.getJwkHeader(), "RFC 8555 Section 6.2"); String accountUrl = "http://localhost:3050/acme/acct/123456"; - exc.setResponse(Response.ok().status(201, "Created") + exc.setResponse(ok().status(201, "Created") .contentType(APPLICATION_JSON) .header("Location", accountUrl) .header("Replay-Nonce", createNonce()) @@ -166,7 +165,7 @@ public Outcome handleRequestInternal(Exchange exc) throws Exception { return RETURN; } - exc.setResponse(Response.ok().status(201, "Created") + exc.setResponse(ok().status(201, "Created") .contentType(APPLICATION_JSON) .header("Replay-Nonce", createNonce()) .header("Location", "http://localhost:3050/acme/order/42212345") @@ -176,7 +175,7 @@ public Outcome handleRequestInternal(Exchange exc) throws Exception { return RETURN; } if ("/acme/order/42212345".equals(exc.getRequest().getUri())) { - exc.setResponse(Response.ok() + exc.setResponse(ok() .contentType(APPLICATION_JSON) .header("Replay-Nonce", createNonce()) .body(Resources.toString(getResource("acme/order-" + orderStatus.get() + ".json"), UTF_8)) @@ -186,13 +185,13 @@ public Outcome handleRequestInternal(Exchange exc) throws Exception { } if ("/acme/authz-v3/151234567".equals(exc.getRequest().getUri())) { if (challengeSucceeded.get()) { - exc.setResponse(Response.ok() + exc.setResponse(ok() .contentType(APPLICATION_JSON) .header("Replay-Nonce", createNonce()) .body(Resources.toString(getResource("acme/authorization-valid.json"), UTF_8)) .build()); } else { - exc.setResponse(Response.ok() + exc.setResponse(ok() .contentType(APPLICATION_JSON) .header("Replay-Nonce", createNonce()) .body(Resources.toString(getResource("acme/authorization.json"), UTF_8)) @@ -203,7 +202,7 @@ public Outcome handleRequestInternal(Exchange exc) throws Exception { if ("/acme/chall-v3/1555123456/abCd1E".equals(exc.getRequest().getUri())) { startChallenge(jws.getKeyIdHeaderValue()); - exc.setResponse(Response.ok() + exc.setResponse(ok() .contentType(APPLICATION_JSON) .header("Replay-Nonce", createNonce()) .body(Resources.toString(getResource("acme/challenge-pending.json"), UTF_8)) @@ -215,7 +214,7 @@ public Outcome handleRequestInternal(Exchange exc) throws Exception { certificates = ca.sign((String) om.readValue(jws.getPayload(), Map.class).get("csr")); orderStatus.set("valid"); - exc.setResponse(Response.ok() + exc.setResponse(ok() .contentType(APPLICATION_JSON) .header("Replay-Nonce", createNonce()) .body(Resources.toString(getResource("acme/order-processing.json"), UTF_8)) @@ -224,7 +223,7 @@ public Outcome handleRequestInternal(Exchange exc) throws Exception { return RETURN; } if ("/acme/cert/fab123456789abcdef0123456789abcdef12".equals(exc.getRequest().getUri())) { - exc.setResponse(Response.ok() + exc.setResponse(ok() .contentType(APPLICATION_JSON) .header("Replay-Nonce", createNonce()) .body(certificates) diff --git a/core/src/test/java/com/predic8/membrane/core/transport/ssl/acme/AcmeStepTest.java b/core/src/test/java/com/predic8/membrane/core/transport/ssl/acme/AcmeStepTest.java index 63f8119848..4d9b10d6d3 100644 --- a/core/src/test/java/com/predic8/membrane/core/transport/ssl/acme/AcmeStepTest.java +++ b/core/src/test/java/com/predic8/membrane/core/transport/ssl/acme/AcmeStepTest.java @@ -25,6 +25,7 @@ import com.predic8.membrane.core.transport.http.*; import com.predic8.membrane.core.transport.ssl.*; import org.bouncycastle.jce.provider.*; +import org.jetbrains.annotations.*; import org.junit.jupiter.api.*; import java.io.*; @@ -35,6 +36,7 @@ import static com.predic8.membrane.core.interceptor.Outcome.*; import static com.predic8.membrane.core.transport.ssl.acme.Authorization.*; import static com.predic8.membrane.core.transport.ssl.acme.Order.*; +import static com.predic8.membrane.core.transport.ssl.acme.Order.ORDER_STATUS_VALID; import static org.junit.jupiter.api.Assertions.*; public class AcmeStepTest { @@ -47,18 +49,18 @@ public class AcmeStepTest { public final String baseUrl = "http://localhost:3050/directory"; @BeforeEach - public void init() throws IOException { + void init() throws IOException { sim = new AcmeServerSimulator(3050, 3052, true); sim.start(); } @AfterEach - public void done() { + void done() { sim.stop(); } @Test - public void all() throws Exception { + void all() throws Exception { Acme acme = new Acme(); acme.setExperimental(true); acme.setDirectoryUrl(baseUrl); @@ -66,8 +68,7 @@ public void all() throws Exception { acme.setContacts("mailto:jsmith@example.com"); acme.setAcmeSynchronizedStorage(new MemoryStorage()); - HttpRouter router = new HttpRouter(); - router.getConfig().setHotDeploy(false); + var router = new TestRouter(); SSLParser sslParser = new SSLParser(); sslParser.setAcme(acme); ServiceProxy sp1 = new ServiceProxy(new ServiceProxyKey(3051), "localhost", 80); @@ -81,10 +82,9 @@ public Outcome handleRequest(Exchange exc) { }); sp1.setSslInboundParser(sslParser); ServiceProxy sp2 = new ServiceProxy(new ServiceProxyKey(3052), "localhost", 80); - AcmeHttpChallengeInterceptor acmeHttpChallengeInterceptor = new AcmeHttpChallengeInterceptor(); - acmeHttpChallengeInterceptor.setIgnorePort(true); - sp2.getFlow().add(acmeHttpChallengeInterceptor); - router.setRules(ImmutableList.of(sp1, sp2)); + sp2.getFlow().add(getChallengeInterceptor()); + router.add(sp1); + router.add(sp2); router.start(); try { @@ -100,7 +100,7 @@ public Outcome handleRequest(Exchange exc) { OrderAndLocation ol = acmeClient.createOrder(accountUrl, Arrays.asList(hosts)); - assertTrue(ol.getOrder().getAuthorizations().size() > 0); + assertFalse(ol.getOrder().getAuthorizations().isEmpty()); for (String authorization : ol.getOrder().getAuthorizations()) { Authorization auth = acmeClient.getAuth(accountUrl, authorization); @@ -132,8 +132,7 @@ public Outcome handleRequest(Exchange exc) { ol = acmeClient.getOrder(accountUrl, ol.getLocation()); } - - assertEquals(Order.ORDER_STATUS_VALID, ol.getOrder().getStatus()); + assertEquals(ORDER_STATUS_VALID, ol.getOrder().getStatus()); acmeClient.getAsse().setCertChain(hosts, acmeClient.downloadCertificate(accountUrl, ol.getOrder().getCertificate())); @@ -143,24 +142,30 @@ public Outcome handleRequest(Exchange exc) { Thread.sleep(10); } - HttpClient hc = new HttpClient(); - Exchange e = new Request.Builder().get("https://localhost:3051/").buildExchange(); - SSLParser sslParser1 = new SSLParser(); - Trust trust = new Trust(); - Certificate certificate = new Certificate(); - certificate.setContent(sim.getCA().getCertificate()); - trust.setCertificateList(ImmutableList.of(certificate)); - sslParser1.setTrust(trust); - e.setProperty(Exchange.SSL_CONTEXT, new StaticSSLContext(sslParser1, router.getResolverMap(), router.getBaseLocation())); - hc.call(e); - - assertEquals(234, e.getResponse().getStatusCode()); + try(HttpClient hc = new HttpClient()) { + Exchange e = new Request.Builder().get("https://localhost:3051/").buildExchange(); + SSLParser sslParser1 = new SSLParser(); + Trust trust = new Trust(); + Certificate certificate = new Certificate(); + certificate.setContent(sim.getCA().getCertificate()); + trust.setCertificateList(ImmutableList.of(certificate)); + sslParser1.setTrust(trust); + e.setProperty(Exchange.SSL_CONTEXT, new StaticSSLContext(sslParser1, router.getResolverMap(), router.getBaseLocation())); + hc.call(e); + assertEquals(234, e.getResponse().getStatusCode()); + } } finally { router.stop(); // TODO shutdown router in AfterAll } } + private static @NotNull AcmeHttpChallengeInterceptor getChallengeInterceptor() { + var acmeHttpChallengeInterceptor = new AcmeHttpChallengeInterceptor(); + acmeHttpChallengeInterceptor.setIgnorePort(true); + return acmeHttpChallengeInterceptor; + } + private static long waitAndCompute(long wait) throws InterruptedException { Thread.sleep(wait); if (wait < 500) diff --git a/core/src/test/java/com/predic8/membrane/core/ws/SoapProxyInvocationTest.java b/core/src/test/java/com/predic8/membrane/core/ws/SoapProxyInvocationTest.java index 48d4e09fdf..28a8e267b3 100644 --- a/core/src/test/java/com/predic8/membrane/core/ws/SoapProxyInvocationTest.java +++ b/core/src/test/java/com/predic8/membrane/core/ws/SoapProxyInvocationTest.java @@ -65,11 +65,11 @@ public static void setup() throws Exception { } private static void setupGateway() throws Exception { - gw = new HttpRouter(); - gw.getConfig().setHotDeploy(false); - gw.getRuleManager().addProxyAndOpenPortIfNew(createCitiesSoapProxyGateway()); - gw.getRuleManager().addProxyAndOpenPortIfNew(createTwoServicesSOAPProxyGateway("ServiceA")); - gw.init(); + gw = new TestRouter(); + gw.getConfiguration().setHotDeploy(false); + gw.add(createCitiesSoapProxyGateway()); + gw.add(createTwoServicesSOAPProxyGateway("ServiceA")); + gw.start(); } private static @NotNull SOAPProxy createCitiesSoapProxyGateway() { @@ -89,10 +89,10 @@ private static void setupGateway() throws Exception { } private static void setupBackend() throws Exception { - backend = new HttpRouter(); - backend.getRuleManager().addProxyAndOpenPortIfNew(createAServiceProxy()); - backend.getRuleManager().addProxyAndOpenPortIfNew(createCitiesServiceProxy()); - backend.init(); + backend = new TestRouter(); + backend.add(createAServiceProxy()); + backend.add(createCitiesServiceProxy()); + backend.start(); } private static @NotNull APIProxy createCitiesServiceProxy() { @@ -132,8 +132,8 @@ private static void setupBackend() throws Exception { @AfterAll public static void teardown() { - gw.shutdown(); - backend.shutdown(); + gw.stop(); + backend.stop(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/evaluation/JDBCApiKeyStorePerformanceTest.java b/core/src/test/java/com/predic8/membrane/evaluation/JDBCApiKeyStorePerformanceTest.java index ae39b6e739..6ab9576cd9 100644 --- a/core/src/test/java/com/predic8/membrane/evaluation/JDBCApiKeyStorePerformanceTest.java +++ b/core/src/test/java/com/predic8/membrane/evaluation/JDBCApiKeyStorePerformanceTest.java @@ -14,7 +14,7 @@ package com.predic8.membrane.evaluation; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.DefaultRouter; import com.predic8.membrane.core.interceptor.apikey.stores.JDBCApiKeyStore; import com.predic8.membrane.core.interceptor.apikey.stores.KeyTable; import com.predic8.membrane.core.interceptor.apikey.stores.ScopeTable; @@ -59,7 +59,7 @@ void setUp() throws SQLException { jdbcApiKeyStore = createApiKeyStore(); connection = getDataSource().getConnection(); - jdbcApiKeyStore.init(new Router()); + jdbcApiKeyStore.init(new DefaultRouter()); } @AfterEach diff --git a/core/src/test/java/com/predic8/membrane/integration/Util.java b/core/src/test/java/com/predic8/membrane/integration/Util.java index 5e236c78e8..fce200a7ea 100644 --- a/core/src/test/java/com/predic8/membrane/integration/Util.java +++ b/core/src/test/java/com/predic8/membrane/integration/Util.java @@ -22,14 +22,12 @@ import java.util.*; public class Util { - public static HttpRouter basicRouter(Proxy... proxies){ - HttpRouter router = new HttpRouter(); - router.getTransport().setForceSocketCloseOnHotDeployAfter(1000); - router.getConfig().setHotDeploy(false); - + public static Router basicRouter(Proxy... proxies){ + var router = new TestRouter(); + router.getConfiguration().setHotDeploy(false); Arrays.stream(proxies).forEach(rule -> router.getRuleManager().addProxy(rule, RuleManager.RuleDefinitionSource.MANUAL)); - router.start(); + router.getTransport().setForceSocketCloseOnHotDeployAfter(1000); return router; } diff --git a/core/src/test/java/com/predic8/membrane/integration/withinternet/LargeBodyTest.java b/core/src/test/java/com/predic8/membrane/integration/withinternet/LargeBodyTest.java index 34d2086354..41060bbe2b 100644 --- a/core/src/test/java/com/predic8/membrane/integration/withinternet/LargeBodyTest.java +++ b/core/src/test/java/com/predic8/membrane/integration/withinternet/LargeBodyTest.java @@ -20,6 +20,7 @@ import com.predic8.membrane.core.proxies.*; import com.predic8.membrane.core.transport.http.*; import com.predic8.membrane.core.transport.http.client.*; +import org.jetbrains.annotations.*; import org.junit.jupiter.api.*; import java.io.*; @@ -27,14 +28,14 @@ import java.util.concurrent.atomic.*; import static com.predic8.membrane.core.http.Header.*; -import static com.predic8.membrane.core.http.Response.ok; -import static com.predic8.membrane.core.interceptor.Outcome.RETURN; -import static java.lang.Integer.MAX_VALUE; +import static com.predic8.membrane.core.http.Response.*; +import static com.predic8.membrane.core.interceptor.Outcome.*; +import static java.lang.Integer.*; import static org.junit.jupiter.api.Assertions.*; public class LargeBodyTest { - private static HttpRouter router, router2; + private static TestRouter router, router2; private static HttpClientConfiguration hcc; private static final AtomicReference middleExchange = new AtomicReference<>(); @@ -45,7 +46,7 @@ public static void setup() throws Exception { hcc = new HttpClientConfiguration(); hcc.getRetryHandler().setRetries(1); - ServiceProxy proxy = new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", 3040), "thomas-bayer.com", 80); + ServiceProxy proxy = getProxy(3040, "thomas-bayer.com", 80); proxy.getFlow().add(new AbstractInterceptor() { @Override public Outcome handleRequest(Exchange exc) { @@ -53,14 +54,10 @@ public Outcome handleRequest(Exchange exc) { return RETURN; } }); - router = new HttpRouter(); - setClientConfigHTTPClientOnInterceptor(router); - - router.getRuleManager().addProxyAndOpenPortIfNew(proxy); - router.init(); + startNewRouter(router, proxy); - ServiceProxy proxy1 = new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", 3041), "localhost", 3040); + ServiceProxy proxy1 = getProxy(3041, "localhost", 3040); proxy1.getFlow().add(new AbstractInterceptor() { @Override public Outcome handleRequest(Exchange exc) { @@ -68,24 +65,33 @@ public Outcome handleRequest(Exchange exc) { return super.handleRequest(exc); } }); - router2 = new HttpRouter(); - setClientConfigHTTPClientOnInterceptor(router2); + startNewRouter(router2, proxy1); + } + + private static @NotNull ServiceProxy getProxy(int port, String targetHost, int targetPort) { + return new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", port), targetHost, targetPort); + } - router2.getRuleManager().addProxyAndOpenPortIfNew(proxy1); - router2.init(); + private static void startNewRouter(TestRouter router, ServiceProxy proxy) throws IOException { + router = new TestRouter(); + router.add(proxy); + router.start(); + setClientConfigHTTPClientOnInterceptor(router); } - private static void setClientConfigHTTPClientOnInterceptor(HttpRouter router2) { - router2.getTransport().getFirstInterceptorOfType(HTTPClientInterceptor.class).get().setHttpClientConfig(hcc); + private static void setClientConfigHTTPClientOnInterceptor(TestRouter router2) { + var i = router2.getTransport().getFirstInterceptorOfType(HTTPClientInterceptor.class).orElseThrow(); + i.setHttpClientConfig(hcc); + i.init(); } @AfterAll public static void shutdown() { if (router != null) - router.shutdown(); + router.stop(); if (router2 != null) - router2.shutdown(); + router2.stop(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/integration/withinternet/OpenAPIRecordFactoryIntegrationTest.java b/core/src/test/java/com/predic8/membrane/integration/withinternet/OpenAPIRecordFactoryIntegrationTest.java index 4320edfb06..d73361dc51 100644 --- a/core/src/test/java/com/predic8/membrane/integration/withinternet/OpenAPIRecordFactoryIntegrationTest.java +++ b/core/src/test/java/com/predic8/membrane/integration/withinternet/OpenAPIRecordFactoryIntegrationTest.java @@ -27,7 +27,7 @@ public class OpenAPIRecordFactoryIntegrationTest { @BeforeAll static void setUp() { - factory = new OpenAPIRecordFactory(new Router()); + factory = new OpenAPIRecordFactory(new DefaultRouter()); } @Test diff --git a/core/src/test/java/com/predic8/membrane/integration/withinternet/ProxySSLConnectionMethodTest.java b/core/src/test/java/com/predic8/membrane/integration/withinternet/ProxySSLConnectionMethodTest.java index 365dce5c2a..cf5c38e998 100644 --- a/core/src/test/java/com/predic8/membrane/integration/withinternet/ProxySSLConnectionMethodTest.java +++ b/core/src/test/java/com/predic8/membrane/integration/withinternet/ProxySSLConnectionMethodTest.java @@ -14,8 +14,7 @@ package com.predic8.membrane.integration.withinternet; -import com.predic8.membrane.core.HttpRouter; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchangestore.MemoryExchangeStore; import com.predic8.membrane.core.proxies.ProxyRule; import com.predic8.membrane.core.proxies.ProxyRuleKey; @@ -33,15 +32,15 @@ class ProxySSLConnectionMethodTest { @BeforeEach void setUp() throws Exception { - router = new HttpRouter(); + router = new TestRouter(); router.setExchangeStore(new MemoryExchangeStore()); - router.getRuleManager().addProxyAndOpenPortIfNew(new ProxyRule(new ProxyRuleKey(3129))); - router.init(); + router.add(new ProxyRule(new ProxyRuleKey(3129))); + router.start(); } @AfterEach void tearDown() { - router.shutdown(); + router.stop(); } @Test diff --git a/core/src/test/java/com/predic8/membrane/integration/withinternet/ViaProxyTest.java b/core/src/test/java/com/predic8/membrane/integration/withinternet/ViaProxyTest.java index 142842f6e2..bd1ee88f2d 100644 --- a/core/src/test/java/com/predic8/membrane/integration/withinternet/ViaProxyTest.java +++ b/core/src/test/java/com/predic8/membrane/integration/withinternet/ViaProxyTest.java @@ -19,43 +19,44 @@ import com.predic8.membrane.core.transport.http.client.*; import org.junit.jupiter.api.*; -import static com.predic8.membrane.core.RuleManager.RuleDefinitionSource.*; import static io.restassured.RestAssured.*; public class ViaProxyTest { - static HttpRouter proxyRouter; - static HttpRouter router; - - @BeforeAll - static void setUp() throws Exception { - ProxyConfiguration proxy = new ProxyConfiguration(); - proxy.setHost("localhost"); - proxy.setPort(3128); - - proxyRouter = new HttpRouter(proxy); - proxyRouter.getRuleManager().addProxy(new ProxyRule(new ProxyRuleKey(3128)), MANUAL); - proxyRouter.init(); - - ServiceProxy rule = new ServiceProxy(new ServiceProxyKey("localhost", "GET", ".*", 4000), "api.predic8.de", 443); - rule.getTarget().setSslParser(new SSLParser()); - router = new HttpRouter(); - router.getRuleManager().addProxyAndOpenPortIfNew(rule); - router.init(); - } - - @Test - void testPost() { - when() - .get("http://localhost:4000/shop/v2/products") - .then() - .statusCode(200); - } - - @AfterAll - static void tearDown() { - router.shutdown(); - proxyRouter.shutdown(); - } + static Router proxyRouter; + static Router router; + + @BeforeAll + static void setUp() throws Exception { + ProxyConfiguration proxy = new ProxyConfiguration(); + proxy.setHost("localhost"); + proxy.setPort(3128); + + proxyRouter = new TestRouter(proxy); + proxyRouter.add(new ProxyRule(new ProxyRuleKey(3128))); + proxyRouter.start(); + + ServiceProxy rule = new ServiceProxy(new ServiceProxyKey("localhost", "GET", ".*", 4000), "api.predic8.de", 443); + rule.getTarget().setSslParser(new SSLParser()); + router = new TestRouter(); + router.add(rule); + router.start(); + } + + @AfterAll + static void tearDown() { + router.stop(); + proxyRouter.stop(); + } + + @Test + void post() { + when() + .get("http://localhost:4000/shop/v2/products") + .then() + .statusCode(200); + } + + } diff --git a/core/src/test/java/com/predic8/membrane/integration/withinternet/interceptor/RewriteInterceptorIntegrationTest.java b/core/src/test/java/com/predic8/membrane/integration/withinternet/interceptor/RewriteInterceptorIntegrationTest.java index af01ca6355..f304997a61 100644 --- a/core/src/test/java/com/predic8/membrane/integration/withinternet/interceptor/RewriteInterceptorIntegrationTest.java +++ b/core/src/test/java/com/predic8/membrane/integration/withinternet/interceptor/RewriteInterceptorIntegrationTest.java @@ -18,53 +18,72 @@ import com.predic8.membrane.core.http.*; import com.predic8.membrane.core.interceptor.rewrite.RewriteInterceptor; import com.predic8.membrane.core.interceptor.rewrite.RewriteInterceptor.*; +import com.predic8.membrane.core.openapi.serviceproxy.*; import com.predic8.membrane.core.proxies.*; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.*; import org.apache.http.params.*; +import org.apache.http.util.*; import org.junit.jupiter.api.*; +import static com.predic8.membrane.core.http.Header.CONTENT_TYPE; +import static com.predic8.membrane.core.http.MimeType.TEXT_XML_UTF8; +import static org.apache.commons.httpclient.HttpVersion.HTTP_1_1; +import static org.apache.http.params.CoreProtocolPNames.PROTOCOL_VERSION; import static org.junit.jupiter.api.Assertions.*; public class RewriteInterceptorIntegrationTest { - private static HttpRouter router; + private static Router router; + + String soap = """ + + + + Bonn + + + s + """; @BeforeAll - public static void setUp() throws Exception { + static void setUp() throws Exception { RewriteInterceptor interceptor = new RewriteInterceptor(); - interceptor.getMappings().add(new Mapping("/blz-service\\?wsdl", "/axis2/services/BLZService?wsdl", null)); + interceptor.getMappings().add(new Mapping("/city\\?wsdl", "/city-service?wsdl", null)); - ServiceProxy proxy = new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", 3006), "thomas-bayer.com", 80); + ServiceProxy proxy = new APIProxy(); + AbstractServiceProxy.Target target = new AbstractServiceProxy.Target(); + target.setUrl("https://www.predic8.de"); + proxy.setTarget(target); + proxy.setKey(new ServiceProxyKey("localhost", "*", ".*", 3006)); proxy.getFlow().add(interceptor); - router = new HttpRouter(); - router.getRuleManager().addProxyAndOpenPortIfNew(proxy); + router = new TestRouter(); + router.add(proxy); + router.start(); } @AfterAll - public static void tearDown() { - router.shutdown(); + static void tearDown() { + router.stop(); } @Test - public void testRewriting() throws Exception { + void testRewriting() throws Exception { HttpClient client = new HttpClient(); - client.getParams().setParameter(HttpProtocolParams.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); - int status = client.executeMethod(getPostMethod()); - + client.getParams().setParameter(PROTOCOL_VERSION, HTTP_1_1); + var post = getPostMethod(); + int status = client.executeMethod(post); assertEquals(200, status); + assertTrue(post.getResponseBodyAsString().contains("CitySoapBinding")); } private PostMethod getPostMethod() { - PostMethod post = new PostMethod("http://localhost:3006/blz-service?wsdl"); - post.setRequestEntity(new InputStreamRequestEntity(this.getClass().getResourceAsStream("/getBank.xml"))); - post.setRequestHeader(Header.CONTENT_TYPE, MimeType.TEXT_XML_UTF8); + PostMethod post = new PostMethod("http://localhost:3006/city?wsdl"); + post.setRequestEntity(new StringRequestEntity(soap)); + post.setRequestHeader(CONTENT_TYPE, TEXT_XML_UTF8); post.setRequestHeader(Header.SOAP_ACTION, ""); - return post; } - - } diff --git a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/LimitedMemoryExchangeStoreIntegrationTest.java b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/LimitedMemoryExchangeStoreIntegrationTest.java index 2d8a533b2d..1f5100dfa8 100644 --- a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/LimitedMemoryExchangeStoreIntegrationTest.java +++ b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/LimitedMemoryExchangeStoreIntegrationTest.java @@ -29,17 +29,18 @@ import java.util.concurrent.atomic.*; import static com.predic8.membrane.core.http.Header.*; +import static com.predic8.membrane.core.interceptor.Outcome.*; import static org.junit.jupiter.api.Assertions.*; public class LimitedMemoryExchangeStoreIntegrationTest { private static LimitedMemoryExchangeStore lmes; - private static HttpRouter router; - private static HttpRouter router2; + private static Router router; + private static Router router2; private static HttpClientConfiguration hcc; private static final AtomicReference middleExchange = new AtomicReference<>(); @BeforeAll - public static void setup() throws Exception { + static void setup() throws Exception { lmes = new LimitedMemoryExchangeStore(); lmes.setMaxSize(500000); @@ -47,22 +48,20 @@ public static void setup() throws Exception { hcc = new HttpClientConfiguration(); hcc.getRetryHandler().setRetries(1); - ServiceProxy proxy = new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", 3045), "dummy", 80); + ServiceProxy proxy = getServiceProxy(3045, "dummy", 80); proxy.getFlow().add(new AbstractInterceptor() { @Override public Outcome handleRequest(Exchange exc) { exc.setResponse(Response.ok().body("").build()); - return Outcome.RETURN; + return RETURN; } }); - router = new HttpRouter(); + router = new TestRouter(); + router.add(proxy); + router.start(); + setClientConfig(router,hcc); - getHttpClientInterceptor(router).setHttpClientConfig(hcc); - - router.getRuleManager().addProxyAndOpenPortIfNew(proxy); - router.init(); - - ServiceProxy proxy1 = new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", 3046), "localhost", 3045); + ServiceProxy proxy1 = getServiceProxy(3046, "localhost", 3045); proxy1.getFlow().add(new AbstractInterceptor() { @Override public Outcome handleRequest(Exchange exc) { @@ -70,19 +69,26 @@ public Outcome handleRequest(Exchange exc) { return super.handleRequest(exc); } }); - router2 = new HttpRouter(); + router2 = new TestRouter(); router2.setExchangeStore(lmes); - - getHttpClientInterceptor(router2).setHttpClientConfig(hcc); - + router2.add(proxy1); + router2.start(); + setClientConfig(router2,hcc); router2.getTransport().getFlow().add(3, new ExchangeStoreInterceptor(lmes)); + } + + private static void setClientConfig(Router router, HttpClientConfiguration hcc) { + var client = getHttpClientInterceptor(router); + client.setHttpClientConfig(hcc); + client.init(); + } - router2.getRuleManager().addProxyAndOpenPortIfNew(proxy1); - router2.init(); + private static @NotNull ServiceProxy getServiceProxy(int port, String localhost, int targetPort) { + return new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", port), localhost, targetPort); } private static @NotNull HTTPClientInterceptor getHttpClientInterceptor(Router router) { - return (HTTPClientInterceptor) router.getTransport().getFlow().stream().filter(i -> i instanceof HTTPClientInterceptor).findFirst().get(); + return router.getTransport().getFirstInterceptorOfType(HTTPClientInterceptor.class).orElseThrow(); } @BeforeEach @@ -93,9 +99,9 @@ public void init() { @AfterAll public static void shutdown() { if (router != null) - router.shutdown(); + router.stop(); if (router2 != null) - router2.shutdown(); + router2.stop(); } @Test @@ -132,7 +138,7 @@ public void largeChunked() throws Exception { long len = Integer.MAX_VALUE + 1L; Exchange e = new Request.Builder().post("http://localhost:3046/foo").body(len, new LargeBodyTest.ConstantInputStream(len)).header(TRANSFER_ENCODING, CHUNKED).buildExchange(); - try(HttpClient hc = new HttpClient(hcc)) { + try (HttpClient hc = new HttpClient(hcc)) { hc.call(e); } assertTrue(e.getRequest().getBody().wasStreamed()); diff --git a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/MassivelyParallelTest.java b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/MassivelyParallelTest.java index 65d6be89f1..f4d38635ad 100644 --- a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/MassivelyParallelTest.java +++ b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/MassivelyParallelTest.java @@ -21,6 +21,7 @@ import com.predic8.membrane.core.transport.http.*; import org.junit.jupiter.api.*; +import java.io.*; import java.util.*; import java.util.concurrent.*; import java.util.function.*; @@ -31,6 +32,7 @@ import static com.predic8.membrane.core.interceptor.Outcome.*; import static java.lang.Thread.*; import static java.util.concurrent.ConcurrentHashMap.*; +import static java.util.concurrent.TimeUnit.SECONDS; import static org.junit.jupiter.api.Assertions.*; /** @@ -47,19 +49,17 @@ class MassivelyParallelTest { private static int CONCURRENT_THREADS = 500; static HttpClient client; - static HttpRouter server; + static TestRouter server; @BeforeAll - public static void init() { + public static void init() throws IOException { client = new HttpClient(); - - server = new HttpRouter(); + server = new TestRouter(); + server.add(createServiceProxy()); + server.start(); server.getTransport().setConcurrentConnectionLimitPerIp(CONCURRENT_THREADS); server.getTransport().setBacklog(CONCURRENT_THREADS); server.getTransport().setSocketTimeout(10000); - server.getConfig().setHotDeploy(false); - server.getRuleManager().addProxy(createServiceProxy(), MANUAL); - server.start(); } private static ServiceProxy createServiceProxy() { @@ -88,7 +88,7 @@ public static void shutdown() { } @Test - @Timeout(30) // seconds + @Timeout(60) // seconds public void run() throws Exception { Set paths = newKeySet(); runInParallel((cdl) -> parallelTestWorker(cdl, paths), CONCURRENT_THREADS); @@ -96,14 +96,14 @@ public void run() throws Exception { } private void runInParallel(Consumer job, int threadCount) { - try(ExecutorService es = Executors.newVirtualThreadPerTaskExecutor()) { + try (ExecutorService es = Executors.newVirtualThreadPerTaskExecutor()) { CountDownLatch cdl = new CountDownLatch(threadCount); try { for (int i = 0; i < threadCount; i++) { es.submit(() -> job.accept(cdl)); } es.shutdown(); - if (!es.awaitTermination(30, TimeUnit.SECONDS)) { + if (!es.awaitTermination(60, SECONDS)) { es.shutdownNow(); fail("Tasks did not complete within timeout"); } diff --git a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/SessionManagerTest.java b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/SessionManagerTest.java index 004f4fef70..8d33e2f8ce 100644 --- a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/SessionManagerTest.java +++ b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/SessionManagerTest.java @@ -14,39 +14,26 @@ package com.predic8.membrane.integration.withoutinternet; -import com.predic8.membrane.core.HttpRouter; -import com.predic8.membrane.core.exchange.Exchange; -import com.predic8.membrane.core.http.Response; -import com.predic8.membrane.core.interceptor.AbstractInterceptorWithSession; -import com.predic8.membrane.core.interceptor.Outcome; +import com.predic8.membrane.core.*; +import com.predic8.membrane.core.exchange.*; +import com.predic8.membrane.core.http.*; +import com.predic8.membrane.core.interceptor.*; import com.predic8.membrane.core.interceptor.session.*; import com.predic8.membrane.integration.*; import org.apache.http.Header; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.RequestBuilder; -import org.apache.http.client.protocol.HttpClientContext; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; - -import java.time.Duration; -import java.time.Instant; -import java.time.format.DateTimeFormatter; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; -import java.util.stream.Stream; +import org.apache.http.client.config.*; +import org.apache.http.client.methods.*; +import org.apache.http.client.protocol.*; +import org.apache.http.impl.client.*; +import org.junit.jupiter.params.*; +import org.junit.jupiter.params.provider.*; + +import java.time.*; +import java.time.format.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.function.*; +import java.util.stream.*; import static org.junit.jupiter.api.Assertions.*; @@ -79,115 +66,114 @@ private static Object[] inMemory() { @MethodSource("data") public void remembersThings( String nameDummyField, - Supplier smSupplier) throws Exception{ - HttpRouter httpRouter = Util.basicRouter(Util.createServiceProxy(GATEWAY_PORT, testInterceptor(smSupplier))); + Supplier smSupplier) throws Exception { + var httpRouter = Util.basicRouter(Util.createServiceProxy(GATEWAY_PORT, testInterceptor(smSupplier))); HttpClientContext ctx = getHttpClientContext(); String rememberThis = UUID.randomUUID().toString(); String rememberThisFromServer = ""; - try(CloseableHttpClient client = getHttpClient()){ + try (CloseableHttpClient client = getHttpClient()) { - try(CloseableHttpResponse resp = client.execute(RequestBuilder.get("http://localhost:" + GATEWAY_PORT).addHeader(REMEMBER_HEADER, rememberThis).build(),ctx)){ + try (CloseableHttpResponse resp = client.execute(RequestBuilder.get("http://localhost:" + GATEWAY_PORT).addHeader(REMEMBER_HEADER, rememberThis).build(), ctx)) { Arrays.stream(resp.getAllHeaders()).forEach(h -> System.out.println(h.toString())); } - try(CloseableHttpResponse resp = client.execute(new HttpGet("http://localhost:" + GATEWAY_PORT),ctx)){ + try (CloseableHttpResponse resp = client.execute(new HttpGet("http://localhost:" + GATEWAY_PORT), ctx)) { rememberThisFromServer = resp.getFirstHeader(REMEMBER_HEADER).getValue(); Arrays.stream(resp.getAllHeaders()).forEach(h -> System.out.println(h.toString())); } } - assertEquals(rememberThis,rememberThisFromServer); + assertEquals(rememberThis, rememberThisFromServer); httpRouter.stop(); - httpRouter.shutdown(); } @ParameterizedTest(name = "{0}") @MethodSource("data") public void sessionExpires( String nameDummyField, - Supplier smSupplier) throws Exception{ - HttpRouter httpRouter = Util.basicRouter(Util.createServiceProxy(GATEWAY_PORT, testInterceptor(smSupplier, Duration.ZERO))); + Supplier smSupplier) throws Exception { + var httpRouter = Util.basicRouter(Util.createServiceProxy(GATEWAY_PORT, testInterceptor(smSupplier, Duration.ZERO))); HttpClientContext ctx = getHttpClientContext(); String rememberThis = UUID.randomUUID().toString(); String rememberThisFromServer; - try(CloseableHttpClient client = getHttpClient()){ + try (CloseableHttpClient client = getHttpClient()) { - try(CloseableHttpResponse resp = client.execute(RequestBuilder.get("http://localhost:" + GATEWAY_PORT).addHeader(REMEMBER_HEADER, rememberThis).build(),ctx)){ + try (CloseableHttpResponse resp = client.execute(RequestBuilder.get("http://localhost:" + GATEWAY_PORT).addHeader(REMEMBER_HEADER, rememberThis).build(), ctx)) { Arrays.stream(resp.getAllHeaders()).forEach(h -> System.out.println(h.toString())); } - try(CloseableHttpResponse resp = client.execute(new HttpGet("http://localhost:" + GATEWAY_PORT),ctx)){ + try (CloseableHttpResponse resp = client.execute(new HttpGet("http://localhost:" + GATEWAY_PORT), ctx)) { rememberThisFromServer = resp.getFirstHeader(REMEMBER_HEADER).getValue(); Arrays.stream(resp.getAllHeaders()).forEach(h -> System.out.println(h.toString())); } } - assertNotEquals(rememberThis,rememberThisFromServer); + assertNotEquals(rememberThis, rememberThisFromServer); assertEquals("null", rememberThisFromServer); - httpRouter.shutdown(); + httpRouter.stop(); } @ParameterizedTest(name = "{0}") @MethodSource("data") public void changeValueInSession( String nameDummyField, - Supplier smSupplier) throws Exception{ - HttpRouter httpRouter = Util.basicRouter(Util.createServiceProxy(GATEWAY_PORT, testInterceptor(smSupplier))); + Supplier smSupplier) throws Exception { + var httpRouter = Util.basicRouter(Util.createServiceProxy(GATEWAY_PORT, testInterceptor(smSupplier))); HttpClientContext ctx = getHttpClientContext(); String rememberThis = UUID.randomUUID().toString(); String rememberThisFromServer; - try(CloseableHttpClient client = getHttpClient()){ + try (CloseableHttpClient client = getHttpClient()) { - try(CloseableHttpResponse resp = client.execute(RequestBuilder.get("http://localhost:" + GATEWAY_PORT).addHeader(REMEMBER_HEADER, rememberThis).build(),ctx)){ + try (CloseableHttpResponse resp = client.execute(RequestBuilder.get("http://localhost:" + GATEWAY_PORT).addHeader(REMEMBER_HEADER, rememberThis).build(), ctx)) { Arrays.stream(resp.getAllHeaders()).forEach(h -> System.out.println(h.toString())); } - try(CloseableHttpResponse resp = client.execute(RequestBuilder.get("http://localhost:" + GATEWAY_PORT).addHeader(REMEMBER_HEADER, "rememberThis").build(),ctx)){ - if(nameDummyField.equals("jwt")){ + try (CloseableHttpResponse resp = client.execute(RequestBuilder.get("http://localhost:" + GATEWAY_PORT).addHeader(REMEMBER_HEADER, "rememberThis").build(), ctx)) { + if (nameDummyField.equals("jwt")) { List
collect = Arrays.stream(resp.getHeaders("Set-Cookie")).toList(); - assertEquals(2,collect.size()); + assertEquals(2, collect.size()); assertEquals(1, collect.stream().filter(v -> v.getValue().toLowerCase().contains(SessionManager.VALUE_TO_EXPIRE_SESSION_IN_BROWSER.toLowerCase())).count()); Arrays.stream(resp.getAllHeaders()).forEach(h -> System.out.println(h.toString())); } } - try(CloseableHttpResponse resp = client.execute(new HttpGet("http://localhost:" + GATEWAY_PORT),ctx)){ + try (CloseableHttpResponse resp = client.execute(new HttpGet("http://localhost:" + GATEWAY_PORT), ctx)) { rememberThisFromServer = resp.getFirstHeader(REMEMBER_HEADER).getValue(); } } - assertEquals("rememberThis",rememberThisFromServer); + assertEquals("rememberThis", rememberThisFromServer); - httpRouter.shutdown(); + httpRouter.stop(); } @ParameterizedTest(name = "{0}") @MethodSource("data") public void sessionCookie( String nameDummyField, - Supplier smSupplier) throws Exception{ + Supplier smSupplier) throws Exception { AbstractInterceptorWithSession abstractInterceptorWithSession = testInterceptor(smSupplier); abstractInterceptorWithSession.getSessionManager().setSessionCookie(true); - HttpRouter httpRouter = Util.basicRouter(Util.createServiceProxy(GATEWAY_PORT, abstractInterceptorWithSession)); + var httpRouter = Util.basicRouter(Util.createServiceProxy(GATEWAY_PORT, abstractInterceptorWithSession)); HttpClientContext ctx = getHttpClientContext(); String rememberThis = UUID.randomUUID().toString(); - try(CloseableHttpClient client = getHttpClient()){ + try (CloseableHttpClient client = getHttpClient()) { - for(int i = 0; i <= 100; i++) { + for (int i = 0; i <= 100; i++) { try (CloseableHttpResponse resp = client.execute(RequestBuilder.get("http://localhost:" + GATEWAY_PORT).addHeader(REMEMBER_HEADER, rememberThis).build(), ctx)) { - if(resp.getFirstHeader("Set-Cookie") != null) { + if (resp.getFirstHeader("Set-Cookie") != null) { allSetCookieHeadersExceptFor1970Expire(resp).forEach(c -> { assertFalse(c.getValue().toLowerCase().contains("Expire".toLowerCase())); assertFalse(c.getValue().toLowerCase().contains("Max-Age".toLowerCase())); @@ -197,9 +183,9 @@ public void sessionCookie( } } - for(int i = 0; i <= 100; i++) { + for (int i = 0; i <= 100; i++) { try (CloseableHttpResponse resp = client.execute(RequestBuilder.get("http://localhost:" + GATEWAY_PORT).addHeader(REMEMBER_HEADER, UUID.randomUUID().toString()).build(), ctx)) { - if(resp.getFirstHeader("Set-Cookie") != null) { + if (resp.getFirstHeader("Set-Cookie") != null) { allSetCookieHeadersExceptFor1970Expire(resp).forEach(c -> { assertFalse(c.getValue().toLowerCase().contains("Expire".toLowerCase())); assertFalse(c.getValue().toLowerCase().contains("Max-Age".toLowerCase())); @@ -210,20 +196,20 @@ public void sessionCookie( } } - httpRouter.shutdown(); + httpRouter.stop(); } @ParameterizedTest(name = "{0}") @MethodSource("data") public void expiresPartIsRefreshedOnAccess( String nameDummyField, - Supplier smSupplier) throws Exception{ - HttpRouter httpRouter = Util.basicRouter(Util.createServiceProxy(GATEWAY_PORT, testInterceptor(smSupplier))); + Supplier smSupplier) throws Exception { + var httpRouter = Util.basicRouter(Util.createServiceProxy(GATEWAY_PORT, testInterceptor(smSupplier))); HttpClientContext ctx = getHttpClientContext(); String rememberThis = UUID.randomUUID().toString(); - try(CloseableHttpClient client = getHttpClient()){ + try (CloseableHttpClient client = getHttpClient()) { String firstExpires; String secondExpires; @@ -251,14 +237,14 @@ public void expiresPartIsRefreshedOnAccess( } System.out.println(firstExpires); System.out.println(secondExpires); - assertNotEquals(firstExpires,secondExpires); + assertNotEquals(firstExpires, secondExpires); // throws if dates are not parsable - no assert available Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(firstExpires.split("=")[1])); Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(secondExpires.split("=")[1])); } - httpRouter.shutdown(); + httpRouter.stop(); } @ParameterizedTest(name = "{0}") @@ -266,7 +252,7 @@ public void expiresPartIsRefreshedOnAccess( public void parallelRequests( String nameDummyField, Supplier smSupplier) throws Exception { - HttpRouter httpRouter = Util.basicRouter(Util.createServiceProxy(GATEWAY_PORT, testInterceptor(smSupplier))); + var httpRouter = Util.basicRouter(Util.createServiceProxy(GATEWAY_PORT, testInterceptor(smSupplier))); HttpClientContext ctx = getHttpClientContext(); ExecutorService executor = Executors.newCachedThreadPool(); @@ -278,7 +264,7 @@ public void parallelRequests( CloseableHttpClient client = getHttpClient(); - for(int i = 0; i < limit; i++) { + for (int i = 0; i < limit; i++) { executor.execute(() -> { try { startAllInParallel.await(); @@ -292,7 +278,7 @@ public void parallelRequests( .filter(e -> e.contains(",")) .count(); - assertEquals(0,wrongCookies); + assertEquals(0, wrongCookies); } } catch (Exception e) { throw new RuntimeException(e); @@ -307,7 +293,7 @@ public void parallelRequests( executor.shutdown(); executor.awaitTermination(60, TimeUnit.SECONDS); client.close(); - httpRouter.shutdown(); + httpRouter.stop(); } private Stream
allSetCookieHeadersExceptFor1970Expire(CloseableHttpResponse resp) { @@ -328,17 +314,17 @@ private HttpClientContext getHttpClientContext() { private AbstractInterceptorWithSession testInterceptor( Supplier smSupplier, Duration... ttl) { - if(ttl == null || ttl.length == 0) - ttl = new Duration[] {Duration.ofSeconds(300)}; + if (ttl == null || ttl.length == 0) + ttl = new Duration[]{Duration.ofSeconds(300)}; AbstractInterceptorWithSession result = new AbstractInterceptorWithSession() { @Override protected Outcome handleRequestInternal(Exchange exc) { String rememberThis = exc.getRequest().getHeader().getFirstValue(REMEMBER_HEADER); - if(rememberThis == null) - exc.setResponse(Response.ok().header(REMEMBER_HEADER,getSessionManager().getSession(exc).get(REMEMBER_HEADER)).build()); + if (rememberThis == null) + exc.setResponse(Response.ok().header(REMEMBER_HEADER, getSessionManager().getSession(exc).get(REMEMBER_HEADER)).build()); else { - getSessionManager().getSession(exc).put(REMEMBER_HEADER,rememberThis); + getSessionManager().getSession(exc).put(REMEMBER_HEADER, rememberThis); exc.setResponse(Response.ok().build()); } return Outcome.RETURN; diff --git a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/AcmeRenewTest.java b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/AcmeRenewTest.java index 2750f74d80..71486c6d3a 100644 --- a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/AcmeRenewTest.java +++ b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/AcmeRenewTest.java @@ -67,8 +67,7 @@ public void all() throws Exception { acme.setContacts("mailto:jsmith@example.com"); acme.setAcmeSynchronizedStorage(new MemoryStorage()); - HttpRouter router = new HttpRouter(); - router.getConfig().setHotDeploy(false); + Router router = new TestRouter(); SSLParser sslParser = new SSLParser(); sslParser.setAcme(acme); ServiceProxy sp1 = new ServiceProxy(new ServiceProxyKey(3051), "localhost", 80); @@ -85,7 +84,8 @@ public Outcome handleRequest(Exchange exc) { AcmeHttpChallengeInterceptor acmeHttpChallengeInterceptor = new AcmeHttpChallengeInterceptor(); acmeHttpChallengeInterceptor.setIgnorePort(true); sp2.getFlow().add(acmeHttpChallengeInterceptor); - router.setRules(ImmutableList.of(sp1, sp2)); + router.add(sp1); + router.add(sp2); router.start(); try { diff --git a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/OpenApiRewriteIntegrationTest.java b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/OpenApiRewriteIntegrationTest.java index 6b6de443a1..2f28566aaf 100644 --- a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/OpenApiRewriteIntegrationTest.java +++ b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/OpenApiRewriteIntegrationTest.java @@ -13,8 +13,7 @@ limitations under the License. */ package com.predic8.membrane.integration.withoutinternet.interceptor; -import com.predic8.membrane.core.HttpRouter; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.interceptor.flow.*; import com.predic8.membrane.core.interceptor.log.*; import com.predic8.membrane.core.openapi.serviceproxy.*; @@ -30,18 +29,19 @@ public class OpenApiRewriteIntegrationTest { - private final Router r = new HttpRouter(); + private Router r; @BeforeEach public void setUp() throws Exception { - r.getRuleManager().addProxyAndOpenPortIfNew(getApiProxy()); - r.getRuleManager().addProxyAndOpenPortIfNew(getTargetProxy()); - r.init(); + r = new TestRouter(); + r.add(getApiProxy()); + r.add(getTargetProxy()); + r.start(); } @AfterEach public void tearDown() { - r.shutdown(); + r.stop(); } @NotNull diff --git a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/REST2SOAPInterceptorIntegrationTest.java b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/REST2SOAPInterceptorIntegrationTest.java index fd37c01487..fade5fde68 100644 --- a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/REST2SOAPInterceptorIntegrationTest.java +++ b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/REST2SOAPInterceptorIntegrationTest.java @@ -29,14 +29,14 @@ public class REST2SOAPInterceptorIntegrationTest { - private static HttpRouter router; + private static Router router; @BeforeAll public static void setUp() throws Exception { ServiceProxy proxy = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", 3004), "", 0); - router = new HttpRouter(); - router.getRuleManager().addProxyAndOpenPortIfNew(proxy); + router = new TestRouter(); + router.add(proxy); var interceptors = proxy.getFlow(); REST2SOAPInterceptor rest2SoapInt = new REST2SOAPInterceptor(); @@ -45,12 +45,12 @@ public static void setUp() throws Exception { SampleSoapServiceInterceptor sampleSoapInt = new SampleSoapServiceInterceptor(); interceptors.add(sampleSoapInt); - router.init(); + router.start(); } @AfterAll public static void tearDown() { - router.shutdown(); + router.stop(); } @Test @@ -60,7 +60,6 @@ public void testRest() throws Exception { GetMethod get = new GetMethod("http://localhost:3004/city/Bonn"); int status = client.executeMethod(get); - System.out.println(get.getResponseBodyAsString()); assertEquals(200, status); } diff --git a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/SOAPProxyIntegrationTest.java b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/SOAPProxyIntegrationTest.java index a62dfb7823..4e6ce0ad84 100644 --- a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/SOAPProxyIntegrationTest.java +++ b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/SOAPProxyIntegrationTest.java @@ -33,28 +33,28 @@ public static void setup() throws Exception { ServiceProxy proxy = new ServiceProxy(new ServiceProxyKey(3000), null, 0); proxy.getFlow().add(new SampleSoapServiceInterceptor()); - targetRouter = new HttpRouter(); - targetRouter.getRuleManager().addProxyAndOpenPortIfNew(proxy); - targetRouter.init(); + targetRouter = new TestRouter(); + targetRouter.add(proxy); + targetRouter.start(); } @AfterAll public static void teardown() { - targetRouter.shutdown(); + targetRouter.stop(); } @BeforeEach - public void startRouter() { - router = Router.init("classpath:/soap-proxy.xml"); + void startRouter() { + router = RouterXmlBootstrap.initByXML("classpath:/soap-proxy.xml"); } @AfterEach - public void shutdownRouter() { - router.shutdown(); + void shutdownRouter() { + router.stop(); } @Test - public void targetProxyTest() { + void targetProxyTest() { when() .get("http://localhost:3000/foo?wsdl") .then() @@ -62,7 +62,7 @@ public void targetProxyTest() { } @Test - public void rewriteSimpleTest() { + void rewriteSimpleTest() { when() .get("http://localhost:2000/foo?wsdl") .then() diff --git a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/oauth2/OAuth2AuthorizationServerInterceptorBase.java b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/oauth2/OAuth2AuthorizationServerInterceptorBase.java index dcd6594470..56d96b954f 100644 --- a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/oauth2/OAuth2AuthorizationServerInterceptorBase.java +++ b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/oauth2/OAuth2AuthorizationServerInterceptorBase.java @@ -202,13 +202,19 @@ public static Runnable runUntilGoodAuthOpenidRequest() { } @BeforeEach - public void setUp() throws Exception{ - router = new HttpRouter(); + void setUp() throws Exception{ + router = new TestRouter(); + router.start(); initOasi(); initMas(); initLoginMockParametersForJohn(); } + @AfterEach + void tearDown() { + router.stop(); + } + public static Collection data() throws Exception { return List.of(); } @@ -281,7 +287,7 @@ private void initMas() throws Exception { //mas.init2(); // requires pull request 330 } - private void initOasi() throws Exception { + private void initOasi() { oasi = new OAuth2AuthorizationServerInterceptor() { @Override public String computeBasePath() { diff --git a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/oauth2/OAuth2Test.java b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/oauth2/OAuth2Test.java index 2f25f9d350..e2fd02daa0 100644 --- a/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/oauth2/OAuth2Test.java +++ b/core/src/test/java/com/predic8/membrane/integration/withoutinternet/interceptor/oauth2/OAuth2Test.java @@ -39,8 +39,8 @@ class OAuth2Test { - static Router router; - static Router router2; + static DefaultRouter router; + static DefaultRouter router2; static ServiceProxy oAuth2ServerProxy; static OAuth2AuthorizationServerInterceptor oAuth2ASI; @@ -53,8 +53,8 @@ class OAuth2Test { @BeforeAll static void startup() throws Exception { - router = new Router(); - router.getConfig().setHotDeploy(false); + router = new DefaultRouter(); + router.getConfiguration().setHotDeploy(false); router.setExchangeStore(new ForgetfulExchangeStore()); router.setTransport(new HttpTransport()); @@ -67,8 +67,8 @@ static void startup() throws Exception { router.init(); router.start(); - router2 = new Router(); - router2.getConfig().setHotDeploy(false); + router2 = new DefaultRouter(); + router2.getConfiguration().setHotDeploy(false); router2.setExchangeStore(new ForgetfulExchangeStore()); router2.setTransport(new HttpTransport()); diff --git a/core/src/test/java/com/predic8/membrane/interceptor/LoadBalancingInterceptorFaultMonitoringStrategyTest.java b/core/src/test/java/com/predic8/membrane/interceptor/LoadBalancingInterceptorFaultMonitoringStrategyTest.java index 7dfbb9f89e..392a355d22 100644 --- a/core/src/test/java/com/predic8/membrane/interceptor/LoadBalancingInterceptorFaultMonitoringStrategyTest.java +++ b/core/src/test/java/com/predic8/membrane/interceptor/LoadBalancingInterceptorFaultMonitoringStrategyTest.java @@ -56,11 +56,27 @@ class LoadBalancingInterceptorFaultMonitoringStrategyTest { private static final Logger log = LoggerFactory.getLogger(LoadBalancingInterceptorFaultMonitoringStrategyTest.class.getName()); LoadBalancingInterceptor balancingInterceptor; - HttpRouter balancer; + Router balancer; // The simulation nodes private final List nodes = new ArrayList<>(); + @AfterEach + void tearDown() { + for (Router httpRouter : nodes) { + try { + httpRouter.stop(); + } catch (Exception e) { + log.warn("Node shutdown failed.", e); + } + } + try { + balancer.stop(); + } catch (Exception e) { + log.warn("Balancer shutdown failed.", e); + } + } + private void setUp(TestingContext ctx) throws Exception { nodes.clear(); for (int i = 1; i <= ctx.numNodes; i++) { @@ -75,15 +91,17 @@ private void setUp(TestingContext ctx) throws Exception { } } - private HttpRouter createLoadBalancer() throws Exception { - HttpRouter r = new HttpRouter(); + private Router createLoadBalancer() throws Exception { + Router r = new TestRouter(); ServiceProxy sp3 = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", 3054), "thomas-bayer.com", 80); balancingInterceptor = new LoadBalancingInterceptor(); balancingInterceptor.setName("Default"); sp3.getFlow().add(balancingInterceptor); - r.getRuleManager().addProxyAndOpenPortIfNew(sp3); - r.getTransport().getFirstInterceptorOfType(HTTPClientInterceptor.class).get().setHttpClientConfig(getHttpClientConfigurationWithRetries()); - r.init(); + r.add(sp3); + r.start(); + var client = r.getTransport().getFirstInterceptorOfType(HTTPClientInterceptor.class).orElseThrow(); + client.setHttpClientConfig(getHttpClientConfigurationWithRetries()); + client.init(); return r; } @@ -98,39 +116,23 @@ private HttpRouter createLoadBalancer() throws Exception { } private Router createRouterForNode(TestingContext ctx, int i) throws Exception { - HttpRouter r = new HttpRouter(); - r.getRuleManager().addProxyAndOpenPortIfNew(createServiceProxy(ctx, i)); - r.init(); + var r = new TestRouter(); + r.add(createServiceProxy(ctx, i)); + r.start(); return r; } private @NotNull ServiceProxy createServiceProxy(TestingContext ctx, int i) { - ServiceProxy serviceProxy = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", (2000 + i)), "thomas-bayer.com", 80); - serviceProxy.getFlow().add(new AbstractInterceptor() { + ServiceProxy sp = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", (2000 + i)), "thomas-bayer.com", 80); + sp.getFlow().add(new AbstractInterceptor() { @Override public Outcome handleResponse(Exchange exc) { exc.getResponse().getHeader().setConnection("close"); return CONTINUE; } }); - serviceProxy.getFlow().add(new RandomlyFailingDummyWebServiceInterceptor(ctx.successChance)); - return serviceProxy; - } - - @AfterEach - void tearDown() { - for (Router httpRouter : nodes) { - try { - httpRouter.shutdown(); - } catch (Exception e) { - log.warn("Node shutdown failed.", e); - } - } - try { - balancer.shutdown(); - } catch (Exception e) { - log.warn("Balancer shutdown failed.", e); - } + sp.getFlow().add(new RandomlyFailingDummyWebServiceInterceptor(ctx.successChance)); + return sp; } /** @@ -155,7 +157,7 @@ void test_2destinations_6threads_100calls_allFail() throws Exception { * Because we set the success chance to 1, all will pass. */ @Test - public void test_2destinations_6threads_100calls_allSucceed() throws Exception { + void test_2destinations_6threads_100calls_allSucceed() throws Exception { TestingContext ctx = new TestingContext.Builder() .numNodes(2) .numThreads(6) @@ -204,7 +206,7 @@ public void test_5destinations_6threads_100calls_1shutdown() throws Exception { .successChance(1d) .preSubmitCallback(integer -> { if (integer == 20) { - nodes.getFirst().shutdown(); + nodes.getFirst().stop(); } return null; }) @@ -212,7 +214,7 @@ public void test_5destinations_6threads_100calls_1shutdown() throws Exception { run(ctx); - assertTrue(ctx.successCounter.get() > 95,"ctx.successCounter.get() > 95 was %s".formatted(ctx.successCounter.get())); + assertTrue(ctx.successCounter.get() > 95, "ctx.successCounter.get() > 95 was %s".formatted(ctx.successCounter.get())); for (int i = 0; i < 100; i++) { if (i < 10 || i >= 40) { assertTrue(ctx.runtimes[i] < 500, "For " + i + " value was: " + ctx.runtimes[i]); @@ -234,13 +236,13 @@ void test_5destinations_6threads_100calls_4shutdown() throws Exception { .successChance(1d) .preSubmitCallback(i -> { if (i == 10) { - nodes.getFirst().shutdown(); + nodes.getFirst().stop(); } else if (i == 20) { - nodes.get(1).shutdown(); + nodes.get(1).stop(); } else if (i == 30) { - nodes.get(2).shutdown(); + nodes.get(2).stop(); } else if (i == 40) { - nodes.get(3).shutdown(); + nodes.get(3).stop(); } return null; }) diff --git a/core/src/test/java/com/predic8/membrane/interceptor/LoadBalancingInterceptorTest.java b/core/src/test/java/com/predic8/membrane/interceptor/LoadBalancingInterceptorTest.java index 2fbd0056b0..0f765282bd 100644 --- a/core/src/test/java/com/predic8/membrane/interceptor/LoadBalancingInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/interceptor/LoadBalancingInterceptorTest.java @@ -29,18 +29,16 @@ import static com.predic8.membrane.core.http.Header.*; import static com.predic8.membrane.core.http.MimeType.*; -import static com.predic8.membrane.core.http.Response.internalServerError; -import static com.predic8.membrane.core.interceptor.InterceptorUtil.getInterceptors; +import static com.predic8.membrane.core.http.Response.*; import static com.predic8.membrane.core.interceptor.Outcome.*; import static com.predic8.membrane.core.interceptor.balancer.BalancerUtil.*; -import static com.predic8.membrane.core.util.NetworkUtil.*; import static java.lang.Thread.*; import static java.util.Objects.*; import static org.apache.commons.httpclient.HttpVersion.*; import static org.apache.http.params.HttpProtocolParams.*; import static org.junit.jupiter.api.Assertions.*; -public class LoadBalancingInterceptorTest { +public abstract class LoadBalancingInterceptorTest { private DummyWebServiceInterceptor mockInterceptor1; private DummyWebServiceInterceptor mockInterceptor2; @@ -48,53 +46,53 @@ public class LoadBalancingInterceptorTest { private DispatchingStrategy roundRobin; private DispatchingStrategy byThreadStrategy; private DispatchingStrategy priorityStrategy; - private HttpRouter service1; - private HttpRouter service2; - protected HttpRouter balancer; + private Router service1; + private Router service2; + protected Router balancer; @BeforeEach public void setUp() throws Exception { - int port2k = getFreePortEqualAbove(2000); - int port3k = getFreePortEqualAbove(3000); - service1 = new HttpRouter(); + int port2k = 2000; + int port3k = 3000; + service1 = new TestRouter(); mockInterceptor1 = new DummyWebServiceInterceptor(); ServiceProxy sp1 = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", port2k), "dummy", 80); sp1.getFlow().add(new AbstractInterceptor(){ @Override public Outcome handleResponse(Exchange exc) { - exc.getResponse().getHeader().add("Connection", "close"); + exc.getResponse().getHeader().setConnection("close"); return CONTINUE; } }); sp1.getFlow().add(mockInterceptor1); - service1.getRuleManager().addProxyAndOpenPortIfNew(sp1); - service1.init(); + service1.add(sp1); + service1.start(); - service2 = new HttpRouter(); + service2 = new TestRouter(); mockInterceptor2 = new DummyWebServiceInterceptor(); ServiceProxy sp2 = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", port3k), "dummy", 80); sp2.getFlow().add(new AbstractInterceptor(){ @Override public Outcome handleResponse(Exchange exc) { - exc.getResponse().getHeader().add("Connection", "close"); + exc.getResponse().getHeader().setConnection("close"); return CONTINUE; } }); sp2.getFlow().add(mockInterceptor2); - service2.getRuleManager().addProxyAndOpenPortIfNew(sp2); - service2.init(); + service2.add(sp2); + service2.start(); - balancer = new HttpRouter(); + balancer = new TestRouter(); ServiceProxy sp3 = new ServiceProxy(new ServiceProxyKey("localhost", "*", ".*", 3054), "dummy", 80); balancingInterceptor = new LoadBalancingInterceptor(); balancingInterceptor.setName("Default"); sp3.getFlow().add(balancingInterceptor); - balancer.getRuleManager().addProxyAndOpenPortIfNew(sp3); + balancer.add(sp3); + balancer.start(); enableFailOverOn5XX(); - balancer.init(); lookupBalancer(balancer, "Default").up("Default", "localhost", port2k); lookupBalancer(balancer, "Default").up("Default", "localhost", port3k); @@ -105,14 +103,16 @@ public Outcome handleResponse(Exchange exc) { } private void enableFailOverOn5XX() { - getInterceptors(balancer.getTransport().getFlow(), HTTPClientInterceptor.class).getLast().setFailOverOn5XX(true); + var clientInterceptor = balancer.getTransport().getFirstInterceptorOfType(HTTPClientInterceptor.class).orElseThrow(); + clientInterceptor.setFailOverOn5XX(true); + clientInterceptor.init(); // Copies the config into the HttpClient. Needed because router.start() is already called } @AfterEach void tearDown() { - service1.shutdown(); - service2.shutdown(); - balancer.shutdown(); + service1.stop(); + service2.stop(); + balancer.stop(); } @Test @@ -146,7 +146,6 @@ void roundRobinDispatchingStrategy() throws Exception { PostMethod vari = getPostMethod(); int status = client.executeMethod(vari); - //System.out.println(new String(vari.getResponseBody())); assertEquals(200, status); assertEquals(1, mockInterceptor1.getCount()); @@ -223,7 +222,7 @@ void failOverOnConnectionRefused() throws Exception { assertEquals(1, mockInterceptor1.getCount()); assertEquals(1, mockInterceptor2.getCount()); - service1.shutdown(); + service1.stop(); sleep(1000); assertEquals(200, client.executeMethod(getPostMethod())); diff --git a/core/src/test/java/com/predic8/membrane/interceptor/MultipleLoadBalancersTest.java b/core/src/test/java/com/predic8/membrane/interceptor/MultipleLoadBalancersTest.java index 0de9b01119..c00569b12d 100644 --- a/core/src/test/java/com/predic8/membrane/interceptor/MultipleLoadBalancersTest.java +++ b/core/src/test/java/com/predic8/membrane/interceptor/MultipleLoadBalancersTest.java @@ -15,8 +15,8 @@ package com.predic8.membrane.interceptor; import com.predic8.membrane.core.*; -import com.predic8.membrane.core.http.Header; import com.predic8.membrane.core.http.*; +import com.predic8.membrane.core.http.Header; import com.predic8.membrane.core.interceptor.balancer.*; import com.predic8.membrane.core.proxies.*; import com.predic8.membrane.core.services.*; @@ -28,132 +28,131 @@ import static org.junit.jupiter.api.Assertions.*; public class MultipleLoadBalancersTest { - private static MockService service1; - private static MockService service2; - private static MockService service11; - private static MockService service12; - - protected static LoadBalancingInterceptor balancingInterceptor1; - protected static LoadBalancingInterceptor balancingInterceptor2; - private static DispatchingStrategy roundRobinStrategy1; - private static DispatchingStrategy roundRobinStrategy2; - protected static HttpRouter balancer; - - private static class MockService { - final int port; - final HttpRouter service1; - final DummyWebServiceInterceptor mockInterceptor1; - - MockService(int port) throws Exception { - this.port = port; - service1 = new HttpRouter(); - mockInterceptor1 = new DummyWebServiceInterceptor(); - ServiceProxy sp1 = new ServiceProxy(new ServiceProxyKey("localhost", - "POST", ".*", port), "thomas-bayer.com", 80); - sp1.getFlow().add(mockInterceptor1); - service1.getRuleManager().addProxyAndOpenPortIfNew(sp1); - service1.init(); - } - - public void close() { - service1.shutdown(); - } - } - - private static LoadBalancingInterceptor createBalancingInterceptor(int port, String name) throws Exception { - ServiceProxy sp3 = new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", port), "thomas-bayer.com", 80); - LoadBalancingInterceptor balancingInterceptor1 = new LoadBalancingInterceptor(); - balancingInterceptor1.setName(name); - sp3.getFlow().add(balancingInterceptor1); - balancer.getRuleManager().addProxyAndOpenPortIfNew(sp3); - balancer.init(); - return balancingInterceptor1; - } - - - @BeforeAll - public static void setUp() throws Exception { - - service1 = new MockService(2001); - service2 = new MockService(2002); - service11 = new MockService(2011); - service12 = new MockService(2012); - - balancer = new HttpRouter(); - - balancingInterceptor1 = createBalancingInterceptor(3054, "Default"); - balancingInterceptor2 = createBalancingInterceptor(7001, "Balancer2"); - - BalancerUtil.lookupBalancer(balancer, "Default").up("Default", "localhost", service1.port); - BalancerUtil.lookupBalancer(balancer, "Default").up("Default", "localhost", service2.port); - - BalancerUtil.lookupBalancer(balancer, "Balancer2").up("Default", "localhost", service11.port); - BalancerUtil.lookupBalancer(balancer, "Balancer2").up("Default", "localhost", service12.port); - - - roundRobinStrategy1 = new RoundRobinStrategy(); - roundRobinStrategy2 = new RoundRobinStrategy(); - } - - @AfterAll - public static void tearDown() throws Exception { - service1.close(); - service2.close(); - service11.close(); - service12.close(); - balancer.shutdown(); - } - - private void assertMockCounters(int n1, int n2, int n11, int n12) { - assertEquals(n1, service1.mockInterceptor1.getCount()); - assertEquals(n2, service2.mockInterceptor1.getCount()); - assertEquals(n11, service11.mockInterceptor1.getCount()); - assertEquals(n12, service12.mockInterceptor1.getCount()); - } - - @Test - public void testRoundRobinDispachingStrategy() throws Exception { - balancingInterceptor1.setDispatchingStrategy(roundRobinStrategy1); - balancingInterceptor2.setDispatchingStrategy(roundRobinStrategy2); - - HttpClient client = new HttpClient(); - client.getParams().setParameter(HttpProtocolParams.PROTOCOL_VERSION, - HttpVersion.HTTP_1_1); - - PostMethod vari = getPostMethod(3054); - int status = client.executeMethod(vari); - - assertEquals(200, status); - assertMockCounters(1, 0, 0, 0); - - assertEquals(200, client.executeMethod(getPostMethod(3054))); - assertMockCounters(1, 1, 0, 0); - - assertEquals(200, client.executeMethod(getPostMethod(3054))); - assertMockCounters(2, 1, 0, 0); - - assertEquals(200, client.executeMethod(getPostMethod(3054))); - assertMockCounters(2, 2, 0, 0); - - assertEquals(200, client.executeMethod(getPostMethod(7001))); - assertMockCounters(2, 2, 1, 0); - - assertEquals(200, client.executeMethod(getPostMethod(7001))); - assertMockCounters(2, 2, 1, 1); - - assertEquals(200, client.executeMethod(getPostMethod(7001))); - assertMockCounters(2, 2, 2, 1); - } - - private PostMethod getPostMethod(int port) { - PostMethod post = new PostMethod( - "http://localhost:" + port + "/axis2/services/BLZService"); - post.setRequestEntity(new InputStreamRequestEntity(this.getClass() - .getResourceAsStream("/getBank.xml"))); - post.setRequestHeader(Header.CONTENT_TYPE, MimeType.TEXT_XML_UTF8); - post.setRequestHeader(Header.SOAP_ACTION, ""); - - return post; - } + private static MockService service1; + private static MockService service2; + private static MockService service11; + private static MockService service12; + + protected static LoadBalancingInterceptor balancingInterceptor1; + protected static LoadBalancingInterceptor balancingInterceptor2; + private static DispatchingStrategy roundRobinStrategy1; + private static DispatchingStrategy roundRobinStrategy2; + protected static Router balancer; + + @AfterAll + static void tearDown() { + service1.close(); + service2.close(); + service11.close(); + service12.close(); + balancer.stop(); + } + + private static class MockService { + final int port; + final Router router; + final DummyWebServiceInterceptor mockInterceptor1; + + MockService(int port) throws Exception { + this.port = port; + router = new TestRouter(); + mockInterceptor1 = new DummyWebServiceInterceptor(); + ServiceProxy sp1 = new ServiceProxy(new ServiceProxyKey("localhost", + "POST", ".*", port), "thomas-bayer.com", 80); + sp1.getFlow().add(mockInterceptor1); + router.add(sp1); + router.start(); + } + + public void close() { + router.stop(); + } + } + + private static LoadBalancingInterceptor createBalancingInterceptor(int port, String name) throws Exception { + ServiceProxy sp3 = new ServiceProxy(new ServiceProxyKey("localhost", "POST", ".*", port), "thomas-bayer.com", 80); + LoadBalancingInterceptor balancingInterceptor1 = new LoadBalancingInterceptor(); + balancingInterceptor1.setName(name); + sp3.getFlow().add(balancingInterceptor1); + balancer.add(sp3); + return balancingInterceptor1; + } + + + @BeforeAll + static void setUp() throws Exception { + + service1 = new MockService(2001); + service2 = new MockService(2002); + service11 = new MockService(2011); + service12 = new MockService(2012); + + balancer = new TestRouter(); + + balancingInterceptor1 = createBalancingInterceptor(3054, "Default"); + balancingInterceptor2 = createBalancingInterceptor(7001, "Balancer2"); + balancer.start(); + + BalancerUtil.lookupBalancer(balancer, "Default").up("Default", "localhost", service1.port); + BalancerUtil.lookupBalancer(balancer, "Default").up("Default", "localhost", service2.port); + + BalancerUtil.lookupBalancer(balancer, "Balancer2").up("Default", "localhost", service11.port); + BalancerUtil.lookupBalancer(balancer, "Balancer2").up("Default", "localhost", service12.port); + + roundRobinStrategy1 = new RoundRobinStrategy(); + roundRobinStrategy2 = new RoundRobinStrategy(); + } + + private void assertMockCounters(int n1, int n2, int n11, int n12) { + assertEquals(n1, service1.mockInterceptor1.getCount()); + assertEquals(n2, service2.mockInterceptor1.getCount()); + assertEquals(n11, service11.mockInterceptor1.getCount()); + assertEquals(n12, service12.mockInterceptor1.getCount()); + } + + @Test + void roundRobinDispatchingStrategy() throws Exception { + balancingInterceptor1.setDispatchingStrategy(roundRobinStrategy1); + balancingInterceptor2.setDispatchingStrategy(roundRobinStrategy2); + + HttpClient client = new HttpClient(); + client.getParams().setParameter(HttpProtocolParams.PROTOCOL_VERSION, + HttpVersion.HTTP_1_1); + + PostMethod vari = getPostMethod(3054); + int status = client.executeMethod(vari); + + assertEquals(200, status); + assertMockCounters(1, 0, 0, 0); + + assertEquals(200, client.executeMethod(getPostMethod(3054))); + assertMockCounters(1, 1, 0, 0); + + assertEquals(200, client.executeMethod(getPostMethod(3054))); + assertMockCounters(2, 1, 0, 0); + + assertEquals(200, client.executeMethod(getPostMethod(3054))); + assertMockCounters(2, 2, 0, 0); + + assertEquals(200, client.executeMethod(getPostMethod(7001))); + assertMockCounters(2, 2, 1, 0); + + assertEquals(200, client.executeMethod(getPostMethod(7001))); + assertMockCounters(2, 2, 1, 1); + + assertEquals(200, client.executeMethod(getPostMethod(7001))); + assertMockCounters(2, 2, 2, 1); + } + + private PostMethod getPostMethod(int port) { + PostMethod post = new PostMethod( + "http://localhost:" + port + "/axis2/services/BLZService"); + post.setRequestEntity(new InputStreamRequestEntity(this.getClass() + .getResourceAsStream("/getBank.xml"))); + post.setRequestHeader(Header.CONTENT_TYPE, MimeType.TEXT_XML_UTF8); + post.setRequestHeader(Header.SOAP_ACTION, ""); + + return post; + } } diff --git a/core/src/test/java/com/predic8/membrane/interceptor/ws_addressing/WsaEndpointRewriterInterceptorTest.java b/core/src/test/java/com/predic8/membrane/interceptor/ws_addressing/WsaEndpointRewriterInterceptorTest.java index 15732654e3..ab0134fa4c 100644 --- a/core/src/test/java/com/predic8/membrane/interceptor/ws_addressing/WsaEndpointRewriterInterceptorTest.java +++ b/core/src/test/java/com/predic8/membrane/interceptor/ws_addressing/WsaEndpointRewriterInterceptorTest.java @@ -29,7 +29,7 @@ public class WsaEndpointRewriterInterceptorTest { @BeforeEach public void setUp() throws Exception { - Router router = new HttpRouter(); + Router router = new DummyTestRouter(); router.init(); rewriter = new WsaEndpointRewriterInterceptor(); rewriter.init(router); diff --git a/core/src/test/resources/log4j2.xml b/core/src/test/resources/log4j2.xml index 169c6a9115..2fca88179f 100644 --- a/core/src/test/resources/log4j2.xml +++ b/core/src/test/resources/log4j2.xml @@ -14,7 +14,7 @@ - + diff --git a/core/src/test/resources/proxy-rules-test-monitor-beans.xml b/core/src/test/resources/proxy-rules-test-monitor-beans.xml index 9e0107ca23..87ca7eb2e4 100644 --- a/core/src/test/resources/proxy-rules-test-monitor-beans.xml +++ b/core/src/test/resources/proxy-rules-test-monitor-beans.xml @@ -11,7 +11,7 @@ - + diff --git a/core/src/test/resources/ref.proxies.xml b/core/src/test/resources/ref.proxies.xml index 4d32511761..75f003c13b 100644 --- a/core/src/test/resources/ref.proxies.xml +++ b/core/src/test/resources/ref.proxies.xml @@ -39,8 +39,7 @@ - + diff --git a/distribution/src/test/java/com/predic8/membrane/examples/ConfigSerializationTest.java b/distribution/src/test/java/com/predic8/membrane/examples/ConfigSerializationTest.java index 17f07af29c..4a36f09fc5 100644 --- a/distribution/src/test/java/com/predic8/membrane/examples/ConfigSerializationTest.java +++ b/distribution/src/test/java/com/predic8/membrane/examples/ConfigSerializationTest.java @@ -100,7 +100,7 @@ public void doit(String configFile) throws Exception { assertContainsNot("incomplete serialization", xml); - Router r2 = MCUtil.fromXML(Router.class, xml); + DefaultRouter r2 = MCUtil.fromXML(DefaultRouter.class, xml); String xml2 = MCUtil.toXML(r2); @@ -111,7 +111,7 @@ public void doit(String configFile) throws Exception { } private String readConfigFileAsXML(String configFile) throws IOException { - return MCUtil.toXML(MCUtil.fromXML(Router.class, readFileToString(new File(configFile), UTF_8))); + return MCUtil.toXML(MCUtil.fromXML(DefaultRouter.class, readFileToString(new File(configFile), UTF_8))); } public void prettyPrint(String xml) throws Exception { diff --git a/distribution/src/test/java/com/predic8/membrane/examples/withinternet/env/HelpLinkExistenceTest.java b/distribution/src/test/java/com/predic8/membrane/examples/withinternet/env/HelpLinkExistenceTest.java index ac087953cf..441a9d8a36 100644 --- a/distribution/src/test/java/com/predic8/membrane/examples/withinternet/env/HelpLinkExistenceTest.java +++ b/distribution/src/test/java/com/predic8/membrane/examples/withinternet/env/HelpLinkExistenceTest.java @@ -20,13 +20,12 @@ import java.lang.annotation.Annotation; import java.util.*; -import com.predic8.membrane.core.exchange.*; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import com.predic8.membrane.annot.MCElement; import com.predic8.membrane.core.Constants; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.DefaultRouter; import com.predic8.membrane.core.http.Request; import com.predic8.membrane.core.http.Response; import com.predic8.membrane.core.interceptor.Interceptor; @@ -93,7 +92,7 @@ private Set> getElementClasses() { try { HashSet> currentSet = new HashSet<>(); - try (BufferedReader r = new BufferedReader(new InputStreamReader(requireNonNull(Router.class.getResourceAsStream("/META-INF/membrane.cache"))))) { + try (BufferedReader r = new BufferedReader(new InputStreamReader(requireNonNull(DefaultRouter.class.getResourceAsStream("/META-INF/membrane.cache"))))) { if (!CACHE_FILE_FORMAT_VERSION.equals(r.readLine())) throw new RuntimeException(); Class annotationClass; diff --git a/distribution/src/test/java/com/predic8/membrane/examples/withinternet/test/FileExchangeStoreExampleTest.java b/distribution/src/test/java/com/predic8/membrane/examples/withinternet/test/FileExchangeStoreExampleTest.java index 4729a680e1..1a1b3dc89e 100644 --- a/distribution/src/test/java/com/predic8/membrane/examples/withinternet/test/FileExchangeStoreExampleTest.java +++ b/distribution/src/test/java/com/predic8/membrane/examples/withinternet/test/FileExchangeStoreExampleTest.java @@ -14,11 +14,13 @@ package com.predic8.membrane.examples.withinternet.test; +import com.predic8.membrane.core.*; import com.predic8.membrane.core.exchangestore.FileExchangeStore; import com.predic8.membrane.examples.util.DistributionExtractingTestcase; import com.predic8.membrane.examples.util.Process2; import com.predic8.membrane.test.HttpAssertions; import org.junit.jupiter.api.Test; +import org.slf4j.*; import java.io.File; import java.io.FilenameFilter; @@ -32,6 +34,8 @@ public class FileExchangeStoreExampleTest extends DistributionExtractingTestcase { + private static final Logger log = LoggerFactory.getLogger(FileExchangeStoreExampleTest.class.getName()); + @Override protected String getExampleDirName() { return "extending-membrane/file-exchangestore"; @@ -124,6 +128,7 @@ private void recursiveDelete(File file) { } private boolean containsRecursively(File base, FilenameFilter filter) { + log.info("Checking {} for {}", base, filter); //noinspection ConstantConditions for (File f : base.listFiles()) { if (f.isDirectory()) diff --git a/distribution/src/test/java/com/predic8/membrane/examples/withinternet/test/Loadbalancing4XmlSessionExampleTest.java b/distribution/src/test/java/com/predic8/membrane/examples/withinternet/test/Loadbalancing4XmlSessionExampleTest.java index e71a557b63..f717b1c098 100644 --- a/distribution/src/test/java/com/predic8/membrane/examples/withinternet/test/Loadbalancing4XmlSessionExampleTest.java +++ b/distribution/src/test/java/com/predic8/membrane/examples/withinternet/test/Loadbalancing4XmlSessionExampleTest.java @@ -24,17 +24,21 @@ public class Loadbalancing4XmlSessionExampleTest extends DistributionExtractingTestcase { + private static final String BODY_SESSION_1 = """ + {"id":"SESSION1"}"""; + private static final String BODY_SESSION_2 = """ + {"id":"SESSION2"}"""; + @Override protected String getExampleDirName() { return "loadbalancing/4-session"; } @Test - public void test() throws Exception { + void test() throws Exception { try(Process2 ignored = startServiceProxyScript()) { given().when() - .body(""" - {"id":"SESSION1"}""") + .body(BODY_SESSION_1) .contentType(APPLICATION_JSON) .post("http://localhost:8080") .then() @@ -42,8 +46,7 @@ public void test() throws Exception { .body(containsString("Request count: 1")); given().when() - .body(""" - {"id":"SESSION1"}""") + .body(BODY_SESSION_1) .contentType(APPLICATION_JSON) .post("http://localhost:8080") .then() @@ -51,8 +54,7 @@ public void test() throws Exception { .body(containsString("Request count: 2")); given().when() - .body(""" - {"id":"SESSION1"}""") + .body(BODY_SESSION_1) .contentType(APPLICATION_JSON) .post("http://localhost:8080") .then() @@ -60,8 +62,7 @@ public void test() throws Exception { .body(containsString("Request count: 3")); given().when() - .body(""" - {"id":"SESSION1"}""") + .body(BODY_SESSION_1) .contentType(APPLICATION_JSON) .post("http://localhost:8080") .then() @@ -69,8 +70,7 @@ public void test() throws Exception { .body(containsString("Request count: 4")); given().when() - .body(""" - {"id":"SESSION2"}""") + .body(BODY_SESSION_2) .contentType(APPLICATION_JSON) .post("http://localhost:8080") .then() @@ -78,8 +78,7 @@ public void test() throws Exception { .body(containsString("Request count: 1")); given().when() - .body(""" - {"id":"SESSION2"}""") + .body(BODY_SESSION_2) .contentType(APPLICATION_JSON) .post("http://localhost:8080") .then() @@ -87,8 +86,7 @@ public void test() throws Exception { .body(containsString("Request count: 2")); given().when() - .body(""" - {"id":"SESSION2"}""") + .body(BODY_SESSION_2) .contentType(APPLICATION_JSON) .post("http://localhost:8080") .then() @@ -96,8 +94,7 @@ public void test() throws Exception { .body(containsString("Request count: 3")); given().when() - .body(""" - {"id":"SESSION2"}""") + .body(BODY_SESSION_2) .contentType(APPLICATION_JSON) .post("http://localhost:8080") .then() diff --git a/distribution/src/test/java/com/predic8/membrane/examples/withoutinternet/test/Loadbalancing6HealthMonitorExampleTest.java b/distribution/src/test/java/com/predic8/membrane/examples/withoutinternet/test/Loadbalancing6HealthMonitorExampleTest.java index a9ed971fd9..4891438524 100644 --- a/distribution/src/test/java/com/predic8/membrane/examples/withoutinternet/test/Loadbalancing6HealthMonitorExampleTest.java +++ b/distribution/src/test/java/com/predic8/membrane/examples/withoutinternet/test/Loadbalancing6HealthMonitorExampleTest.java @@ -189,7 +189,7 @@ void https_lbAlternates() throws Exception { void https_adminShowsNodesUp() throws Exception { ensureCertificates(); try (Process2 ignored = builder.parameters(PROXIES_TLS_XML_OPTION).start()) { - // @formatter:off + // @formatter:off String html = given() .relaxedHTTPSValidation() .get(ADMIN_URL_HTTPS).then() diff --git a/distribution/src/test/java/com/predic8/membrane/load/LoadTester.java b/distribution/src/test/java/com/predic8/membrane/load/LoadTester.java index 2d43b19078..e3b049a433 100644 --- a/distribution/src/test/java/com/predic8/membrane/load/LoadTester.java +++ b/distribution/src/test/java/com/predic8/membrane/load/LoadTester.java @@ -48,7 +48,7 @@ public class LoadTester { */ public static final int CONCURRENCY = 200; - Router r = new HttpRouter(); + Router r = new DefaultRouter(); public static void main(String[] args) throws Exception { var instance = new LoadTester(); diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 9ab79ee21b..70732f0b86 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -12,9 +12,19 @@ - Correct YAML example on GitHub README - Rename in apis.yaml +# 7.X + +- JMXExporter: + - Tutorial + - Documentation + - See JmxExporter +- Synchronization of BeanRegistry # 7.1.0 +- reverseDNS + - Now it is in transport + - Maybe move it to configuration - Register JSON Schema for YAML at: https://www.schemastore.org - Grafana Dashboard: Complete Dashboard for Membrane with documentation in examples/monitoring/grafana - Remove GroovyTemplateInterceptor (Not Template Interceptor) @@ -23,6 +33,7 @@ # 7.0.4 - Discuss renaming the WebSocketInterceptor.flow to something else to avoid confusion with flowParser +- do not pass a `Router` reference into all sorts of beans: Access to global functionality should happen only on a very limited basis. # 7.0.1 @@ -41,7 +52,8 @@ ## (Breaking) Interface Changes - +- JMX: Name changes to "io.membrane-api:00=routers, name=" +- Removed GateKeeperClientInterceptor - Removed support for `internal:` syntax in target URLs, leaving `internal://` as the only valid way to call internal APIs. - Remove WADLInterceptor - HttpClient TB (done) diff --git a/war/src/main/java/com/predic8/membrane/servlet/MembraneServletContextListener.java b/war/src/main/java/com/predic8/membrane/servlet/MembraneServletContextListener.java index 155eaaac67..fc91c48750 100644 --- a/war/src/main/java/com/predic8/membrane/servlet/MembraneServletContextListener.java +++ b/war/src/main/java/com/predic8/membrane/servlet/MembraneServletContextListener.java @@ -15,7 +15,7 @@ package com.predic8.membrane.servlet; import com.predic8.membrane.core.Constants; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.DefaultRouter; import com.predic8.membrane.servlet.config.spring.BaseLocationXmlWebApplicationContext; import jakarta.servlet.ServletContextEvent; import jakarta.servlet.ServletContextListener; @@ -36,7 +36,7 @@ public void contextInitialized(ServletContextEvent sce) { log.debug("loading proxies configuration from: " + getProxiesXmlLocation(sce)); appCtx = new BaseLocationXmlWebApplicationContext(); - Router router = RouterUtil.initializeRoutersFromSpringWebContext(appCtx, sce.getServletContext(), getProxiesXmlLocation(sce)); + DefaultRouter router = RouterUtil.initializeRoutersFromSpringWebContext(appCtx, sce.getServletContext(), getProxiesXmlLocation(sce)); if (router != null) throw new RuntimeException("A with a cannot be used with MembraneServletContextListener. Use MembraneServlet instead."); diff --git a/war/src/main/java/com/predic8/membrane/servlet/RouterUtil.java b/war/src/main/java/com/predic8/membrane/servlet/RouterUtil.java index 96daf4b5b5..ec45c58375 100644 --- a/war/src/main/java/com/predic8/membrane/servlet/RouterUtil.java +++ b/war/src/main/java/com/predic8/membrane/servlet/RouterUtil.java @@ -20,18 +20,18 @@ import org.springframework.web.context.support.XmlWebApplicationContext; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.DefaultRouter; import com.predic8.membrane.servlet.embedded.ServletTransport; public class RouterUtil { - public static Router initializeRoutersFromSpringWebContext(XmlWebApplicationContext appCtx, final ServletContext ctx, String configLocation) { + public static DefaultRouter initializeRoutersFromSpringWebContext(XmlWebApplicationContext appCtx, final ServletContext ctx, String configLocation) { appCtx.setServletContext(ctx); appCtx.setConfigLocation(configLocation); appCtx.refresh(); - Collection routers = appCtx.getBeansOfType(Router.class).values(); - Router theOne = null; - for (Router r : routers) { + Collection routers = appCtx.getBeansOfType(DefaultRouter.class).values(); + DefaultRouter theOne = null; + for (DefaultRouter r : routers) { r.getResolverMap().addSchemaResolver(new FileSchemaWebAppResolver(ctx)); if (r.getTransport() instanceof ServletTransport) { if (theOne != null) diff --git a/war/src/main/java/com/predic8/membrane/servlet/embedded/MembraneServlet.java b/war/src/main/java/com/predic8/membrane/servlet/embedded/MembraneServlet.java index 9784f907cd..96724b4bb9 100644 --- a/war/src/main/java/com/predic8/membrane/servlet/embedded/MembraneServlet.java +++ b/war/src/main/java/com/predic8/membrane/servlet/embedded/MembraneServlet.java @@ -14,7 +14,7 @@ package com.predic8.membrane.servlet.embedded; -import com.predic8.membrane.core.Router; +import com.predic8.membrane.core.DefaultRouter; import com.predic8.membrane.servlet.RouterUtil; import com.predic8.membrane.servlet.config.spring.BaseLocationXmlWebApplicationContext; import jakarta.servlet.ServletConfig; @@ -36,7 +36,7 @@ public class MembraneServlet extends HttpServlet { private static final Logger log = LoggerFactory.getLogger(MembraneServlet.class); private XmlWebApplicationContext appCtx; - private Router router; + private DefaultRouter router; @Override public void init(ServletConfig config) throws ServletException {