Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions annot/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,21 @@
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.
--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<artifactId>service-proxy-annot</artifactId>
<name>${project.artifactId}</name>
<packaging>jar</packaging>

<parent>
<groupId>org.membrane-soa</groupId>
<artifactId>service-proxy-parent</artifactId>
<relativePath>../pom.xml</relativePath>
<version>7.0.5</version>
</parent>
<parent>
<groupId>org.membrane-soa</groupId>
<artifactId>service-proxy-parent</artifactId>
<relativePath>../pom.xml</relativePath>
<version>7.0.5</version>
</parent>

<dependencies>
<dependency>
Expand Down Expand Up @@ -87,6 +89,11 @@
<version>3.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,22 @@ public interface BeanRegistry {
Grammar getGrammar();

<T> List<T> getBeans(Class<T> clazz);

/**
* Retrieves a single bean of the specified type.
*
* @param clazz the class of the bean to retrieve
* @param <T> the bean type
* @return Optional containing the bean if exactly one exists, empty otherwise
* @throws RuntimeException if multiple beans of the specified type exist
*/
<T> Optional<T> getBean(Class<T> clazz);

/**
* Registers a bean with the specified name.
*
* @param beanName the name to register the bean under
* @param bean instance to register (must not be null)
*/
void register(String beanName, Object bean);
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,22 @@ public <T> List<T> getBeans(Class<T> clazz) {
.map(clazz::cast)
.toList();
}

public <T> Optional<T> getBean(Class<T> 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);
log.error(msg);
throw new RuntimeException(msg);
}
return beans.size() == 1 ? Optional.of(beans.getFirst()) : Optional.empty();
}

public void register(String beanName, Object bean) {
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,7 @@ public static List<BeanDefinition> parseMembraneResources(@NotNull InputStream r
try (resource) {
return parseToBeanDefinitions(resource, grammar);
} catch (JsonParseException e) {
throw new IOException(
"Invalid YAML: multiple configurations must be separated by '---' "
+ "(at line " + e.getLocation().getLineNr()
+ ", column " + e.getLocation().getColumnNr() + ").",
e
);
throw new IOException("Invalid YAML: multiple configurations must be separated by '---' (at line %d, column %d).".formatted(e.getLocation().getLineNr(), e.getLocation().getColumnNr()), e);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* 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.annot.beanregistry;

import org.junit.jupiter.api.*;
import org.mockito.*;

import java.util.*;

import static org.junit.jupiter.api.Assertions.assertEquals;

class BeanRegistryImplementationTest {

private BeanRegistryImplementation registry;
private BeanRegistryAware aware;

@BeforeEach
void setup() {
aware = Mockito.mock(BeanRegistryAware.class);
registry = new BeanRegistryImplementation(null, aware, null);
}

@Test
void register() {
A a1 = new A("a1");
A a2 = new A("a2");
A a3 = new A("a3");
registry.register("bean1", a1);
registry.register("bean2", a2);
registry.register("bean3", a3);
List<A> as = registry.getBeans(A.class);
assertEquals(3, as.size());
assertEquals(Set.of(a1,a2,a3),new HashSet<>(as));
}

@Test
void getBean() {
A a1 = new A("a1");
registry.register("bean1", a1);
assertEquals(a1, registry.getBean(A.class).orElseThrow());
}

class A {
String value;

public A(String value) {
this.value = value;
}
}
}
7 changes: 1 addition & 6 deletions core/src/main/java/com/predic8/membrane/core/Router.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ public class Router implements Lifecycle, ApplicationContextAware, BeanRegistryA
protected final FlowController flowController;
protected ExchangeStore exchangeStore = new LimitedMemoryExchangeStore();
protected Transport transport;
protected GlobalInterceptor globalInterceptor = new GlobalInterceptor();
protected final ResolverMap resolverMap;
protected final DNSCache dnsCache = new DNSCache();
private final KubernetesWatcher kubernetesWatcher = new KubernetesWatcher(this);
Expand Down Expand Up @@ -497,7 +496,7 @@ public void setBeanName(String s) {
*/
@MCChildElement(order = 2)
public void setGlobalInterceptor(GlobalInterceptor globalInterceptor) {
this.globalInterceptor = globalInterceptor;
registry.register("globalInterceptor", globalInterceptor);
}
Comment thread
predic8 marked this conversation as resolved.

public String getId() {
Expand Down Expand Up @@ -530,10 +529,6 @@ public FlowController getFlowController() {
return flowController;
}

public GlobalInterceptor getGlobalInterceptor() {
return globalInterceptor;
}

public synchronized void setAsynchronousInitialization(boolean asynchronousInitialization) {
this.asynchronousInitialization = asynchronousInitialization;
notifyAll();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ private static Router initRouterByYAML(MembraneCommandLine commandLine, String o
}

private static Router initRouterByYAML(String location) throws Exception {
var router = new HttpRouter();
var router = new Router();
router.setBaseLocation(location);
router.setAsynchronousInitialization(true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* @description The global chain applies plugins to all endpoints, enabling centralized features
* such as global user authentication, logging, and other cross-cutting concerns.
*/
@MCElement(name = "global", excludeFromFlow = true)
@MCElement(name = "global", excludeFromFlow = true, component = false, topLevel = true)
public class GlobalInterceptor extends AbstractFlowWithChildrenInterceptor {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public abstract class Transport {
* SSL and Non-SSL are mixed here, maybe split that in future
*/
protected final Set<IPortChangeListener> menuListeners = new HashSet<>();

private List<Interceptor> interceptors = new Vector<>();

private Router router;
private boolean reverseDNS = true;

Expand Down Expand Up @@ -62,7 +62,7 @@ public void init(Router router) throws Exception {
interceptors.add(getExchangeStoreInterceptor());
interceptors.add(getInterceptor(DispatchingInterceptor.class));
interceptors.add(getInterceptor(ReverseProxyingInterceptor.class));
interceptors.add(router.getGlobalInterceptor());
router.getRegistry().getBean(GlobalInterceptor.class).ifPresent(i -> interceptors.add(i ));
Comment thread
predic8 marked this conversation as resolved.
interceptors.add(getInterceptor(UserFeatureInterceptor.class));
interceptors.add(getInterceptor(InternalRoutingInterceptor.class));
interceptors.add(getInterceptor(HTTPClientInterceptor.class));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,21 +346,16 @@ public List<Object> getBeans() {
return List.of();
}


@Override
public void parseYamls(InputStream yamls, Grammar grammar) throws IOException {
BeanCollector.super.parseYamls(yamls, grammar);
}

@Override
public void handle(ChangeEvent changeEvent, boolean isLast) {

}
public void handle(ChangeEvent changeEvent, boolean isLast) {}

@Override
public void start() {

}
public void start() {}

@Override
public Grammar getGrammar() {
Expand All @@ -371,6 +366,14 @@ public Grammar getGrammar() {
public <T> List<T> getBeans(Class<T> clazz) {
return List.of();
}

@Override
public <T> Optional<T> getBean(Class<T> clazz) {
return Optional.empty();
}

@Override
public void register(String beanName, Object object) {}
}

private static APIProxy parse(String yaml, BeanRegistry reg) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package com.predic8.membrane.core.transport.http;

import com.predic8.membrane.annot.beanregistry.*;
import com.predic8.membrane.core.*;
import com.predic8.membrane.core.exchangestore.*;
import com.predic8.membrane.core.interceptor.GlobalInterceptor;
Expand All @@ -39,14 +40,15 @@ public class HttpTransportTest {
private final GlobalInterceptor globalInterceptor = new GlobalInterceptor();

@BeforeEach
public void before() throws Exception {
void before() throws Exception {
when(resolverMap.getHTTPSchemaResolver()).thenReturn(httpSchemaResolver);
when(router.getResolverMap()).thenReturn(resolverMap);
when(router.getRuleManager()).thenReturn(ruleManager);
when(router.getExchangeStore()).thenReturn(exchangeStore);
when(router.getGlobalInterceptor()).thenReturn(globalInterceptor);
when(router.getHttpClientFactory()).thenReturn(new HttpClientFactory(null));
when(router.getStatistics()).thenReturn(statistics);
BeanRegistryImplementation value = new BeanRegistryImplementation(null, router, null); // Do not inline! Otherwise mocking is not possible!
when(router.getRegistry()).thenReturn(value);

transport = new HttpTransport();
transport.init(router);
Expand Down
Loading