From c272b06547a5786d12a75a9d80cf914e88f204e4 Mon Sep 17 00:00:00 2001 From: Tim Hurman Date: Tue, 10 Dec 2024 12:36:17 +0900 Subject: [PATCH 1/2] Converted the KieServerRegistry lookup to utilise the ServiceLoader --- .../controller/api/KieServerController.java | 6 +- .../WebSocketKieServerControllerImpl.java | 21 ++++--- .../services/api/KieServerRegistryAware.java | 14 +++++ .../server/services/impl/KieServerImpl.java | 63 +++++++++++++------ .../controller/DefaultRestControllerImpl.java | 29 +++++++-- .../policy/KeepLatestContainerOnlyPolicy.java | 3 +- ....server.controller.api.KieServerController | 1 + .../impl/AbstractKieServerImplTest.java | 12 ++-- .../KieControllerCrashIntegrationTest.java | 5 +- ...ieControllerValidationIntegrationTest.java | 6 +- 10 files changed, 111 insertions(+), 49 deletions(-) create mode 100644 kie-server-parent/kie-server-services/kie-server-services-common/src/main/resources/META-INF/services/org.kie.server.controller.api.KieServerController diff --git a/kie-server-parent/kie-server-controller/kie-server-controller-api/src/main/java/org/kie/server/controller/api/KieServerController.java b/kie-server-parent/kie-server-controller/kie-server-controller-api/src/main/java/org/kie/server/controller/api/KieServerController.java index abdb4dc351..5e5cbdbfb7 100644 --- a/kie-server-parent/kie-server-controller/kie-server-controller-api/src/main/java/org/kie/server/controller/api/KieServerController.java +++ b/kie-server-parent/kie-server-controller/kie-server-controller-api/src/main/java/org/kie/server/controller/api/KieServerController.java @@ -27,7 +27,7 @@ public interface KieServerController { /** - * Entry point for for KieServer to connect(and register if done for the first time). At the same time, when given KieServerInstance + * Entry point for KieServer to connect(and register if done for the first time). At the same time, when given KieServerInstance * has been already added a KieServerSetup with data will be returned. Otherwise empty (or default) KieServerSetup will be provided. * @param serverInfo representation of minimal set of information about KieServer * @return KieServer configuration @@ -35,8 +35,8 @@ public interface KieServerController { KieServerSetup connect(KieServerInfo serverInfo); /** - * Entry point for for KieServer to update its status information. - * @param serverInfo representation of minimal set of information about KieServer + * Entry point for KieServer to update its status information. + * @param containerSpec representation of minimal set of information about KieServer */ default KieServerSetup update(KieServerStateInfo containerSpec) { diff --git a/kie-server-parent/kie-server-controller/kie-server-controller-websocket-client/src/main/java/org/kie/server/controller/websocket/client/WebSocketKieServerControllerImpl.java b/kie-server-parent/kie-server-controller/kie-server-controller-websocket-client/src/main/java/org/kie/server/controller/websocket/client/WebSocketKieServerControllerImpl.java index b919848d4b..211e98b9b4 100644 --- a/kie-server-parent/kie-server-controller/kie-server-controller-websocket-client/src/main/java/org/kie/server/controller/websocket/client/WebSocketKieServerControllerImpl.java +++ b/kie-server-parent/kie-server-controller/kie-server-controller-websocket-client/src/main/java/org/kie/server/controller/websocket/client/WebSocketKieServerControllerImpl.java @@ -51,10 +51,9 @@ public class WebSocketKieServerControllerImpl implements KieServerController, Ki private KieServerRegistry context; private final KieServerMessageHandlerWebSocketClient client; private final Marshaller marshaller; - + private final DefaultRestControllerImpl restController = new DefaultRestControllerImpl(); + private KieServerInfo serverInfo; - - private DefaultRestControllerImpl restController; public WebSocketKieServerControllerImpl() { this.marshaller = MarshallerFactory.getMarshaller(MarshallingFormat.JSON, this.getClass().getClassLoader()); @@ -69,6 +68,16 @@ public WebSocketKieServerControllerImpl() { }); } + @Override + public Integer getPriority() { + return 100; + } + + @Override + public boolean supports(String url) { + return url != null && url.startsWith("ws"); + } + @Override public KieServerSetup connect(KieServerInfo serverInfo) { KieServerState currentState = context.getStateRepository().load(KieServerEnvironment.getServerId()); @@ -170,15 +179,11 @@ protected String serialize(Object object) { @Override public void setRegistry(KieServerRegistry registry) { this.context = registry; - - this.restController = new DefaultRestControllerImpl(this.context); + this.restController.setRegistry(registry); } @Override public KieServerRegistry getRegistry() { return this.context; } - - - } diff --git a/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/api/KieServerRegistryAware.java b/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/api/KieServerRegistryAware.java index deb4cf4cb9..f4655fc789 100644 --- a/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/api/KieServerRegistryAware.java +++ b/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/api/KieServerRegistryAware.java @@ -6,4 +6,18 @@ public interface KieServerRegistryAware { void setRegistry(KieServerRegistry registry); KieServerRegistry getRegistry(); + + + /** + * Determine the priority of the loaded KieServerController loaded through the ServiceLoader. + * @return A priority for the KieServerController. 0 being the highest, Integer.MAX_VALUE being the lowest. If null, then the lowest priority is assumed. + */ + Integer getPriority(); + + /** + * Determine if a KieServerController supports a specific connection point. + * @param url The URL to check. + * @return true if the KieServerController supports the endpoint, false otherwise. + */ + boolean supports(String url); } diff --git a/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/impl/KieServerImpl.java b/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/impl/KieServerImpl.java index 44fb259ccf..25be548961 100644 --- a/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/impl/KieServerImpl.java +++ b/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/impl/KieServerImpl.java @@ -16,19 +16,7 @@ package org.kie.server.services.impl; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Optional; -import java.util.ServiceLoader; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicBoolean; @@ -1138,15 +1126,48 @@ protected Map getReleaseUpdateParameters(KieModuleMetaData metaD return parameters; } + /** + * Get the first KieServerController which is supported for the all controller URLs. This assumes that all + * controllers are of the same type. For example, it is not possible to have one REST and one WebSocket controller. + * + * @return A KieServerController or null if one is not available. + */ protected KieServerController getController() { - KieServerController controller = new DefaultRestControllerImpl(context); + KieServerState currentState = context.getStateRepository().load(KieServerEnvironment.getServerId()); + Set controllers = currentState.getControllers(); + + if (controllers.isEmpty()) { + logger.debug("No controllers registered"); + return null; + } + + KieServerController controller = null; + int controllerPriority = Integer.MAX_VALUE; try { - Iterator it = kieControllers.iterator(); - if (it != null && it.hasNext()) { - controller = it.next(); + for (KieServerController curr: kieControllers) { + // Only want remote capable + if (!(curr instanceof KieServerRegistryAware)) { + continue; + } - if (controller instanceof KieServerRegistryAware) { - ((KieServerRegistryAware) controller).setRegistry(context); + KieServerRegistryAware currRemote = (KieServerRegistryAware)curr; + currRemote.setRegistry(context); + + boolean supportsAll = controllers.stream().allMatch(currRemote::supports); + if (!supportsAll) { + logger.debug("KieServerController {} does not support all controllers", curr.getClass().getName()); + continue; + } + + // See if this is a better fit. + Integer currPriority = currRemote.getPriority(); + if (null == currPriority) { + currPriority = Integer.MAX_VALUE; + } + + if (currPriority >= 0 && currPriority < controllerPriority) { + controllerPriority = currPriority; + controller = curr; } } } catch (Exception e) { @@ -1161,7 +1182,9 @@ protected void notifyStatusToControllers() { } protected KieServerController getDefaultController() { - return new DefaultRestControllerImpl(context); + DefaultRestControllerImpl controller = new DefaultRestControllerImpl(); + controller.setRegistry(context); + return controller; } protected ContainerManager getContainerManager() { diff --git a/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/impl/controller/DefaultRestControllerImpl.java b/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/impl/controller/DefaultRestControllerImpl.java index 764814e72b..1815f86a23 100644 --- a/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/impl/controller/DefaultRestControllerImpl.java +++ b/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/impl/controller/DefaultRestControllerImpl.java @@ -36,22 +36,41 @@ import org.kie.server.services.api.KieControllerNotConnectedException; import org.kie.server.services.api.KieControllerNotDefinedException; import org.kie.server.services.api.KieServerRegistry; +import org.kie.server.services.api.KieServerRegistryAware; import org.kie.server.services.impl.storage.KieServerState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static org.kie.server.common.KeyStoreHelperUtil.loadControllerPassword; -public class DefaultRestControllerImpl implements KieServerController { +public class DefaultRestControllerImpl implements KieServerController, KieServerRegistryAware { private static final Logger logger = LoggerFactory.getLogger(DefaultRestControllerImpl.class); - private final KieServerRegistry context; + private KieServerRegistry context; - public DefaultRestControllerImpl(KieServerRegistry context) { - this.context = context; + public DefaultRestControllerImpl() { } + @Override + public void setRegistry(KieServerRegistry registry) { + this.context = registry; + } + + @Override + public KieServerRegistry getRegistry() { + return context; + } + + @Override + public Integer getPriority() { + return 100; + } + + @Override + public boolean supports(String url) { + return url != null && url.startsWith("http"); + } protected T makeHttpPutRequestAndCreateCustomResponse(String uri, String body, Class resultType, String user, String password, String token) { logger.debug("About to send PUT request to '{}' with payload '{}' by thread {}", uri, body, Thread.currentThread().getId()); @@ -323,6 +342,4 @@ public void stopContainer(String containerId) { } } } - - } diff --git a/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/impl/policy/KeepLatestContainerOnlyPolicy.java b/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/impl/policy/KeepLatestContainerOnlyPolicy.java index 3b620b305f..536ba6b3ce 100644 --- a/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/impl/policy/KeepLatestContainerOnlyPolicy.java +++ b/kie-server-parent/kie-server-services/kie-server-services-common/src/main/java/org/kie/server/services/impl/policy/KeepLatestContainerOnlyPolicy.java @@ -88,7 +88,8 @@ public void stop() { @Override public void apply(KieServerRegistry kieServerRegistry, KieServer kieServer) { - DefaultRestControllerImpl controller = new DefaultRestControllerImpl(kieServerRegistry); + DefaultRestControllerImpl controller = new DefaultRestControllerImpl(); + controller.setRegistry(kieServerRegistry); List containerAliases = kieServerRegistry.getContainerAliases(); if (containerAliases.isEmpty()) { diff --git a/kie-server-parent/kie-server-services/kie-server-services-common/src/main/resources/META-INF/services/org.kie.server.controller.api.KieServerController b/kie-server-parent/kie-server-services/kie-server-services-common/src/main/resources/META-INF/services/org.kie.server.controller.api.KieServerController new file mode 100644 index 0000000000..b85036ddaa --- /dev/null +++ b/kie-server-parent/kie-server-services/kie-server-services-common/src/main/resources/META-INF/services/org.kie.server.controller.api.KieServerController @@ -0,0 +1 @@ +org.kie.server.services.impl.controller.DefaultRestControllerImpl \ No newline at end of file diff --git a/kie-server-parent/kie-server-services/kie-server-services-common/src/test/java/org/kie/server/services/impl/AbstractKieServerImplTest.java b/kie-server-parent/kie-server-services/kie-server-services-common/src/test/java/org/kie/server/services/impl/AbstractKieServerImplTest.java index 91867b4d3c..417550b05d 100644 --- a/kie-server-parent/kie-server-services/kie-server-services-common/src/test/java/org/kie/server/services/impl/AbstractKieServerImplTest.java +++ b/kie-server-parent/kie-server-services/kie-server-services-common/src/test/java/org/kie/server/services/impl/AbstractKieServerImplTest.java @@ -62,11 +62,7 @@ import org.kie.server.api.model.Severity; import org.kie.server.controller.api.KieServerController; import org.kie.server.controller.api.model.KieServerSetup; -import org.kie.server.services.api.KieContainerInstance; -import org.kie.server.services.api.KieControllerNotConnectedException; -import org.kie.server.services.api.KieServerExtension; -import org.kie.server.services.api.KieServerRegistry; -import org.kie.server.services.api.SupportedTransports; +import org.kie.server.services.api.*; import org.kie.server.services.impl.controller.DefaultRestControllerImpl; import org.kie.server.services.impl.storage.KieServerState; import org.kie.server.services.impl.storage.KieServerStateRepository; @@ -710,9 +706,10 @@ public void markAsReady() { @Override public KieServerController getController() { - return new DefaultRestControllerImpl(getServerRegistry()) { + KieServerController controller = new DefaultRestControllerImpl() { @Override public KieServerSetup connect(KieServerInfo serverInfo) { + setRegistry(getServerRegistry()); try { if (latch.await(10, TimeUnit.MILLISECONDS)) { return new KieServerSetup(); @@ -722,8 +719,9 @@ public KieServerSetup connect(KieServerInfo serverInfo) { throw new KieControllerNotConnectedException("Unable to connect to any controller"); } } - }; + ((KieServerRegistryAware)controller).setRegistry(getServerRegistry()); + return controller; } }; diff --git a/kie-server-parent/kie-server-tests/kie-server-integ-tests-controller/src/test/java/org/kie/server/integrationtests/controller/KieControllerCrashIntegrationTest.java b/kie-server-parent/kie-server-tests/kie-server-integ-tests-controller/src/test/java/org/kie/server/integrationtests/controller/KieControllerCrashIntegrationTest.java index d556641b13..55e8d7b616 100644 --- a/kie-server-parent/kie-server-tests/kie-server-integ-tests-controller/src/test/java/org/kie/server/integrationtests/controller/KieControllerCrashIntegrationTest.java +++ b/kie-server-parent/kie-server-tests/kie-server-integ-tests-controller/src/test/java/org/kie/server/integrationtests/controller/KieControllerCrashIntegrationTest.java @@ -96,7 +96,7 @@ public void onContainerSpecUpdated(ContainerSpecUpdated containerSpecUpdated) {} if (TestConfig.isLocalServer()) { controllerClient = KieServerControllerClientFactory.newWebSocketClient(TestConfig.getControllerWebSocketManagementUrl(), (String) null, - (String) null, + (String) null, eventHandler); } else { controllerClient = KieServerControllerClientFactory.newWebSocketClient(TestConfig.getControllerWebSocketManagementUrl(), @@ -162,7 +162,8 @@ public KieServerState load(String serverId) { }; registry.registerStateRepository(dummyKieServerStateRepository); - KieServerController controller = new DefaultRestControllerImpl(registry); + DefaultRestControllerImpl controller = new DefaultRestControllerImpl(); + controller.setRegistry(registry); controller.connect(kieServerInfo); // Check that kie server is registered. serverUp.await(5, TimeUnit.SECONDS); diff --git a/kie-server-parent/kie-server-tests/kie-server-integ-tests-controller/src/test/java/org/kie/server/integrationtests/controller/KieControllerValidationIntegrationTest.java b/kie-server-parent/kie-server-tests/kie-server-integ-tests-controller/src/test/java/org/kie/server/integrationtests/controller/KieControllerValidationIntegrationTest.java index 0eec4f3498..a9d6e7c979 100644 --- a/kie-server-parent/kie-server-tests/kie-server-integ-tests-controller/src/test/java/org/kie/server/integrationtests/controller/KieControllerValidationIntegrationTest.java +++ b/kie-server-parent/kie-server-tests/kie-server-integ-tests-controller/src/test/java/org/kie/server/integrationtests/controller/KieControllerValidationIntegrationTest.java @@ -110,7 +110,8 @@ public void testBadRegistered() throws Exception { kieServerInfo.setMode(KieServerMode.PRODUCTION); kieServerInfo.setName(SERVER_NAME); - KieServerController controller = new DefaultRestControllerImpl(registry); + DefaultRestControllerImpl controller = new DefaultRestControllerImpl(); + controller.setRegistry(registry); assertThatThrownBy(() -> controller.connect(kieServerInfo)).isInstanceOf(KieControllerNotConnectedException.class); // Check that kie server is not registered. @@ -151,7 +152,8 @@ public void testGoodRegistered() throws Exception { KieServerRegistry registry = new KieServerRegistryImpl(); registry.registerStateRepository(dummyKieServerStateRepository); - KieServerController controller = new DefaultRestControllerImpl(registry); + DefaultRestControllerImpl controller = new DefaultRestControllerImpl(); + controller.setRegistry(registry); KieServerSetup setup = controller.connect(kieServerInfo); Assert.assertTrue(setup.hasNoErrors()); From 339a518577c0dfd7d7bc3d12d9be14fb8119199b Mon Sep 17 00:00:00 2001 From: Tim Hurman Date: Thu, 12 Dec 2024 23:03:04 +0900 Subject: [PATCH 2/2] Added the ability to configure userproperties on the websocket through a subclass --- .../client/WebSocketKieServerControllerImpl.java | 7 +++++++ .../websocket/common/WebSocketClientImpl.java | 1 + .../config/WebSocketClientConfiguration.java | 8 ++++++++ .../config/WebSocketClientConfigurationImpl.java | 14 ++++++++++++++ 4 files changed, 30 insertions(+) diff --git a/kie-server-parent/kie-server-controller/kie-server-controller-websocket-client/src/main/java/org/kie/server/controller/websocket/client/WebSocketKieServerControllerImpl.java b/kie-server-parent/kie-server-controller/kie-server-controller-websocket-client/src/main/java/org/kie/server/controller/websocket/client/WebSocketKieServerControllerImpl.java index 211e98b9b4..dc7f742e74 100644 --- a/kie-server-parent/kie-server-controller/kie-server-controller-websocket-client/src/main/java/org/kie/server/controller/websocket/client/WebSocketKieServerControllerImpl.java +++ b/kie-server-parent/kie-server-controller/kie-server-controller-websocket-client/src/main/java/org/kie/server/controller/websocket/client/WebSocketKieServerControllerImpl.java @@ -16,6 +16,8 @@ package org.kie.server.controller.websocket.client; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -102,6 +104,7 @@ public KieServerSetup connect(KieServerInfo serverInfo) { "kieserver")) .password(KeyStoreHelperUtil.loadControllerPassword(config)) .token(config.getConfigItemValue(KieServerConstants.CFG_KIE_CONTROLLER_TOKEN)) + .userProperties(getUserProperties()) .build()); CountDownLatch waitLatch = new CountDownLatch(1); @@ -186,4 +189,8 @@ public void setRegistry(KieServerRegistry registry) { public KieServerRegistry getRegistry() { return this.context; } + + protected Map getUserProperties() { + return new HashMap<>(); + } } diff --git a/kie-server-parent/kie-server-controller/kie-server-controller-websocket-common/src/main/java/org/kie/server/controller/websocket/common/WebSocketClientImpl.java b/kie-server-parent/kie-server-controller/kie-server-controller-websocket-common/src/main/java/org/kie/server/controller/websocket/common/WebSocketClientImpl.java index 757622d8e4..e96e2998c2 100644 --- a/kie-server-parent/kie-server-controller/kie-server-controller-websocket-common/src/main/java/org/kie/server/controller/websocket/common/WebSocketClientImpl.java +++ b/kie-server-parent/kie-server-controller/kie-server-controller-websocket-common/src/main/java/org/kie/server/controller/websocket/common/WebSocketClientImpl.java @@ -113,6 +113,7 @@ public void init(final WebSocketClientConfiguration clientConfig) { .encoders(clientConfig.getEncoders()) .decoders(clientConfig.getDecoders()) .build(); + this.config.getUserProperties().putAll(clientConfig.getUserProperties()); this.endpoint = URI.create(clientConfig.getControllerUrl()); session = container.connectToServer(this, this.config, this.endpoint); LOGGER.info("New Web Socket Session with id: {}, started", session.getId()); diff --git a/kie-server-parent/kie-server-controller/kie-server-controller-websocket-common/src/main/java/org/kie/server/controller/websocket/common/config/WebSocketClientConfiguration.java b/kie-server-parent/kie-server-controller/kie-server-controller-websocket-common/src/main/java/org/kie/server/controller/websocket/common/config/WebSocketClientConfiguration.java index a08f2cc21c..da41eeee6c 100644 --- a/kie-server-parent/kie-server-controller/kie-server-controller-websocket-common/src/main/java/org/kie/server/controller/websocket/common/config/WebSocketClientConfiguration.java +++ b/kie-server-parent/kie-server-controller/kie-server-controller-websocket-common/src/main/java/org/kie/server/controller/websocket/common/config/WebSocketClientConfiguration.java @@ -18,6 +18,7 @@ import java.util.Arrays; import java.util.List; +import java.util.Map; import javax.websocket.Decoder; import javax.websocket.Encoder; @@ -43,6 +44,8 @@ static Builder builder() { List> getDecoders(); + Map getUserProperties(); + class Builder { private WebSocketClientConfigurationImpl config = new WebSocketClientConfigurationImpl(); @@ -87,6 +90,11 @@ public Builder decoders(final Class... decoders) { return this; } + public Builder userProperties(final Map userProperties) { + config.setUserProperties(userProperties); + return this; + } + public WebSocketClientConfiguration build() { return config; } diff --git a/kie-server-parent/kie-server-controller/kie-server-controller-websocket-common/src/main/java/org/kie/server/controller/websocket/common/config/WebSocketClientConfigurationImpl.java b/kie-server-parent/kie-server-controller/kie-server-controller-websocket-common/src/main/java/org/kie/server/controller/websocket/common/config/WebSocketClientConfigurationImpl.java index f0f9053290..194e695ae9 100644 --- a/kie-server-parent/kie-server-controller/kie-server-controller-websocket-common/src/main/java/org/kie/server/controller/websocket/common/config/WebSocketClientConfigurationImpl.java +++ b/kie-server-parent/kie-server-controller/kie-server-controller-websocket-common/src/main/java/org/kie/server/controller/websocket/common/config/WebSocketClientConfigurationImpl.java @@ -16,7 +16,9 @@ package org.kie.server.controller.websocket.common.config; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.websocket.Decoder; import javax.websocket.Encoder; @@ -38,6 +40,8 @@ public class WebSocketClientConfigurationImpl implements WebSocketClientConfigur private List> decoders; + private Map userProperties; + protected WebSocketClientConfigurationImpl() { } @@ -113,6 +117,15 @@ public void setDecoders(List> decoders) { this.decoders = decoders; } + @Override + public Map getUserProperties() { + return userProperties; + } + + public void setUserProperties(Map userProperties) { + this.userProperties = userProperties; + } + @Override public String toString() { return "WebSocketClientConfigurationImpl{" + @@ -124,6 +137,7 @@ public String toString() { ", asyncSendTimeout=" + asyncSendTimeout + ", encoders=" + encoders + ", decoders=" + decoders + + ", userProperties=" + userProperties + '}'; } }