This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new a8c52fe  Revert "CAMEL-14344 camel-milo - Upgrade to newer milo 
version (#3539)" (#3545)
a8c52fe is described below

commit a8c52fec223eca7152c12bd54a071fc9838d69ec
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Wed Feb 5 05:06:03 2020 +0100

    Revert "CAMEL-14344 camel-milo - Upgrade to newer milo version (#3539)" 
(#3545)
    
    This reverts commit 13fc9143ef6dfee9d8e1d297fd305c2a644594d4.
---
 components/camel-milo/pom.xml                      |   6 -
 .../src/main/docs/milo-client-component.adoc       |   8 +-
 .../src/main/docs/milo-server-component.adoc       |   8 +-
 .../milo/client/MiloClientConfiguration.java       |   4 +-
 .../component/milo/client/MiloClientConsumer.java  |   1 +
 .../milo/client/internal/SubscriptionManager.java  |  22 +-
 .../component/milo/server/MiloServerComponent.java | 297 +++++++--------------
 .../component/milo/server/internal/CallMethod.java |  73 -----
 .../milo/server/internal/CamelNamespace.java       | 163 ++++++++---
 .../milo/server/internal/CamelServerItem.java      |   7 +-
 .../component/milo/AbstractMiloServerTest.java     |  27 +-
 .../milo/MonitorItemMultiConnectionsCertTest.java  |  12 +-
 .../milo/MonitorItemMultiConnectionsTest.java      |   6 +-
 .../camel/component/milo/MonitorItemTest.java      |   6 +-
 .../camel/component/milo/WriteClientTest.java      |   4 +-
 .../camel/component/milo/call/CallClientTest.java  | 135 +++-------
 .../apache/camel/component/milo/call/MockCall.java |  71 +++++
 .../camel/component/milo/call/MockCallMethod.java  |  77 ------
 .../component/milo/call/MockCamelNamespace.java    | 141 ----------
 .../camel/component/milo/call/MockNamespace.java   | 176 ++++++++++++
 .../server/ServerSetCertificateManagerTest.java    |   2 +-
 .../camel-milo/src/test/resources/ca/cacert.pem    |  32 ---
 .../camel-milo/src/test/resources/cert/Makefile    |  16 ++
 .../camel-milo/src/test/resources/cert/cert.ini    |  13 +
 .../camel-milo/src/test/resources/cert/cert.p12    | Bin 0 -> 2461 bytes
 .../src/test/resources/cert/certificate.crt        |  20 ++
 .../src/test/resources/cert/certificate.der        | Bin 0 -> 856 bytes
 .../src/test/resources/cert/privateKey.key         |  28 ++
 components/camel-milo/src/test/resources/keystore  | Bin 3990 -> 0 bytes
 .../camel-milo/src/test/resources/openssl-ca.cnf   |  80 ------
 .../src/test/resources/openssl-server.cnf          |  39 ---
 components/camel-milo/src/test/resources/run.sh    |  21 --
 .../modules/ROOT/pages/milo-client-component.adoc  |   9 +-
 .../modules/ROOT/pages/milo-server-component.adoc  |   6 +-
 .../modules/ROOT/pages/camel-3x-upgrade-guide.adoc |  21 --
 parent/pom.xml                                     |   5 +-
 .../karaf/features/src/main/resources/features.xml |  23 +-
 .../apache/camel/itest/karaf/CamelMiloTest.java    |  28 --
 38 files changed, 636 insertions(+), 951 deletions(-)

diff --git a/components/camel-milo/pom.xml b/components/camel-milo/pom.xml
index 3149be6..807ea5f 100644
--- a/components/camel-milo/pom.xml
+++ b/components/camel-milo/pom.xml
@@ -55,12 +55,6 @@
             <version>${milo-version}</version>
         </dependency>
 
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-            <version>${milo-guava-version}</version>
-        </dependency>
-
         <!-- testing -->
         <dependency>
             <groupId>org.apache.camel</groupId>
diff --git a/components/camel-milo/src/main/docs/milo-client-component.adoc 
b/components/camel-milo/src/main/docs/milo-client-component.adoc
index d30640b..705750a 100644
--- a/components/camel-milo/src/main/docs/milo-client-component.adoc
+++ b/components/camel-milo/src/main/docs/milo-client-component.adoc
@@ -10,8 +10,6 @@
 The Milo Client component provides access to OPC UA servers using the
 http://eclipse.org/milo[Eclipse Milo™] implementation.
 
-*Java 9+*: This component requires Java 9+ at runtime.
-
 Maven users will need to add the following dependency to their `pom.xml`
 for this component:
 
@@ -54,13 +52,13 @@ The URI syntax of the endpoint is:
 
 [source]
 ------------------------
-milo-client:opc.tcp://[user:password@]host:port/path/to/service?node=RAW(nsu=urn:foo:bar;s=item-1)
+milo-client:tcp://[user:password@]host:port/path/to/service?node=RAW(nsu=urn:foo:bar;s=item-1)
 ------------------------
 
 If the server does not use a path, then it is possible to simply omit it:
 
 ------------------------
-milo-client:opc.tcp://[user:password@]host:port?node=RAW(nsu=urn:foo:bar;s=item-1)
+milo-client:tcp://[user:password@]host:port?node=RAW(nsu=urn:foo:bar;s=item-1)
 ------------------------
 
 If no user credentials are provided the client will switch to anonymous mode.
@@ -241,7 +239,7 @@ As the values generated by the syntax cannot be 
transparently encoded into a URI
 However Camel allows to wrap the actual value inside `RAW(…)`, which makes 
escaping unnecessary. For example:
 
 ------------------------
-milo-client:opc.tcp://user:password@localhost:12345?node=RAW(nsu=http://foo.bar;s=foo/bar)
+milo-client:tcp://user:password@localhost:12345?node=RAW(nsu=http://foo.bar;s=foo/bar)
 ------------------------
 
 === Method ID
diff --git a/components/camel-milo/src/main/docs/milo-server-component.adoc 
b/components/camel-milo/src/main/docs/milo-server-component.adoc
index bf62602..d70a8ae 100644
--- a/components/camel-milo/src/main/docs/milo-server-component.adoc
+++ b/components/camel-milo/src/main/docs/milo-server-component.adoc
@@ -10,7 +10,7 @@
 The Milo Server component provides an OPC UA server using the
 http://eclipse.org/milo[Eclipse Milo™] implementation.
 
-*Java 9+*: This component requires Java 9+ at runtime.
+*Java 8*: This component requires Java 8 at runtime. 
 
 Maven users will need to add the following dependency to their `pom.xml`
 for this component:
@@ -30,7 +30,7 @@ Value write requests from OPC UA Client will trigger messages 
which are sent int
 
 
 // component options: START
-The OPC UA Server component supports 20 options, which are listed below.
+The OPC UA Server component supports 22 options, which are listed below.
 
 
 
@@ -39,10 +39,12 @@ The OPC UA Server component supports 20 options, which are 
listed below.
 | Name | Description | Default | Type
 | *namespaceUri* (common) | The URI of the namespace, defaults to 
urn:org:apache:camel |  | String
 | *applicationName* (common) | The application name |  | String
-| *path* (common) | The path to be appended to the end of the endpoint url. 
(doesn't need to start with '/') |  | String
 | *applicationUri* (common) | The application URI |  | String
 | *productUri* (common) | The product URI |  | String
 | *bindPort* (common) | The TCP port the server binds to |  | int
+| *strictEndpointUrlsEnabled* (common) | Set whether strict endpoint URLs are 
enforced | false | boolean
+| *serverName* (common) | Server name |  | String
+| *hostname* (common) | Server hostname |  | String
 | *securityPolicies* (common) | Security policies |  | Set
 | *securityPoliciesById* (common) | Security policies by URI or name |  | 
Collection
 | *userAuthenticationCredentials* (common) | Set user password combinations in 
the form of user1:pwd1,user2:pwd2 Usernames and passwords will be URL decoded | 
 | String
diff --git 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientConfiguration.java
 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientConfiguration.java
index 687a88a..a532657 100644
--- 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientConfiguration.java
+++ 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientConfiguration.java
@@ -353,12 +353,12 @@ public class MiloClientConfiguration implements Cloneable 
{
 
             String adding = null;
             try {
-                adding = SecurityPolicy.fromUri(policy).getUri();
+                adding = SecurityPolicy.fromUri(policy).getSecurityPolicyUri();
             } catch (Exception e) {
             }
             if (adding == null) {
                 try {
-                    adding = SecurityPolicy.valueOf(policy).getUri();
+                    adding = 
SecurityPolicy.valueOf(policy).getSecurityPolicyUri();
                 } catch (Exception e) {
                 }
             }
diff --git 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientConsumer.java
 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientConsumer.java
index 03023da..515fa4b 100644
--- 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientConsumer.java
+++ 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientConsumer.java
@@ -28,6 +28,7 @@ import 
org.eclipse.milo.opcua.stack.core.types.builtin.ExpandedNodeId;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
 import static java.util.Objects.requireNonNull;
 
 public class MiloClientConsumer extends DefaultConsumer {
diff --git 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/internal/SubscriptionManager.java
 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/internal/SubscriptionManager.java
index 786854f..0a13dbd 100644
--- 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/internal/SubscriptionManager.java
+++ 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/internal/SubscriptionManager.java
@@ -45,7 +45,7 @@ import 
org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider;
 import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem;
 import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
 import 
org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscriptionManager.SubscriptionListener;
-import org.eclipse.milo.opcua.stack.client.DiscoveryClient;
+import org.eclipse.milo.opcua.stack.client.UaTcpStackClient;
 import org.eclipse.milo.opcua.stack.core.AttributeId;
 import org.eclipse.milo.opcua.stack.core.Identifiers;
 import org.eclipse.milo.opcua.stack.core.StatusCodes;
@@ -427,18 +427,10 @@ public class SubscriptionManager {
 
         // eval enpoint
 
-        String discoveryUri = getEndpointDiscoveryUri();
-
-        final URI uri = URI.create(getEndpointDiscoveryUri());
-
-        //milo library doesn't allow user info as a part of the uri, it has to 
be removed before sending to milo
-        final String user = uri.getUserInfo();
-        if (user != null && !user.isEmpty()) {
-            discoveryUri = discoveryUri.replaceFirst(user + "@", "");
-        }
+        final String discoveryUri = getEndpointDiscoveryUri();
         LOG.debug("Discovering endpoints from: {}", discoveryUri);
 
-        final EndpointDescription endpoint = 
DiscoveryClient.getEndpoints(discoveryUri).thenApply(endpoints -> {
+        final EndpointDescription endpoint = 
UaTcpStackClient.getEndpoints(discoveryUri).thenApply(endpoints -> {
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Found enpoints:");
                 for (final EndpointDescription ep : endpoints) {
@@ -455,9 +447,13 @@ public class SubscriptionManager {
 
         LOG.debug("Selected endpoint: {}", endpoint);
 
+        final URI uri = URI.create(getEndpointDiscoveryUri());
+
         // set identity providers
+
         final List<IdentityProvider> providers = new LinkedList<>();
 
+        final String user = uri.getUserInfo();
         if (user != null && !user.isEmpty()) {
             final String[] creds = user.split(":", 2);
             if (creds != null && creds.length == 2) {
@@ -474,7 +470,7 @@ public class SubscriptionManager {
 
         // create client
 
-        final OpcUaClient client = OpcUaClient.create(cfg.build());
+        final OpcUaClient client = new OpcUaClient(cfg.build());
         client.connect().get();
 
         try {
@@ -534,7 +530,7 @@ public class SubscriptionManager {
         }
     }
 
-    private EndpointDescription findEndpoint(final List<EndpointDescription> 
endpoints) throws URISyntaxException {
+    private EndpointDescription findEndpoint(final EndpointDescription[] 
endpoints) throws URISyntaxException {
 
         final Predicate<String> allowed;
         final Set<String> uris = 
this.configuration.getAllowedSecurityPolicies();
diff --git 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/MiloServerComponent.java
 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/MiloServerComponent.java
index 3e8ce5a..ccbbebf 100644
--- 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/MiloServerComponent.java
+++ 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/MiloServerComponent.java
@@ -23,12 +23,12 @@ import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.security.KeyPair;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
-import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -47,28 +47,23 @@ import 
org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfigBuilder;
 import org.eclipse.milo.opcua.sdk.server.identity.AnonymousIdentityValidator;
 import org.eclipse.milo.opcua.sdk.server.identity.IdentityValidator;
 import org.eclipse.milo.opcua.sdk.server.identity.UsernameIdentityValidator;
-import org.eclipse.milo.opcua.sdk.server.util.HostnameUtil;
 import org.eclipse.milo.opcua.stack.core.StatusCodes;
 import org.eclipse.milo.opcua.stack.core.UaException;
-import org.eclipse.milo.opcua.stack.core.security.CertificateManager;
-import org.eclipse.milo.opcua.stack.core.security.CertificateValidator;
-import org.eclipse.milo.opcua.stack.core.security.DefaultCertificateManager;
-import org.eclipse.milo.opcua.stack.core.security.DefaultCertificateValidator;
-import org.eclipse.milo.opcua.stack.core.security.DefaultTrustListManager;
+import org.eclipse.milo.opcua.stack.core.application.CertificateManager;
+import org.eclipse.milo.opcua.stack.core.application.CertificateValidator;
+import org.eclipse.milo.opcua.stack.core.application.DefaultCertificateManager;
+import 
org.eclipse.milo.opcua.stack.core.application.DefaultCertificateValidator;
 import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
-import org.eclipse.milo.opcua.stack.core.transport.TransportProfile;
 import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
-import org.eclipse.milo.opcua.stack.core.types.enumerated.MessageSecurityMode;
 import org.eclipse.milo.opcua.stack.core.types.enumerated.UserTokenType;
 import org.eclipse.milo.opcua.stack.core.types.structured.BuildInfo;
 import org.eclipse.milo.opcua.stack.core.types.structured.UserTokenPolicy;
-import org.eclipse.milo.opcua.stack.server.EndpointConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
+import static java.util.Collections.singletonList;
 import static 
org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfig.USER_TOKEN_POLICY_ANONYMOUS;
-import static 
org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfig.USER_TOKEN_POLICY_USERNAME;
-import static 
org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfig.USER_TOKEN_POLICY_X509;
 
 /**
  * OPC UA Server based component
@@ -80,25 +75,54 @@ public class MiloServerComponent extends DefaultComponent {
     private static final Logger LOG = 
LoggerFactory.getLogger(MiloServerComponent.class);
 
     private static final String URL_CHARSET = "UTF-8";
+    private static final OpcUaServerConfig DEFAULT_SERVER_CONFIG;
+
+    static {
+        final OpcUaServerConfigBuilder cfg = OpcUaServerConfig.builder();
+
+        cfg.setCertificateManager(new DefaultCertificateManager());
+        cfg.setCertificateValidator(DenyAllCertificateValidator.INSTANCE);
+        cfg.setSecurityPolicies(EnumSet.allOf(SecurityPolicy.class));
+        cfg.setApplicationName(LocalizedText.english("Apache Camel Milo 
Server"));
+        cfg.setApplicationUri("urn:org:apache:camel:milo:server");
+        cfg.setProductUri("urn:org:apache:camel:milo");
+
+        if 
(Boolean.getBoolean("org.apache.camel.milo.server.default.enableAnonymous")) {
+            
cfg.setUserTokenPolicies(singletonList(USER_TOKEN_POLICY_ANONYMOUS));
+            cfg.setIdentityValidator(AnonymousIdentityValidator.INSTANCE);
+        }
+
+        DEFAULT_SERVER_CONFIG = cfg.build();
+    }
 
-    private int port;
+    private static final class DenyAllCertificateValidator implements 
CertificateValidator {
+        public static final CertificateValidator INSTANCE = new 
DenyAllCertificateValidator();
+
+        private DenyAllCertificateValidator() {
+        }
+
+        @Override
+        public void validate(final X509Certificate certificate) throws 
UaException {
+            throw new UaException(StatusCodes.Bad_CertificateUseNotAllowed);
+        }
+
+        @Override
+        public void verifyTrustChain(List<X509Certificate> certificateChain) 
throws UaException {
+            throw new UaException(StatusCodes.Bad_CertificateUseNotAllowed);
+        }
+    }
 
     private String namespaceUri = DEFAULT_NAMESPACE_URI;
 
-    private OpcUaServerConfigBuilder opcServerConfig;
+    private final OpcUaServerConfigBuilder serverConfig;
 
     private OpcUaServer server;
-
     private CamelNamespace namespace;
 
     private final Map<String, MiloServerEndpoint> endpoints = new HashMap<>();
 
     private Boolean enableAnonymousAuthentication;
 
-    private CertificateManager certificateManager;
-
-    private Set<SecurityPolicy> securityPolicies;
-
     private Map<String, String> userMap;
 
     private String usernameSecurityPolicyUri = 
OpcUaServerConfig.USER_TOKEN_POLICY_USERNAME.getSecurityPolicyUri();
@@ -109,33 +133,19 @@ public class MiloServerComponent extends DefaultComponent 
{
 
     private final List<Runnable> runOnStop = new LinkedList<>();
 
-    private X509Certificate certificate;
-
-    private String productUri;
-
-    private String applicationUri;
-
-    private String applicationName;
-
-    private String path;
-
-    private BuildInfo buildInfo;
-
     public MiloServerComponent() {
-        this.opcServerConfig = null;
+        this(DEFAULT_SERVER_CONFIG);
     }
 
     public MiloServerComponent(final OpcUaServerConfig serverConfig) {
-        this.opcServerConfig = OpcUaServerConfig.copy(serverConfig);
-
+        this.serverConfig = OpcUaServerConfig.copy(serverConfig != null ? 
serverConfig : DEFAULT_SERVER_CONFIG);
     }
 
     @Override
     protected void doStart() throws Exception {
         this.server = new OpcUaServer(buildServerConfig());
 
-        this.namespace = new CamelNamespace(this.namespaceUri, this.server);
-        this.namespace.startup();
+        this.namespace = 
this.server.getNamespaceManager().registerAndAdd(this.namespaceUri, index -> 
new CamelNamespace(index, this.namespaceUri, this.server));
 
         super.doStart();
         this.server.startup();
@@ -147,7 +157,6 @@ public class MiloServerComponent extends DefaultComponent {
      * @return the new server configuration, never returns {@code null}
      */
     private OpcUaServerConfig buildServerConfig() {
-        OpcUaServerConfigBuilder serverConfig = this.opcServerConfig  != null 
? this.opcServerConfig : createDefaultConfiguration();
 
         if (this.userMap != null || this.enableAnonymousAuthentication != 
null) {
             // set identity validator
@@ -161,7 +170,7 @@ public class MiloServerComponent extends DefaultComponent {
                 }
                 return pwd.equals(challenge.getPassword());
             });
-            serverConfig.setIdentityValidator(identityValidator);
+            this.serverConfig.setIdentityValidator(identityValidator);
 
             // add token policies
 
@@ -172,9 +181,11 @@ public class MiloServerComponent extends DefaultComponent {
             if (userMap != null) {
                 tokenPolicies.add(getUsernamePolicy());
             }
-            
serverConfig.setEndpoints(createEndpointConfigurations(tokenPolicies));
-        } else {
-            serverConfig.setEndpoints(createEndpointConfigurations(null, 
securityPolicies));
+            this.serverConfig.setUserTokenPolicies(tokenPolicies);
+        }
+
+        if (this.bindAddresses != null) {
+            this.serverConfig.setBindAddresses(new 
ArrayList<>(this.bindAddresses));
         }
 
         if (this.certificateValidator != null) {
@@ -190,151 +201,12 @@ public class MiloServerComponent extends 
DefaultComponent {
                     }
                 });
             }
-            serverConfig.setCertificateValidator(validator);
+            this.serverConfig.setCertificateValidator(validator);
         }
 
         // build final configuration
-        return serverConfig.build();
-    }
-
-    private OpcUaServerConfigBuilder createDefaultConfiguration() {
-        final OpcUaServerConfigBuilder cfg = OpcUaServerConfig.builder();
-
-        cfg.setCertificateManager(new DefaultCertificateManager());
-        cfg.setCertificateValidator(DenyAllCertificateValidator.INSTANCE);
-        cfg.setEndpoints(createEndpointConfigurations(null));
-        cfg.setApplicationName(LocalizedText.english(applicationName == null ? 
"Apache Camel Milo Server" : applicationName));
-        cfg.setApplicationUri("urn:org:apache:camel:milo:server");
-        cfg.setProductUri("urn:org:apache:camel:milo");
-        cfg.setCertificateManager(certificateManager);
-        if (productUri != null) {
-            cfg.setProductUri(productUri);
-        }
-        if (applicationUri != null) {
-            cfg.setApplicationUri(applicationUri);
-        }
-        if (buildInfo != null) {
-            cfg.setBuildInfo(buildInfo);
-        }
-
-        if 
(Boolean.getBoolean("org.apache.camel.milo.server.default.enableAnonymous")) {
-            cfg.setIdentityValidator(AnonymousIdentityValidator.INSTANCE);
-        }
-
-        return cfg;
-    }
-
-    private Set<EndpointConfiguration> 
createEndpointConfigurations(List<UserTokenPolicy> userTokenPolicies) {
-        return createEndpointConfigurations(userTokenPolicies, 
this.securityPolicies);
-    }
-
-    private Set<EndpointConfiguration> 
createEndpointConfigurations(List<UserTokenPolicy> userTokenPolicies, 
Set<SecurityPolicy> securityPolicies) {
-        Set<EndpointConfiguration> endpointConfigurations = new 
LinkedHashSet<>();
-
-        //if address is not defined, return empty set
-        if (bindAddresses == null) {
-            return Collections.emptySet();
-        }
-
-        for (String bindAddress : bindAddresses) {
-            Set<String> hostnames = new LinkedHashSet<>();
-            hostnames.add(HostnameUtil.getHostname());
-            hostnames.addAll(HostnameUtil.getHostnames(bindAddress));
-
-            boolean anonymous = (this.enableAnonymousAuthentication != null && 
this.enableAnonymousAuthentication)
-                    || 
Boolean.getBoolean("org.apache.camel.milo.server.default.enableAnonymous");
-
-            UserTokenPolicy[] tokenPolicies =
-                    userTokenPolicies != null ? userTokenPolicies.toArray(new 
UserTokenPolicy[userTokenPolicies.size()])
-                            : anonymous
-                                ? new UserTokenPolicy[] 
{USER_TOKEN_POLICY_ANONYMOUS, USER_TOKEN_POLICY_USERNAME, 
USER_TOKEN_POLICY_X509}
-                                : new UserTokenPolicy[] 
{USER_TOKEN_POLICY_USERNAME, USER_TOKEN_POLICY_X509};
-
-            for (String hostname : hostnames) {
-                EndpointConfiguration.Builder builder = 
EndpointConfiguration.newBuilder()
-                        .setBindAddress(bindAddress)
-                        .setHostname(hostname)
-                        .setCertificate(certificate)
-                        .setPath(this.path == null ? "" : this.path)
-                        .addTokenPolicies(tokenPolicies);
-
-
-                if (securityPolicies == null || 
securityPolicies.contains(SecurityPolicy.None)) {
-                    EndpointConfiguration.Builder noSecurityBuilder = 
builder.copy()
-                            .setSecurityPolicy(SecurityPolicy.None)
-                            .setSecurityMode(MessageSecurityMode.None);
-
-                    
endpointConfigurations.add(buildTcpEndpoint(noSecurityBuilder));
-                    
endpointConfigurations.add(buildHttpsEndpoint(noSecurityBuilder));
-                } else if 
(securityPolicies.contains(SecurityPolicy.Basic256Sha256)) {
-
-                    // TCP Basic256Sha256 / SignAndEncrypt
-                    endpointConfigurations.add(buildTcpEndpoint(
-                            builder.copy()
-                                    
.setSecurityPolicy(SecurityPolicy.Basic256Sha256)
-                                    
.setSecurityMode(MessageSecurityMode.SignAndEncrypt))
-                    );
-                } else if 
(securityPolicies.contains(SecurityPolicy.Basic256Sha256)) {
-                    // HTTPS Basic256Sha256 / Sign (SignAndEncrypt not allowed 
for HTTPS)
-                    endpointConfigurations.add(buildHttpsEndpoint(
-                            builder.copy()
-                                    
.setSecurityPolicy(SecurityPolicy.Basic256Sha256)
-                                    .setSecurityMode(MessageSecurityMode.Sign))
-                    );
-                }
-
-                /*
-                 * It's good practice to provide a discovery-specific endpoint 
with no security.
-                 * It's required practice if all regular endpoints have 
security configured.
-                 *
-                 * Usage of the  "/discovery" suffix is defined by OPC UA Part 
6:
-                 *
-                 * Each OPC UA Server Application implements the Discovery 
Service Set. If the OPC UA Server requires a
-                 * different address for this Endpoint it shall create the 
address by appending the path "/discovery" to
-                 * its base address.
-                 */
-                EndpointConfiguration.Builder discoveryBuilder = builder.copy()
-                        .setPath("/discovery")
-                        .setSecurityPolicy(SecurityPolicy.None)
-                        .setSecurityMode(MessageSecurityMode.None);
-
-                endpointConfigurations.add(buildTcpEndpoint(discoveryBuilder));
-                
endpointConfigurations.add(buildHttpsEndpoint(discoveryBuilder));
-            }
-        }
-
-        return endpointConfigurations;
-    }
 
-    private EndpointConfiguration 
buildTcpEndpoint(EndpointConfiguration.Builder base) {
-        return base.copy()
-                .setTransportProfile(TransportProfile.TCP_UASC_UABINARY)
-                .setBindPort(this.port)
-                .build();
-    }
-
-    private EndpointConfiguration 
buildHttpsEndpoint(EndpointConfiguration.Builder base) {
-        return base.copy()
-                .setTransportProfile(TransportProfile.HTTPS_UABINARY)
-                .setBindPort(this.port)
-                .build();
-    }
-
-    private static final class DenyAllCertificateValidator implements 
CertificateValidator {
-        public static final CertificateValidator INSTANCE = new 
DenyAllCertificateValidator();
-
-        private DenyAllCertificateValidator() {
-        }
-
-        @Override
-        public void validate(final X509Certificate certificate) throws 
UaException {
-            throw new UaException(StatusCodes.Bad_CertificateUseNotAllowed);
-        }
-
-        @Override
-        public void verifyTrustChain(List<X509Certificate> certificateChain) 
throws UaException {
-            throw new UaException(StatusCodes.Bad_CertificateUseNotAllowed);
-        }
+        return this.serverConfig.build();
     }
 
     /**
@@ -399,15 +271,7 @@ public class MiloServerComponent extends DefaultComponent {
      */
     public void setApplicationName(final String applicationName) {
         Objects.requireNonNull(applicationName);
-        this.applicationName = applicationName;
-    }
-
-    /**
-     * The path to be appended to the end of the endpoint url. (doesn't need 
to start with '/')
-     */
-    public void setPath(final String path) {
-        Objects.requireNonNull(path);
-        this.path = path;
+        
this.serverConfig.setApplicationName(LocalizedText.english(applicationName));
     }
 
     /**
@@ -415,7 +279,7 @@ public class MiloServerComponent extends DefaultComponent {
      */
     public void setApplicationUri(final String applicationUri) {
         Objects.requireNonNull(applicationUri);
-        this.applicationUri = applicationUri;
+        this.serverConfig.setApplicationUri(applicationUri);
     }
 
     /**
@@ -423,14 +287,35 @@ public class MiloServerComponent extends DefaultComponent 
{
      */
     public void setProductUri(final String productUri) {
         Objects.requireNonNull(productUri);
-        this.productUri = productUri;
+        this.serverConfig.setProductUri(productUri);
     }
 
     /**
      * The TCP port the server binds to
      */
     public void setBindPort(final int port) {
-        this.port = port;
+        this.serverConfig.setBindPort(port);
+    }
+
+    /**
+     * Set whether strict endpoint URLs are enforced
+     */
+    public void setStrictEndpointUrlsEnabled(final boolean 
strictEndpointUrlsEnforced) {
+        
this.serverConfig.setStrictEndpointUrlsEnabled(strictEndpointUrlsEnforced);
+    }
+
+    /**
+     * Server name
+     */
+    public void setServerName(final String serverName) {
+        this.serverConfig.setServerName(serverName);
+    }
+
+    /**
+     * Server hostname
+     */
+    public void setHostname(final String hostname) {
+        this.serverConfig.setServerName(hostname);
     }
 
     /**
@@ -438,9 +323,9 @@ public class MiloServerComponent extends DefaultComponent {
      */
     public void setSecurityPolicies(final Set<SecurityPolicy> 
securityPolicies) {
         if (securityPolicies == null || securityPolicies.isEmpty()) {
-            this.securityPolicies = EnumSet.noneOf(SecurityPolicy.class);
+            
this.serverConfig.setSecurityPolicies(EnumSet.noneOf(SecurityPolicy.class));
         } else {
-            this.securityPolicies = EnumSet.copyOf(securityPolicies);
+            
this.serverConfig.setSecurityPolicies(EnumSet.copyOf(securityPolicies));
         }
     }
 
@@ -457,7 +342,7 @@ public class MiloServerComponent extends DefaultComponent {
             }
         }
 
-        this.securityPolicies = policies;
+        this.serverConfig.setSecurityPolicies(policies);
     }
 
     /**
@@ -507,7 +392,7 @@ public class MiloServerComponent extends DefaultComponent {
      * Set the {@link UserTokenPolicy} used when
      */
     public void setUsernameSecurityPolicyUri(final SecurityPolicy 
usernameSecurityPolicy) {
-        this.usernameSecurityPolicyUri = usernameSecurityPolicy.getUri();
+        this.usernameSecurityPolicyUri = 
usernameSecurityPolicy.getSecurityPolicyUri();
     }
 
     /**
@@ -532,7 +417,7 @@ public class MiloServerComponent extends DefaultComponent {
      * Server build info
      */
     public void setBuildInfo(final BuildInfo buildInfo) {
-        this.buildInfo = buildInfo;
+        this.serverConfig.setBuildInfo(buildInfo);
     }
 
     /**
@@ -555,7 +440,6 @@ public class MiloServerComponent extends DefaultComponent {
      * Server certificate
      */
     public void setServerCertificate(final KeyPair keyPair, final 
X509Certificate certificate) {
-        this.certificate = certificate;
         setCertificateManager(new DefaultCertificateManager(keyPair, 
certificate));
     }
 
@@ -563,7 +447,11 @@ public class MiloServerComponent extends DefaultComponent {
      * Server certificate manager
      */
     public void setCertificateManager(final CertificateManager 
certificateManager) {
-        this.certificateManager = certificateManager != null ? 
certificateManager : new DefaultCertificateManager();
+        if (certificateManager != null) {
+            this.serverConfig.setCertificateManager(certificateManager);
+        } else {
+            this.serverConfig.setCertificateManager(new 
DefaultCertificateManager());
+        }
     }
 
     /**
@@ -577,11 +465,6 @@ public class MiloServerComponent extends DefaultComponent {
      * Validator for client certificates using default file based approach
      */
     public void setDefaultCertificateValidator(final File certificatesBaseDir) 
{
-        try {
-            DefaultTrustListManager trustListManager = new 
DefaultTrustListManager(certificatesBaseDir);
-            this.certificateValidator = () -> new 
DefaultCertificateValidator(trustListManager);
-        } catch (IOException e) {
-            LOG.error("Failed to construct certificateValidator.", e);
-        }
+        this.certificateValidator = () -> new 
DefaultCertificateValidator(certificatesBaseDir);
     }
 }
diff --git 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/internal/CallMethod.java
 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/internal/CallMethod.java
deleted file mode 100644
index c190280..0000000
--- 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/internal/CallMethod.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.camel.component.milo.server.internal;
-
-import org.eclipse.milo.opcua.sdk.core.ValueRanks;
-import 
org.eclipse.milo.opcua.sdk.server.api.methods.AbstractMethodInvocationHandler;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaMethodNode;
-import org.eclipse.milo.opcua.stack.core.Identifiers;
-import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
-import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
-import org.eclipse.milo.opcua.stack.core.types.structured.Argument;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class CallMethod extends AbstractMethodInvocationHandler {
-
-    public static final Argument IN = new Argument(
-        "in",
-        Identifiers.String,
-        ValueRanks.Scalar,
-        null,
-        new LocalizedText("A value.")
-    );
-
-    public static final Argument OUT = new Argument(
-        "out",
-        Identifiers.String,
-        ValueRanks.Scalar,
-        null,
-        new LocalizedText("A value.")
-    );
-
-    private final Logger logger = LoggerFactory.getLogger(getClass());
-
-    public CallMethod(UaMethodNode node) {
-        super(node);
-    }
-
-    @Override
-    public Argument[] getInputArguments() {
-        return new Argument[]{IN};
-    }
-
-    @Override
-    public Argument[] getOutputArguments() {
-        return new Argument[]{OUT};
-    }
-
-    @Override
-    protected Variant[] invoke(InvocationContext invocationContext, Variant[] 
inputValues) {
-        logger.debug("Invoking sqrt() method of objectId={}", 
invocationContext.getObjectId());
-
-        String in = (String) inputValues[0].getValue();
-
-        return new Variant[]{new Variant("out-" + in)};
-    }
-
-}
diff --git 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/internal/CamelNamespace.java
 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/internal/CamelNamespace.java
index 7a166cf..7fdd2a9 100644
--- 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/internal/CamelNamespace.java
+++ 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/internal/CamelNamespace.java
@@ -19,78 +19,157 @@ package org.apache.camel.component.milo.server.internal;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
+import com.google.common.collect.Lists;
+import org.apache.camel.component.milo.client.MiloClientConsumer;
 import org.eclipse.milo.opcua.sdk.core.Reference;
 import org.eclipse.milo.opcua.sdk.server.OpcUaServer;
+import org.eclipse.milo.opcua.sdk.server.api.AccessContext;
 import org.eclipse.milo.opcua.sdk.server.api.DataItem;
-import org.eclipse.milo.opcua.sdk.server.api.ManagedNamespace;
 import org.eclipse.milo.opcua.sdk.server.api.MonitoredItem;
+import org.eclipse.milo.opcua.sdk.server.api.Namespace;
+import org.eclipse.milo.opcua.sdk.server.api.ServerNodeMap;
+import org.eclipse.milo.opcua.sdk.server.nodes.AttributeContext;
+import org.eclipse.milo.opcua.sdk.server.nodes.ServerNode;
 import org.eclipse.milo.opcua.sdk.server.nodes.UaFolderNode;
 import org.eclipse.milo.opcua.sdk.server.nodes.UaObjectNode;
 import org.eclipse.milo.opcua.sdk.server.util.SubscriptionModel;
 import org.eclipse.milo.opcua.stack.core.Identifiers;
+import org.eclipse.milo.opcua.stack.core.StatusCodes;
+import org.eclipse.milo.opcua.stack.core.UaException;
+import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
 import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
 import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
 import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName;
+import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
+import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
+import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort;
+import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass;
+import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
+import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId;
+import org.eclipse.milo.opcua.stack.core.types.structured.WriteValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-public class CamelNamespace extends ManagedNamespace {
+public class CamelNamespace implements Namespace {
 
-    private final SubscriptionModel subscriptionModel;
+    private static final Logger LOG = 
LoggerFactory.getLogger(MiloClientConsumer.class);
+
+    private final UShort namespaceIndex;
 
-    private UaObjectNode itemsObject;
-    private UaFolderNode folder;
+    private final String namespaceUri;
 
+    private final ServerNodeMap nodeManager;
+    private final SubscriptionModel subscriptionModel;
+
+    private final UaFolderNode folder;
+    private final UaObjectNode itemsObject;
 
     private final Map<String, CamelServerItem> itemMap = new HashMap<>();
 
-    public CamelNamespace(final String namespaceUri, final OpcUaServer server) 
{
-        super(server, namespaceUri);
+    public CamelNamespace(final UShort namespaceIndex, final String 
namespaceUri, final OpcUaServer server) {
+        this.namespaceIndex = namespaceIndex;
+        this.namespaceUri = namespaceUri;
 
+        this.nodeManager = server.getNodeMap();
         this.subscriptionModel = new SubscriptionModel(server, this);
+
+        // create structure
+
+        {
+            final NodeId nodeId = new NodeId(namespaceIndex, "camel");
+            final QualifiedName name = new QualifiedName(namespaceIndex, 
"camel");
+            final LocalizedText displayName = LocalizedText.english("Camel");
+
+            this.folder = new UaFolderNode(this.nodeManager, nodeId, name, 
displayName);
+            this.nodeManager.addNode(this.folder);
+        }
+
+        {
+            final NodeId nodeId = new NodeId(namespaceIndex, "items");
+            final QualifiedName name = new QualifiedName(namespaceIndex, 
"items");
+            final LocalizedText displayName = LocalizedText.english("Items");
+            this.itemsObject = new UaObjectNode(this.nodeManager, nodeId, 
name, displayName);
+            this.folder.addComponent(this.itemsObject);
+        }
+
+        // register reference to structure
+
+        try {
+            server.getUaNamespace().addReference(Identifiers.ObjectsFolder, 
Identifiers.Organizes, true, this.folder.getNodeId().expanded(), 
NodeClass.Object);
+        } catch (final UaException e) {
+            throw new RuntimeException("Failed to register folder", e);
+        }
     }
 
     @Override
-    protected void onStartup() {
-        super.onStartup();
-        // create structure
+    public UShort getNamespaceIndex() {
+        return this.namespaceIndex;
+    }
 
-        final NodeId nodeId = newNodeId("camel");
-        final QualifiedName name = newQualifiedName("camel");
-        final LocalizedText displayName = LocalizedText.english("Camel");
+    @Override
+    public String getNamespaceUri() {
+        return this.namespaceUri;
+    }
 
-        this.folder = new UaFolderNode(getNodeContext(), nodeId, name, 
displayName);
-        getNodeManager().addNode(this.folder);
+    @Override
+    public CompletableFuture<List<Reference>> browse(final AccessContext 
context, final NodeId nodeId) {
+        final ServerNode node = this.nodeManager.get(nodeId);
+
+        if (node != null) {
+            return CompletableFuture.completedFuture(node.getReferences());
+        } else {
+            final CompletableFuture<List<Reference>> f = new 
CompletableFuture<>();
+            f.completeExceptionally(new 
UaException(StatusCodes.Bad_NodeIdUnknown));
+            return f;
+        }
+    }
 
-        final NodeId nodeId2 = newNodeId("items");
-        final QualifiedName name2 = newQualifiedName("items");
-        final LocalizedText displayName2 = LocalizedText.english("Items");
+    @Override
+    public void read(final ReadContext context, final Double maxAge, final 
TimestampsToReturn timestamps, final List<ReadValueId> readValueIds) {
+        final List<DataValue> results = 
Lists.newArrayListWithCapacity(readValueIds.size());
 
-        this.itemsObject = UaObjectNode.builder(getNodeContext())
-                .setNodeId(nodeId2)
-                .setBrowseName(name2)
-                .setDisplayName(displayName2)
-                .setTypeDefinition(Identifiers.FolderType)
-                .build();
-        this.folder.addComponent(this.itemsObject);
-        this.itemsObject.addComponent(this.folder);
-        this.getNodeManager().addNode(this.itemsObject);
+        for (final ReadValueId id : readValueIds) {
+            final ServerNode node = this.nodeManager.get(id.getNodeId());
 
+            final DataValue value;
 
-        // register reference to structure
+            if (node != null) {
+                value = node.readAttribute(new AttributeContext(context), 
id.getAttributeId(), timestamps, id.getIndexRange(), null);
+            } else {
+                value = new DataValue(StatusCodes.Bad_NodeIdUnknown);
+            }
+
+            results.add(value);
+        }
+
+        context.complete(results);
+    }
+
+    @Override
+    public void write(final WriteContext context, final List<WriteValue> 
writeValues) {
+        final List<StatusCode> results = 
Lists.newArrayListWithCapacity(writeValues.size());
+
+        for (final WriteValue writeValue : writeValues) {
+            try {
+                final ServerNode node = 
this.nodeManager.getNode(writeValue.getNodeId()).orElseThrow(() -> new 
UaException(StatusCodes.Bad_NodeIdUnknown));
+
+                node.writeAttribute(new AttributeContext(context), 
writeValue.getAttributeId(), writeValue.getValue(), writeValue.getIndexRange());
+
+                if (LOG.isTraceEnabled()) {
+                    final Variant variant = writeValue.getValue().getValue();
+                    final Object o = variant != null ? variant.getValue() : 
null;
+                    LOG.trace("Wrote value={} to attributeId={} of {}", o, 
writeValue.getAttributeId(), writeValue.getNodeId());
+                }
+
+                results.add(StatusCode.GOOD);
+            } catch (final UaException e) {
+                results.add(e.getStatusCode());
+            }
+        }
 
-        folder.addReference(new Reference(
-                folder.getNodeId(),
-                Identifiers.Organizes,
-                Identifiers.ObjectsFolder.expanded(),
-                false
-        ));
-
-        itemsObject.addReference(new Reference(
-                nodeId,
-                Identifiers.HasComponent,
-                Identifiers.ObjectNode.expanded(),
-                Reference.Direction.INVERSE
-        ));
+        context.complete(results);
     }
 
     @Override
@@ -117,7 +196,7 @@ public class CamelNamespace extends ManagedNamespace {
         synchronized (this) {
             CamelServerItem item = this.itemMap.get(itemId);
             if (item == null) {
-                item = new CamelServerItem(itemId, getNodeContext(), 
getNamespaceIndex(), this.itemsObject);
+                item = new CamelServerItem(itemId, this.nodeManager, 
this.namespaceIndex, this.itemsObject);
                 this.itemMap.put(itemId, item);
             }
             return item;
diff --git 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/internal/CamelServerItem.java
 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/internal/CamelServerItem.java
index fa74c02..c1db1eb 100644
--- 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/internal/CamelServerItem.java
+++ 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/server/internal/CamelServerItem.java
@@ -23,7 +23,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
 import java.util.function.Consumer;
 
 import org.eclipse.milo.opcua.sdk.core.AccessLevel;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaNodeContext;
+import org.eclipse.milo.opcua.sdk.server.api.ServerNodeMap;
 import org.eclipse.milo.opcua.sdk.server.nodes.UaObjectNode;
 import org.eclipse.milo.opcua.sdk.server.nodes.UaVariableNode;
 import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
@@ -49,7 +49,7 @@ public class CamelServerItem {
     private final Set<Consumer<DataValue>> listeners = new 
CopyOnWriteArraySet<>();
     private DataValue value = new DataValue(StatusCode.BAD);
 
-    public CamelServerItem(final String itemId, final UaNodeContext 
nodeContext, final UShort namespaceIndex, final UaObjectNode baseNode) {
+    public CamelServerItem(final String itemId, final ServerNodeMap 
nodeManager, final UShort namespaceIndex, final UaObjectNode baseNode) {
 
         this.itemId = itemId;
         this.baseNode = baseNode;
@@ -60,7 +60,7 @@ public class CamelServerItem {
 
         // create variable node
 
-        this.item = new UaVariableNode(nodeContext, nodeId, qname, 
displayName) {
+        this.item = new UaVariableNode(nodeManager, nodeId, qname, 
displayName) {
 
             @Override
             public synchronized DataValue getValue() {
@@ -79,7 +79,6 @@ public class CamelServerItem {
         
this.item.setUserAccessLevel(ubyte(AccessLevel.getMask(AccessLevel.READ_WRITE)));
 
         baseNode.addComponent(this.item);
-        nodeContext.getNodeManager().addNode(this.item);
     }
 
     public void dispose() {
diff --git 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/AbstractMiloServerTest.java
 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/AbstractMiloServerTest.java
index ab12493..35902b0 100644
--- 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/AbstractMiloServerTest.java
+++ 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/AbstractMiloServerTest.java
@@ -27,7 +27,6 @@ import org.apache.camel.test.AvailablePortFinder;
 import org.apache.camel.test.junit4.CamelTestSupport;
 import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
 import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
-import org.junit.Assume;
 
 public abstract class AbstractMiloServerTest extends CamelTestSupport {
 
@@ -35,7 +34,6 @@ public abstract class AbstractMiloServerTest extends 
CamelTestSupport {
 
     @Override
     protected void doPreSetup() throws Exception {
-        Assume.assumeTrue("Requires java 9+", isJavaVersionSatisfied(9));
         super.doPreSetup();
         this.serverPort = AvailablePortFinder.getNextAvailable();
     }
@@ -114,10 +112,9 @@ public abstract class AbstractMiloServerTest extends 
CamelTestSupport {
         try {
 
             final KeyStoreLoader loader = new KeyStoreLoader();
-            loader.setUrl("file:src/test/resources/keystore");
-            loader.setKeyStorePassword("testtest");
-
-            loader.setKeyPassword("test");
+            loader.setUrl("file:src/test/resources/cert/cert.p12");
+            loader.setKeyStorePassword("pwd1");
+            loader.setKeyPassword("pwd1");
             return loader.load();
         } catch (final GeneralSecurityException | IOException e) {
             throw new RuntimeException(e);
@@ -125,22 +122,4 @@ public abstract class AbstractMiloServerTest extends 
CamelTestSupport {
 
     }
 
-    /**
-     * Return true, if java version (defined by method 
getRequiredJavaVersion()) is satisfied.
-     * Works for java versions 9+
-     */
-    boolean isJavaVersionSatisfied(int requiredVersion) {
-        String version = System.getProperty("java.version");
-        if (!version.startsWith("1.")) {
-            int dot = version.indexOf(".");
-            if (dot != -1) {
-                version = version.substring(0, dot);
-            }
-            if (Integer.parseInt(version) >= requiredVersion) {
-                return true;
-            }
-        }
-        return false;
-    }
-
 }
diff --git 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/MonitorItemMultiConnectionsCertTest.java
 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/MonitorItemMultiConnectionsCertTest.java
index 5b3bcfcf..1c10522 100644
--- 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/MonitorItemMultiConnectionsCertTest.java
+++ 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/MonitorItemMultiConnectionsCertTest.java
@@ -43,18 +43,18 @@ public class MonitorItemMultiConnectionsCertTest extends 
AbstractMiloServerTest
     private static final String MILO_SERVER_ITEM_1 = "milo-server:myitem1";
 
     // with key
-    private static final String MILO_CLIENT_ITEM_C1_1 = 
"milo-client:opc.tcp://foo:bar@localhost:@@port@@?node="
+    private static final String MILO_CLIENT_ITEM_C1_1 = 
"milo-client:tcp://foo:bar@localhost:@@port@@?node="
                                                         + 
NodeIds.nodeValue(MiloServerComponent.DEFAULT_NAMESPACE_URI, "items-myitem1")
-                                                        + 
"&keyStoreUrl=file:src/test/resources/keystore&keyStorePassword=testtest&keyPassword=test&keyAlias=test"
+                                                        + 
"&keyStoreUrl=file:src/test/resources/cert/cert.p12&keyStorePassword=pwd1&keyPassword=pwd1"
                                                         + 
"&discoveryEndpointSuffix=/discovery&overrideHost=true";
 
     // with wrong password
-    private static final String MILO_CLIENT_ITEM_C2_1 = 
"milo-client:opc.tcp://foo:bar2@localhost:@@port@@?node="
+    private static final String MILO_CLIENT_ITEM_C2_1 = 
"milo-client:tcp://foo:bar2@localhost:@@port@@?node="
                                                         + 
NodeIds.nodeValue(MiloServerComponent.DEFAULT_NAMESPACE_URI, "items-myitem1")
                                                         + 
"&discoveryEndpointSuffix=/discovery&overrideHost=true";
 
     // without key, clientId=1
-    private static final String MILO_CLIENT_ITEM_C3_1 = 
"milo-client:opc.tcp://foo:bar@localhost:@@port@@?clientId=1&node="
+    private static final String MILO_CLIENT_ITEM_C3_1 = 
"milo-client:tcp://foo:bar@localhost:@@port@@?clientId=1&node="
                                                         + 
NodeIds.nodeValue(MiloServerComponent.DEFAULT_NAMESPACE_URI, "items-myitem1")
                                                         + 
"&discoveryEndpointSuffix=/discovery&overrideHost=true";
 
@@ -79,10 +79,10 @@ public class MonitorItemMultiConnectionsCertTest extends 
AbstractMiloServerTest
         super.configureMiloServer(server);
 
         final Path baseDir = Paths.get("target/testing/cert/default");
-        final Path trusted = baseDir.resolve("trusted/certs");
+        final Path trusted = baseDir.resolve("trusted");
 
         Files.createDirectories(trusted);
-        Files.copy(Paths.get("src/test/resources/ca/cacert.pem"), 
trusted.resolve("cacert.pem"), REPLACE_EXISTING);
+        Files.copy(Paths.get("src/test/resources/cert/certificate.der"), 
trusted.resolve("certificate.der"), REPLACE_EXISTING);
 
         server.setServerCertificate(loadDefaultTestKey());
         server.setDefaultCertificateValidator(baseDir.toFile());
diff --git 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/MonitorItemMultiConnectionsTest.java
 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/MonitorItemMultiConnectionsTest.java
index 116cf98..dcccaf9 100644
--- 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/MonitorItemMultiConnectionsTest.java
+++ 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/MonitorItemMultiConnectionsTest.java
@@ -34,13 +34,13 @@ public class MonitorItemMultiConnectionsTest extends 
AbstractMiloServerTest {
 
     private static final String MILO_SERVER_ITEM_1 = "milo-server:myitem1";
 
-    private static final String MILO_CLIENT_ITEM_C1_1 = 
"milo-client:opc.tcp://foo:bar@localhost:@@port@@?node="
+    private static final String MILO_CLIENT_ITEM_C1_1 = 
"milo-client:tcp://foo:bar@localhost:@@port@@?node="
                                                         + 
NodeIds.nodeValue(MiloServerComponent.DEFAULT_NAMESPACE_URI, "items-myitem1") + 
"&overrideHost=true";
 
-    private static final String MILO_CLIENT_ITEM_C2_1 = 
"milo-client:opc.tcp://foo:bar2@localhost:@@port@@?node="
+    private static final String MILO_CLIENT_ITEM_C2_1 = 
"milo-client:tcp://foo:bar2@localhost:@@port@@?node="
                                                         + 
NodeIds.nodeValue(MiloServerComponent.DEFAULT_NAMESPACE_URI, "items-myitem1") + 
"&overrideHost=true";
 
-    private static final String MILO_CLIENT_ITEM_C3_1 = 
"milo-client:opc.tcp://foo2:bar@localhost:@@port@@?node="
+    private static final String MILO_CLIENT_ITEM_C3_1 = 
"milo-client:tcp://foo2:bar@localhost:@@port@@?node="
                                                         + 
NodeIds.nodeValue(MiloServerComponent.DEFAULT_NAMESPACE_URI, "items-myitem1") + 
"&overrideHost=true";
 
     private static final String MOCK_TEST_1 = "mock:test1";
diff --git 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/MonitorItemTest.java
 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/MonitorItemTest.java
index 3b3ba6d..b4d9b3e 100644
--- 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/MonitorItemTest.java
+++ 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/MonitorItemTest.java
@@ -34,9 +34,9 @@ public class MonitorItemTest extends AbstractMiloServerTest {
 
     private static final String MILO_SERVER_ITEM_1 = "milo-server:myitem1";
 
-    private static final String MILO_CLIENT_ITEM_C1_1 = 
"milo-client:opc.tcp://foo:bar@localhost:@@port@@?node="
-                                                    + 
NodeIds.nodeValue(MiloServerComponent.DEFAULT_NAMESPACE_URI, "items-myitem1")
-                                                    + 
"&allowedSecurityPolicies=None&overrideHost=true";
+    private static final String MILO_CLIENT_ITEM_C1_1 = 
"milo-client:tcp://foo:bar@localhost:@@port@@?node="
+                                                        + 
NodeIds.nodeValue(MiloServerComponent.DEFAULT_NAMESPACE_URI, "items-myitem1")
+                                                        + 
"&allowedSecurityPolicies=None&overrideHost=true";
 
     private static final String MOCK_TEST_1 = "mock:test1";
 
diff --git 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/WriteClientTest.java
 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/WriteClientTest.java
index 9a0942c..43214b3 100644
--- 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/WriteClientTest.java
+++ 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/WriteClientTest.java
@@ -41,8 +41,8 @@ public class WriteClientTest extends AbstractMiloServerTest {
     private static final String MILO_SERVER_ITEM_1 = "milo-server:myitem1";
     private static final String MILO_SERVER_ITEM_2 = "milo-server:myitem2";
 
-    private static final String MILO_CLIENT_BASE_C1 = 
"milo-client:opc.tcp://foo:bar@localhost:@@port@@";
-    private static final String MILO_CLIENT_BASE_C2 = 
"milo-client:opc.tcp://foo2:bar2@localhost:@@port@@";
+    private static final String MILO_CLIENT_BASE_C1 = 
"milo-client:tcp://foo:bar@localhost:@@port@@";
+    private static final String MILO_CLIENT_BASE_C2 = 
"milo-client:tcp://foo2:bar2@localhost:@@port@@";
 
     private static final String MILO_CLIENT_ITEM_C1_1 = MILO_CLIENT_BASE_C1 + 
"?node=" + nodeValue(MiloServerComponent.DEFAULT_NAMESPACE_URI, "items-myitem1")
                                                         + "&overrideHost=true";
diff --git 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/CallClientTest.java
 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/CallClientTest.java
index db70850..56ef9ee 100644
--- 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/CallClientTest.java
+++ 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/CallClientTest.java
@@ -18,34 +18,29 @@ package org.apache.camel.component.milo.call;
 
 import java.util.Arrays;
 import java.util.EnumSet;
-import java.util.LinkedHashSet;
+import java.util.LinkedList;
 import java.util.List;
-import java.util.Set;
 
 import org.apache.camel.Produce;
 import org.apache.camel.ProducerTemplate;
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.milo.AbstractMiloServerTest;
-import org.apache.camel.component.milo.NodeIds;
+import org.apache.camel.component.milo.call.MockCall.Call1;
 import org.eclipse.milo.opcua.sdk.server.OpcUaServer;
 import org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfig;
 import org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfigBuilder;
-import org.eclipse.milo.opcua.sdk.server.util.HostnameUtil;
-import org.eclipse.milo.opcua.stack.core.security.DefaultCertificateManager;
-import org.eclipse.milo.opcua.stack.core.security.InsecureCertificateValidator;
+import org.eclipse.milo.opcua.sdk.server.identity.AnonymousIdentityValidator;
+import org.eclipse.milo.opcua.sdk.server.nodes.UaMethodNode;
+import org.eclipse.milo.opcua.stack.core.application.DefaultCertificateManager;
+import 
org.eclipse.milo.opcua.stack.core.application.InsecureCertificateValidator;
 import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
-import org.eclipse.milo.opcua.stack.core.transport.TransportProfile;
-import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
-import org.eclipse.milo.opcua.stack.core.types.enumerated.MessageSecurityMode;
-import org.eclipse.milo.opcua.stack.core.types.structured.UserTokenPolicy;
-import org.eclipse.milo.opcua.stack.server.EndpointConfiguration;
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
 import static org.apache.camel.component.milo.NodeIds.nodeValue;
-import static 
org.eclipse.milo.opcua.sdk.server.api.config.OpcUaServerConfig.USER_TOKEN_POLICY_ANONYMOUS;
 
 /**
  * Unit tests for calling from the client side
@@ -54,27 +49,17 @@ public class CallClientTest extends AbstractMiloServerTest {
 
     private static final String DIRECT_START_1 = "direct:start1";
 
-    private static final String MILO_CLIENT_BASE_C1 = 
"milo-client:opc.tcp://localhost:@@port@@";
+    private static final String MILO_CLIENT_BASE_C1 = 
"milo-client:tcp://localhost:@@port@@";
 
-    private static final String MILO_CLIENT_ITEM_C1_1 = MILO_CLIENT_BASE_C1 + 
"?node=" + NodeIds.nodeValue(MockCamelNamespace.URI, 
MockCamelNamespace.FOLDER_ID)
-                                                        + "&method=" + 
nodeValue(MockCamelNamespace.URI, MockCamelNamespace.CALL_ID) + 
"&overrideHost=true";
-
-    private OpcUaServer server;
-    private MockCamelNamespace namespace;
-    private MockCallMethod callMethod;
+    private static final String MILO_CLIENT_ITEM_C1_1 = MILO_CLIENT_BASE_C1 + 
"?node=" + nodeValue(MockNamespace.URI, MockNamespace.FOLDER_ID) + "&method="
+                                                        + 
nodeValue(MockNamespace.URI, "id1") + "&overrideHost=true";
 
     @Produce(DIRECT_START_1)
-    private ProducerTemplate producer1;
+    protected ProducerTemplate producer1;
 
-    @Override
-    protected RoutesBuilder createRouteBuilder() throws Exception {
-        return new RouteBuilder() {
-            @Override
-            public void configure() throws Exception {
-                from(DIRECT_START_1).to(resolve(MILO_CLIENT_ITEM_C1_1));
-            }
-        };
-    }
+    private OpcUaServer server;
+
+    private Call1 call1;
 
     @Override
     protected boolean isAddServer() {
@@ -83,75 +68,43 @@ public class CallClientTest extends AbstractMiloServerTest {
 
     @Before
     public void start() throws Exception {
-        final OpcUaServerConfigBuilder cfg = OpcUaServerConfig.builder();
-
-        cfg.setCertificateManager(new DefaultCertificateManager());
-        
cfg.setEndpoints(createEndpointConfigurations(Arrays.asList(OpcUaServerConfig.USER_TOKEN_POLICY_ANONYMOUS),
 EnumSet.of(SecurityPolicy.None)));
-        cfg.setApplicationName(LocalizedText.english("Apache Camel Milo 
Server"));
-        cfg.setApplicationUri("urn:mock:namespace");
-        cfg.setProductUri("urn:org:apache:camel:milo");
-        cfg.setCertificateManager(new DefaultCertificateManager());
-        cfg.setCertificateValidator(new InsecureCertificateValidator());
-
-        this.server = new OpcUaServer(cfg.build());
+        final OpcUaServerConfigBuilder config = new OpcUaServerConfigBuilder();
+        config.setBindAddresses(Arrays.asList("localhost"));
+        config.setBindPort(getServerPort());
+        config.setIdentityValidator(AnonymousIdentityValidator.INSTANCE);
+        
config.setUserTokenPolicies(Arrays.asList(OpcUaServerConfig.USER_TOKEN_POLICY_ANONYMOUS));
+        config.setSecurityPolicies(EnumSet.of(SecurityPolicy.None));
+        config.setCertificateManager(new DefaultCertificateManager());
+        config.setCertificateValidator(new InsecureCertificateValidator());
 
-        this.namespace = new MockCamelNamespace(this.server, node -> 
callMethod = new MockCallMethod(node));
-        this.namespace.startup();
-        this.server.startup().get();
-    }
+        this.server = new OpcUaServer(config.build());
 
-    private Set<EndpointConfiguration> 
createEndpointConfigurations(List<UserTokenPolicy> userTokenPolicies, 
Set<SecurityPolicy> securityPolicies) {
-        Set<EndpointConfiguration> endpointConfigurations = new 
LinkedHashSet<>();
+        this.call1 = new MockCall.Call1();
 
-        String bindAddress = "0.0.0.0";
-        Set<String> hostnames = new LinkedHashSet<>();
-        hostnames.add(HostnameUtil.getHostname());
-        hostnames.addAll(HostnameUtil.getHostnames(bindAddress));
+        this.server.getNamespaceManager().registerAndAdd(MockNamespace.URI, 
index -> {
 
-        UserTokenPolicy[] tokenPolicies = new UserTokenPolicy[] 
{USER_TOKEN_POLICY_ANONYMOUS};
+            final List<UaMethodNode> methods = new LinkedList<>();
+            methods.add(MockCall.fromNode(index, this.server.getNodeMap(), 
"id1", "name1", this.call1));
 
-        for (String hostname : hostnames) {
-            EndpointConfiguration.Builder builder = 
EndpointConfiguration.newBuilder()
-                    .setBindAddress(bindAddress)
-                    .setHostname(hostname)
-                    .setCertificate(() -> null)
-                    .addTokenPolicies(tokenPolicies);
+            return new MockNamespace(index, this.server, methods);
+        });
 
+        this.server.startup().get();
+    }
 
-            if (securityPolicies == null || 
securityPolicies.contains(SecurityPolicy.None)) {
-                EndpointConfiguration.Builder noSecurityBuilder = 
builder.copy()
-                        .setSecurityPolicy(SecurityPolicy.None)
-                        .setSecurityMode(MessageSecurityMode.None);
-
-                
endpointConfigurations.add(buildTcpEndpoint(noSecurityBuilder));
-            }
-            /*
-             * It's good practice to provide a discovery-specific endpoint 
with no security.
-             * It's required practice if all regular endpoints have security 
configured.
-             *
-             * Usage of the  "/discovery" suffix is defined by OPC UA Part 6:
-             *
-             * Each OPC UA Server Application implements the Discovery Service 
Set. If the OPC UA Server requires a
-             * different address for this Endpoint it shall create the address 
by appending the path "/discovery" to
-             * its base address.
-             */
-
-            EndpointConfiguration.Builder discoveryBuilder = builder.copy()
-                    .setPath("/discovery")
-                    .setSecurityPolicy(SecurityPolicy.None)
-                    .setSecurityMode(MessageSecurityMode.None);
-
-            endpointConfigurations.add(buildTcpEndpoint(discoveryBuilder));
-        }
-
-        return endpointConfigurations;
+    @After
+    public void stop() {
+        this.server.shutdown();
     }
 
-    private EndpointConfiguration 
buildTcpEndpoint(EndpointConfiguration.Builder base) {
-        return base.copy()
-                .setTransportProfile(TransportProfile.TCP_UASC_UABINARY)
-                .setBindPort(getServerPort())
-                .build();
+    @Override
+    protected RoutesBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from(DIRECT_START_1).to(resolve(MILO_CLIENT_ITEM_C1_1));
+            }
+        };
     }
 
     @Test
@@ -162,8 +115,8 @@ public class CallClientTest extends AbstractMiloServerTest {
         doCall(this.producer1, "bar");
 
         // assert
-        Assert.assertNotNull(this.callMethod);
-        Assert.assertArrayEquals(new Object[] {"out-foo", "out-bar"}, 
this.callMethod.getCalls().toArray());
+
+        Assert.assertArrayEquals(new Object[] {"foo", "bar"}, 
this.call1.calls.toArray());
     }
 
     private static void doCall(final ProducerTemplate producerTemplate, final 
Object input) {
diff --git 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/MockCall.java
 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/MockCall.java
new file mode 100644
index 0000000..51408c2
--- /dev/null
+++ 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/MockCall.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.milo.call;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.milo.opcua.sdk.server.annotations.UaInputArgument;
+import org.eclipse.milo.opcua.sdk.server.annotations.UaMethod;
+import org.eclipse.milo.opcua.sdk.server.annotations.UaOutputArgument;
+import org.eclipse.milo.opcua.sdk.server.api.ServerNodeMap;
+import org.eclipse.milo.opcua.sdk.server.nodes.UaMethodNode;
+import org.eclipse.milo.opcua.sdk.server.util.AnnotationBasedInvocationHandler;
+import 
org.eclipse.milo.opcua.sdk.server.util.AnnotationBasedInvocationHandler.InvocationContext;
+import 
org.eclipse.milo.opcua.sdk.server.util.AnnotationBasedInvocationHandler.Out;
+import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
+import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName;
+import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
+import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort;
+
+import static 
org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText.english;
+
+public final class MockCall {
+
+    private MockCall() {
+    }
+
+    // in: str1[String], out: out1[String]
+    public static class Call1 {
+
+        public List<String> calls = new LinkedList<>();
+
+        @UaMethod
+        public void call(final InvocationContext context, 
@UaInputArgument(name = "in1")
+        final String in1, @UaOutputArgument(name = "out1")
+        final Out<String> out1) {
+            this.calls.add(in1);
+            out1.set("out-" + in1);
+        }
+    }
+
+    public static UaMethodNode fromNode(final UShort index, final 
ServerNodeMap nodeMap, final String nodeId, final String name, final Object 
methodObject) {
+
+        try {
+            final UaMethodNode method = new UaMethodNode(nodeMap, new 
NodeId(index, nodeId), new QualifiedName(index, name), english(name), 
english(nodeId), UInteger.MIN,
+                                                         UInteger.MIN, true, 
true);
+
+            final AnnotationBasedInvocationHandler handler = 
AnnotationBasedInvocationHandler.fromAnnotatedObject(nodeMap, methodObject);
+            method.setInputArguments(handler.getInputArguments());
+            method.setOutputArguments(handler.getOutputArguments());
+            method.setInvocationHandler(handler);
+            return method;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/MockCallMethod.java
 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/MockCallMethod.java
deleted file mode 100644
index fe52c8c..0000000
--- 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/MockCallMethod.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.camel.component.milo.call;
-
-import java.util.LinkedList;
-import java.util.List;
-
-import org.eclipse.milo.opcua.sdk.core.ValueRanks;
-import 
org.eclipse.milo.opcua.sdk.server.api.methods.AbstractMethodInvocationHandler;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaMethodNode;
-import org.eclipse.milo.opcua.stack.core.Identifiers;
-import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
-import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
-import org.eclipse.milo.opcua.stack.core.types.structured.Argument;
-
-public class MockCallMethod extends AbstractMethodInvocationHandler {
-
-    public static final Argument IN = new Argument(
-        "in",
-        Identifiers.String,
-        ValueRanks.Scalar,
-        null,
-        new LocalizedText("A value.")
-    );
-
-    public static final Argument OUT = new Argument(
-        "out",
-        Identifiers.String,
-        ValueRanks.Scalar,
-        null,
-        new LocalizedText("A value.")
-    );
-
-    public List<String> calls = new LinkedList<>();
-
-    public MockCallMethod(UaMethodNode node) {
-        super(node);
-    }
-
-    @Override
-    public Argument[] getInputArguments() {
-        return new Argument[]{IN};
-    }
-
-    @Override
-    public Argument[] getOutputArguments() {
-        return new Argument[]{OUT};
-    }
-
-    @Override
-    protected Variant[] invoke(InvocationContext invocationContext, Variant[] 
inputValues) {
-        String in = (String) inputValues[0].getValue();
-
-        calls.add("out-" + in);
-
-        return new Variant[]{new Variant("out-" + in)};
-    }
-
-    public List<String> getCalls() {
-        return calls;
-    }
-}
diff --git 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/MockCamelNamespace.java
 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/MockCamelNamespace.java
deleted file mode 100644
index 3197485..0000000
--- 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/MockCamelNamespace.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.milo.call;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-
-import org.apache.camel.component.milo.client.MiloClientConsumer;
-import org.apache.camel.component.milo.server.internal.CamelServerItem;
-import org.eclipse.milo.opcua.sdk.core.Reference;
-import org.eclipse.milo.opcua.sdk.server.OpcUaServer;
-import org.eclipse.milo.opcua.sdk.server.api.DataItem;
-import org.eclipse.milo.opcua.sdk.server.api.ManagedNamespace;
-import org.eclipse.milo.opcua.sdk.server.api.MonitoredItem;
-import 
org.eclipse.milo.opcua.sdk.server.api.methods.AbstractMethodInvocationHandler;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaFolderNode;
-import org.eclipse.milo.opcua.sdk.server.nodes.UaMethodNode;
-import org.eclipse.milo.opcua.sdk.server.util.SubscriptionModel;
-import org.eclipse.milo.opcua.stack.core.Identifiers;
-import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
-import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
-import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MockCamelNamespace extends ManagedNamespace {
-
-    public static final String URI = "urn:org:apache:camel:mock";
-    public static final int FOLDER_ID = 1;
-    public static final int CALL_ID = 2;
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(MiloClientConsumer.class);
-
-    private final SubscriptionModel subscriptionModel;
-
-    private final Function<UaMethodNode, AbstractMethodInvocationHandler> 
callMethodCreator;
-
-    private UaFolderNode folder;
-
-    private final Map<String, CamelServerItem> itemMap = new HashMap<>();
-
-    public MockCamelNamespace(final OpcUaServer server, Function<UaMethodNode, 
AbstractMethodInvocationHandler>  callMethodCreator) {
-        super(server, URI);
-
-        this.subscriptionModel = new SubscriptionModel(server, this);
-        this.callMethodCreator = callMethodCreator;
-    }
-
-    @Override
-    protected void onStartup() {
-        super.onStartup();
-        // create structure
-
-        final NodeId nodeId = newNodeId(FOLDER_ID);
-        final QualifiedName name = newQualifiedName("camel");
-        final LocalizedText displayName = LocalizedText.english("Camel");
-
-        this.folder = new UaFolderNode(getNodeContext(), nodeId, name, 
displayName);
-        getNodeManager().addNode(this.folder);
-
-        // register reference to structure
-
-        folder.addReference(new Reference(
-                folder.getNodeId(),
-                Identifiers.Organizes,
-                Identifiers.ObjectsFolder.expanded(),
-                false
-        ));
-
-        addCallMethod(folder);
-    }
-
-    private void addCallMethod(UaFolderNode folderNode) {
-        UaMethodNode methodNode = UaMethodNode.builder(getNodeContext())
-                .setNodeId(new NodeId(getNamespaceIndex(), CALL_ID))
-                .setBrowseName(newQualifiedName("call"))
-                .setDisplayName(new LocalizedText(null, "call"))
-                .setDescription(
-                        LocalizedText.english("Returns the \"out-\"+entry 
parameter"))
-                .build();
-
-        AbstractMethodInvocationHandler callMethod = 
callMethodCreator.apply(methodNode);
-        methodNode.setProperty(UaMethodNode.InputArguments, 
callMethod.getInputArguments());
-        methodNode.setProperty(UaMethodNode.OutputArguments, 
callMethod.getOutputArguments());
-        methodNode.setInvocationHandler(callMethod);
-
-        getNodeManager().addNode(methodNode);
-
-        methodNode.addReference(new Reference(
-                methodNode.getNodeId(),
-                Identifiers.HasComponent,
-                folderNode.getNodeId().expanded(),
-                false
-        ));
-
-        methodNode.addReference(new Reference(
-                methodNode.getNodeId(),
-                Identifiers.HasComponent,
-                folderNode.getNodeId().expanded(),
-                folderNode.getNodeClass(),
-                false
-        ));
-    }
-
-
-    @Override
-    public void onDataItemsCreated(final List<DataItem> dataItems) {
-        this.subscriptionModel.onDataItemsCreated(dataItems);
-    }
-
-    @Override
-    public void onDataItemsModified(final List<DataItem> dataItems) {
-        this.subscriptionModel.onDataItemsModified(dataItems);
-    }
-
-    @Override
-    public void onDataItemsDeleted(final List<DataItem> dataItems) {
-        this.subscriptionModel.onDataItemsDeleted(dataItems);
-    }
-
-    @Override
-    public void onMonitoringModeChanged(final List<MonitoredItem> 
monitoredItems) {
-        this.subscriptionModel.onMonitoringModeChanged(monitoredItems);
-    }
-}
diff --git 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/MockNamespace.java
 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/MockNamespace.java
new file mode 100644
index 0000000..1acd8de
--- /dev/null
+++ 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/call/MockNamespace.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.milo.call;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.milo.opcua.sdk.core.Reference;
+import org.eclipse.milo.opcua.sdk.server.OpcUaServer;
+import org.eclipse.milo.opcua.sdk.server.api.AccessContext;
+import org.eclipse.milo.opcua.sdk.server.api.DataItem;
+import org.eclipse.milo.opcua.sdk.server.api.MethodInvocationHandler;
+import org.eclipse.milo.opcua.sdk.server.api.MonitoredItem;
+import org.eclipse.milo.opcua.sdk.server.api.Namespace;
+import org.eclipse.milo.opcua.sdk.server.api.ServerNodeMap;
+import org.eclipse.milo.opcua.sdk.server.model.nodes.objects.FolderNode;
+import org.eclipse.milo.opcua.sdk.server.nodes.AttributeContext;
+import org.eclipse.milo.opcua.sdk.server.nodes.ServerNode;
+import org.eclipse.milo.opcua.sdk.server.nodes.UaFolderNode;
+import org.eclipse.milo.opcua.sdk.server.nodes.UaMethodNode;
+import org.eclipse.milo.opcua.sdk.server.util.SubscriptionModel;
+import org.eclipse.milo.opcua.stack.core.Identifiers;
+import org.eclipse.milo.opcua.stack.core.StatusCodes;
+import org.eclipse.milo.opcua.stack.core.UaException;
+import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
+import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
+import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
+import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName;
+import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
+import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort;
+import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
+import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId;
+import org.eclipse.milo.opcua.stack.core.types.structured.WriteValue;
+
+import static java.util.stream.Collectors.toList;
+
+public class MockNamespace implements Namespace {
+
+    public static final int FOLDER_ID = 1;
+
+    public static final String URI = "urn:mock:namespace";
+
+    private final UShort index;
+
+    private final ServerNodeMap nodeMap;
+    private final SubscriptionModel subscriptionModel;
+
+    public MockNamespace(final UShort index, final OpcUaServer server, 
List<UaMethodNode> methods) {
+        this.index = index;
+        this.nodeMap = server.getNodeMap();
+        this.subscriptionModel = new SubscriptionModel(server, this);
+
+        registerItems(methods);
+    }
+
+    private void registerItems(List<UaMethodNode> methods) {
+
+        // create a folder
+
+        final UaFolderNode folder = new UaFolderNode(this.nodeMap, new 
NodeId(this.index, FOLDER_ID), new QualifiedName(this.index, "FooBarFolder"),
+                                                     
LocalizedText.english("Foo Bar Folder"));
+
+        // add our folder to the objects folder
+
+        this.nodeMap.getNode(Identifiers.ObjectsFolder).ifPresent(node -> {
+            ((FolderNode)node).addComponent(folder);
+        });
+
+        // add method calls
+
+        methods.forEach(folder::addComponent);
+    }
+
+    // default method implementations follow
+
+    @Override
+    public void read(final ReadContext context, final Double maxAge, final 
TimestampsToReturn timestamps, final List<ReadValueId> readValueIds) {
+
+        final List<DataValue> results = new ArrayList<>(readValueIds.size());
+
+        for (final ReadValueId id : readValueIds) {
+            final ServerNode node = this.nodeMap.get(id.getNodeId());
+
+            final DataValue value = node != null ? node.readAttribute(new 
AttributeContext(context), id.getAttributeId()) : new 
DataValue(StatusCodes.Bad_NodeIdUnknown);
+
+            results.add(value);
+        }
+
+        // report back with result
+
+        context.complete(results);
+    }
+
+    @Override
+    public void write(final WriteContext context, final List<WriteValue> 
writeValues) {
+
+        final List<StatusCode> results = writeValues.stream().map(value -> {
+            if (this.nodeMap.containsKey(value.getNodeId())) {
+                return new StatusCode(StatusCodes.Bad_NotWritable);
+            } else {
+                return new StatusCode(StatusCodes.Bad_NodeIdUnknown);
+            }
+        }).collect(toList());
+
+        // report back with result
+
+        context.complete(results);
+    }
+
+    @Override
+    public CompletableFuture<List<Reference>> browse(final AccessContext 
context, final NodeId nodeId) {
+        final ServerNode node = this.nodeMap.get(nodeId);
+
+        if (node != null) {
+            return CompletableFuture.completedFuture(node.getReferences());
+        } else {
+            final CompletableFuture<List<Reference>> f = new 
CompletableFuture<>();
+            f.completeExceptionally(new 
UaException(StatusCodes.Bad_NodeIdUnknown));
+            return f;
+        }
+    }
+
+    @Override
+    public Optional<MethodInvocationHandler> getInvocationHandler(final NodeId 
methodId) {
+        return Optional.ofNullable(this.nodeMap.get(methodId)).filter(n -> n 
instanceof UaMethodNode).flatMap(n -> {
+            final UaMethodNode m = (UaMethodNode)n;
+            return m.getInvocationHandler();
+        });
+    }
+
+    @Override
+    public void onDataItemsCreated(final List<DataItem> dataItems) {
+        this.subscriptionModel.onDataItemsCreated(dataItems);
+    }
+
+    @Override
+    public void onDataItemsModified(final List<DataItem> dataItems) {
+        this.subscriptionModel.onDataItemsModified(dataItems);
+    }
+
+    @Override
+    public void onDataItemsDeleted(final List<DataItem> dataItems) {
+        this.subscriptionModel.onDataItemsDeleted(dataItems);
+    }
+
+    @Override
+    public void onMonitoringModeChanged(final List<MonitoredItem> 
monitoredItems) {
+        this.subscriptionModel.onMonitoringModeChanged(monitoredItems);
+    }
+
+    @Override
+    public UShort getNamespaceIndex() {
+        return this.index;
+    }
+
+    @Override
+    public String getNamespaceUri() {
+        return URI;
+    }
+}
diff --git 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/server/ServerSetCertificateManagerTest.java
 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/server/ServerSetCertificateManagerTest.java
index f4ea7f4..fe58263 100644
--- 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/server/ServerSetCertificateManagerTest.java
+++ 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/server/ServerSetCertificateManagerTest.java
@@ -38,7 +38,7 @@ public class ServerSetCertificateManagerTest extends 
AbstractMiloServerTest {
         final Path trusted = baseDir.resolve("trusted");
 
         Files.createDirectories(trusted);
-        Files.copy(Paths.get("src/test/resources/ca/cacert.pem"), 
trusted.resolve("cacert.pem"), REPLACE_EXISTING);
+        Files.copy(Paths.get("src/test/resources/cert/certificate.der"), 
trusted.resolve("certificate.der"), REPLACE_EXISTING);
 
         server.setServerCertificate(loadDefaultTestKey());
         server.setDefaultCertificateValidator(baseDir.toFile());
diff --git a/components/camel-milo/src/test/resources/ca/cacert.pem 
b/components/camel-milo/src/test/resources/ca/cacert.pem
deleted file mode 100644
index f23452c..0000000
--- a/components/camel-milo/src/test/resources/ca/cacert.pem
+++ /dev/null
@@ -1,32 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFeTCCA2GgAwIBAgIJAIoc1wRX1g4hMA0GCSqGSIb3DQEBCwUAMEsxCzAJBgNV
-BAYTAlJIMQswCQYDVQQIDAJSSDELMAkGA1UEBwwCUkgxEDAOBgNVBAoMB1Rlc3Qg
-Q0ExEDAOBgNVBAMMB1Rlc3QgQ0EwHhcNMjAwMTI4MTYxNTA0WhcNMjAwMjI3MTYx
-NTA0WjBLMQswCQYDVQQGEwJSSDELMAkGA1UECAwCUkgxCzAJBgNVBAcMAlJIMRAw
-DgYDVQQKDAdUZXN0IENBMRAwDgYDVQQDDAdUZXN0IENBMIICIjANBgkqhkiG9w0B
-AQEFAAOCAg8AMIICCgKCAgEAvk1N3IMWVqJIlMuFkD2XiPiEPk5m7ToriB0ThNyY
-IUKVayEoFOyU82ciycERJHVgo64BxQ3e4BqBakyarI4ssbiI6hm8onWzjCBPy5U+
-RQxK/oDoK3vn1uCQRKbdjkJvbbmbTVlWrpTGmNBflw+OlTGSswcWxc3q0KrKYmm0
-eGcvL6ZNy+ciTPXRyE7ccHR87yP+CIs8l4O4j5QavcIYH6PSHtMU6XUFIZGpj9vI
-6PbKu2MPK1+QRL+zevf5Q3l5tdjHavh0NDW8QcCa/te7qc7gQvYttFzYMuzvNqeZ
-OL3iCWJVKG5Atxo9JvSsb0IbDXqnGQrRqYoHwk64bT2Hs3G5pwBLSoO+HrKqfaS3
-c5KINGrfCVcfrKIHyA3l/RLIhlhzkxj1Mvq2sP8Jt0IfZNpXjBiXw6zH76Biozgq
-gdTNypOz3an1OkfQRcsXjjaI/EKLxcTAV5DQR2++OI6eFfalVjbdmWCvOBOXa3tN
-UtxACL/kNbjAegRzZTZyTy/uA1nj3E2FdDDGqUnxiNtXBVQ40s4xoi2w0sdWQ3ZL
-ntLQ3NhLJw8UCCUMMQZEwghAeyXGqS7GuAszoPDBzjkJyI456sR8E5mapjwwVbMz
-nCGfeEgNoRSMuAteJwS/nw2M9ApxgqYan+683cV2pIU8wGtkRzYxvRXMswKIBx83
-ksUCAwEAAaNgMF4wHQYDVR0OBBYEFOS5A19qy9nHzu0q5pXrpdT4vGXbMB8GA1Ud
-IwQYMBaAFOS5A19qy9nHzu0q5pXrpdT4vGXbMA8GA1UdEwEB/wQFMAMBAf8wCwYD
-VR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQBr3dLjF8MLJTGW92UejISaCLft
-jqyXonrHLi3snrC2rW6OkGD35Mk+ylpuYHSzCl258P5W8J9A9snRgzL6pqXw2ZPB
-GLjGyge4PKvzH25O8kCgAuvyNBPPDKMdhhMzaL1qsr8zveUIYxMtJMVZuzpYFD8u
-2/MZQ6yf8PVVsnEPlrjg2ByUEiSBNAnmqC3zFnR90Zv2F8jQyhCZyZf/57lGDS4c
-5ap8mFhwxY6gZbzv/LW8r13hT7QbGkgl6yildg1/+Ozn8RkRoYNcZ6r7Nl0Z6TL3
-Vs4vab0cuketxIdpzld5FW3b+DBjzpR1pdzGtnm3ultSBHD75vxBeKI3//K1Ar1G
-U8NAuWIKEEOirhsm23XBowmwEcbKD8AlHjfZVDGs1kWvhdu09RY1BHYt0YBIbirE
-g+F537+MUr5l934eQxIpOiHyJmiqNnfC4l9e4tUIKfX64yWoqu5davEIBI0x9mKe
-Ug8uofPCm6U78S6jANauze6X9r8T8bDm56y9yztQXVf1mZxTgoHRspX6wt89YQVJ
-VZzrWyRsMvPDGWevH809CHJaOFMjS23ffF5KML9Gzf/XShRQWCNkE85T55W8FgS0
-Kt0m9ZRPWEGulbsO85ETjssatI1xKKwRNOQIWdk625sci42PSgK/q8Avufe0rRbH
-398+r4PDI8gaMQKG4A==
------END CERTIFICATE-----
diff --git a/components/camel-milo/src/test/resources/cert/Makefile 
b/components/camel-milo/src/test/resources/cert/Makefile
new file mode 100644
index 0000000..b44c850
--- /dev/null
+++ b/components/camel-milo/src/test/resources/cert/Makefile
@@ -0,0 +1,16 @@
+.PHONY: clean all show
+
+all:
+       openssl req -batch -x509 -sha256 -nodes -days 36500 \
+               -subj '/C=XX/L=End of the universe/O=Milliways' \
+               -config cert.ini \
+               -newkey rsa:2048 -keyout privateKey.key -out certificate.crt
+       openssl pkcs12 -password pass:pwd1 -export -out cert.p12 -inkey 
privateKey.key -in certificate.crt
+       openssl x509 -outform der -in certificate.crt -out certificate.der
+
+show:
+       openssl x509 -in certificate.crt -text -noout
+
+clean:
+       @-rm privateKey.key certificate.crt cert.p12 certificate.der
+
diff --git a/components/camel-milo/src/test/resources/cert/cert.ini 
b/components/camel-milo/src/test/resources/cert/cert.ini
new file mode 100644
index 0000000..7eaaed2
--- /dev/null
+++ b/components/camel-milo/src/test/resources/cert/cert.ini
@@ -0,0 +1,13 @@
+[req]
+x509_extensions = v3_req
+distinguished_name = req_distinguished_name
+
+[req_distinguished_name]
+
+[v3_req]
+basicConstraints = CA:FALSE
+keyUsage = digitalSignature, keyEncipherment
+subjectAltName = @alt_names
+
+[alt_names]
+URI.1 = http://camel.apache.org/EclipseMilo/Client
diff --git a/components/camel-milo/src/test/resources/cert/cert.p12 
b/components/camel-milo/src/test/resources/cert/cert.p12
new file mode 100644
index 0000000..8a2eed9
Binary files /dev/null and 
b/components/camel-milo/src/test/resources/cert/cert.p12 differ
diff --git a/components/camel-milo/src/test/resources/cert/certificate.crt 
b/components/camel-milo/src/test/resources/cert/certificate.crt
new file mode 100644
index 0000000..8b7c784
--- /dev/null
+++ b/components/camel-milo/src/test/resources/cert/certificate.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDVDCCAjygAwIBAgIJAKvxBeV3q1AsMA0GCSqGSIb3DQEBCwUAMD8xCzAJBgNV
+BAYTAlhYMRwwGgYDVQQHExNFbmQgb2YgdGhlIHVuaXZlcnNlMRIwEAYDVQQKEwlN
+aWxsaXdheXMwIBcNMTYwNzIxMTMyODAwWhgPMjExNjA2MjcxMzI4MDBaMD8xCzAJ
+BgNVBAYTAlhYMRwwGgYDVQQHExNFbmQgb2YgdGhlIHVuaXZlcnNlMRIwEAYDVQQK
+EwlNaWxsaXdheXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDYISUG
+ggjH/3KuUHLjUvDWNomCDzMqTA4QrlK0cxt0VZq0DmzP1xEtAhXJ6eXVsBsfbvzW
+F/AK1otAP67wsGz52edbzchW0TVvKd3CAKBH8LFgycu7k6bYdc+0crgyxeM1NUmC
+x1nxbfTMWSC1CWOzjZXOVlqyUIHY8HJetPpJpS0GizAfa+eCHaRXOyC89dUX0cS8
+370NbcqfrYvbd8LOosHLYqJ/x7P7YIxOkw/wn5m2OAeSfItqfNCLbR2+oiCrLLv0
+MXQVCiiYfPLoEePFb288/AkgI/1go4Lsh6/vBnTU03r/YKM1QHVxygax3+I/9cXp
+wNmV8HyDNo5Lu98bAgMBAAGjUTBPMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgWgMDUG
+A1UdEQQuMCyGKmh0dHA6Ly9jYW1lbC5hcGFjaGUub3JnL0VjbGlwc2VNaWxvL0Ns
+aWVudDANBgkqhkiG9w0BAQsFAAOCAQEAWplx3EQyl69Xrn73v55sPa8mlBKMjjJ3
+FmloVkUoYO8k8xciPDRHSVaeKYwU3dO4NBwPnbo0JMZWEaYr9SsVWbLRsfqu3pGt
+ScHp7n1GB8gkstoX3cuqzVF0UQCkSsfUNXGCfQVQbQwJg8hBU77WTflDbcrGMbxf
+PgTkwOv8qfNjPawu4j05/9SKoauKoNVQ1nHS7D3tkzoPxh+0efOhrhOPXtB/C9yH
+QKIMFzsh0uLlzNZiMURjTZo/asZ9RdCplUzd3ciQDZk6QxW8DIrOfySUMuWU1UDa
+1/qA0w7xg+1azBRl3oiUwNxOmHHVeWqonhbvYlG+GG/MjQHcg62NHg==
+-----END CERTIFICATE-----
diff --git a/components/camel-milo/src/test/resources/cert/certificate.der 
b/components/camel-milo/src/test/resources/cert/certificate.der
new file mode 100644
index 0000000..37abde7
Binary files /dev/null and 
b/components/camel-milo/src/test/resources/cert/certificate.der differ
diff --git a/components/camel-milo/src/test/resources/cert/privateKey.key 
b/components/camel-milo/src/test/resources/cert/privateKey.key
new file mode 100644
index 0000000..5900120
--- /dev/null
+++ b/components/camel-milo/src/test/resources/cert/privateKey.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDYISUGggjH/3Ku
+UHLjUvDWNomCDzMqTA4QrlK0cxt0VZq0DmzP1xEtAhXJ6eXVsBsfbvzWF/AK1otA
+P67wsGz52edbzchW0TVvKd3CAKBH8LFgycu7k6bYdc+0crgyxeM1NUmCx1nxbfTM
+WSC1CWOzjZXOVlqyUIHY8HJetPpJpS0GizAfa+eCHaRXOyC89dUX0cS8370Nbcqf
+rYvbd8LOosHLYqJ/x7P7YIxOkw/wn5m2OAeSfItqfNCLbR2+oiCrLLv0MXQVCiiY
+fPLoEePFb288/AkgI/1go4Lsh6/vBnTU03r/YKM1QHVxygax3+I/9cXpwNmV8HyD
+No5Lu98bAgMBAAECggEBAJdMLJUvtmH7axan7qVATKRIrV5EsbasYzQ+NFtqMQ/x
+VUkyx+1/SuDNEt+0Q1ah33rTwV9Ghp2vru+dJSQM/VyytAlKNzK/Zb6Z+klzEsEJ
+t8JfwaVgKW5imrJhlJzGdtWqpflNAKPIK5RZ2FGjbw4k0XgOb5NgVGW/fPDblFK0
+ar1Yc/FLWOYFWFfNoZhni+ZH4U2KmEjZlkIL+d4KgewrjSPJ9w6XJijxMD5eDc5+
+r1ZfaSz5RNM/5LWokqLajCuxBxohRXldgF3Y3UtuQipeok1RPmQb0UcPSz7zndHF
+BV90c3o09v0/aqp2USlzCABIHO0l5Qru9m5wtvI+L/ECgYEA+TaweFBy6vGLa1jU
+hr8vaED880KNu6bIfHfmT580cG8ZXdz/+JHup+lERQmjuEX9Jc6QO2AUVsn1bZ8P
+oxs/4kNKL3cYZ/r66cBSSu0xihXsFAvDm4rrwSI5IAzOioMxBVs65sicpaceunHP
+l+c7Ma2cEUnlwYVuRAXhy1jjVhcCgYEA3gPR6q1lYgYsm8alOUzy/Eexp8PMbpgE
+t6c5eyT4Swau9XkNxp5R/tLCMvuZxwplZauChpE7O1TTiu88vrqRVVl4fZVkIlnx
+/xzzQFuAny/Qx+FOU18gNhFCRn4aAs5k+wdOncCIonz3IhMcusruseorBw57DLil
+TNlLZtQPZZ0CgYEAtUiEHDEhNyiX63GFv7MpUCQeHPJn2X4cTvaFEZxU8AjRIgdW
+KEI3oes8nx/A+ZXn7O2S264rfWqR3rkbDeIPmY6rU1XF6jWW+hzNf/WE2NbTkU1x
+cB8hGa/EcD0ArZ97NFNFyIVb9eBYqPWLNgudcqjAY48m05w1NsQ0mNBDJucCgYAP
+JWWRxAiRmmg6rF+jPBurmFyHXHU66kYQHWlvfEMwIyGWf46wCScA4nH7Nmz0RkJK
+oFvEQG4xCwVvigiz3liB4Ru2PZXaPhajV99EebmZopJ0wGsuhuPUrHLACmRN4rTC
+52m2m2b25t2ZRoKEP8nu+1G6JoPAh2xHhN9/AWKXhQKBgQDFmIUZwFmb3+oYgEN5
+QVmiwHgy9+AX+atZ76N3oajF42w3SFTLO9yQ5dlb9nBfwzpraZn2T9fAyiP0a9iU
+A9Y5MUFWlqMfgeOK/HEprcA7/Wth8ou3iu6Ojn85Iy2VqmqA4OYUYQTsS6izus4W
+Eel2uEuwhoIseSX1F0tqMlwxVg==
+-----END PRIVATE KEY-----
diff --git a/components/camel-milo/src/test/resources/keystore 
b/components/camel-milo/src/test/resources/keystore
deleted file mode 100644
index ef6d68f..0000000
Binary files a/components/camel-milo/src/test/resources/keystore and /dev/null 
differ
diff --git a/components/camel-milo/src/test/resources/openssl-ca.cnf 
b/components/camel-milo/src/test/resources/openssl-ca.cnf
deleted file mode 100644
index bd29e0e..0000000
--- a/components/camel-milo/src/test/resources/openssl-ca.cnf
+++ /dev/null
@@ -1,80 +0,0 @@
-HOME            = .
-RANDFILE        = $ENV::HOME/.rnd
-
-####################################################################
-[ ca ]
-default_ca    = CA_default      # The default ca section
-
-[ CA_default ]
-
-default_days     = 1000         # How long to certify for
-default_crl_days = 30           # How long before next CRL
-default_md       = sha256       # Use public key default MD
-preserve         = no           # Keep passed DN ordering
-
-x509_extensions = ca_extensions # The extensions to add to the cert
-
-email_in_dn     = no            # Don't concat the email in the DN
-copy_extensions = copy          # Required to copy SANs from CSR to cert
-
-base_dir      = .
-certificate   = $base_dir/ca/cacert.pem   # The CA certifcate
-private_key   = $base_dir/ca/cakey.pem    # The CA private key
-new_certs_dir = $base_dir/cert              # Location for new certs after 
signing
-database      = $base_dir/ca/index.txt    # Database index file
-serial        = $base_dir/ca/serial.txt   # The current serial number
-
-unique_subject = no  # Set to 'no' to allow creation of
-                     # several certificates with same subject.
-
-####################################################################
-[ req ]
-default_bits       = 4096
-default_keyfile    = ca/cakey.pem
-distinguished_name = ca_distinguished_name
-x509_extensions    = ca_extensions
-string_mask        = utf8only
-
-####################################################################
-[ ca_distinguished_name ]
-countryName         = Country Name (2 letter code)
-countryName_default = RH
-
-stateOrProvinceName         = State or Province Name (full name)
-stateOrProvinceName_default = RH
-
-localityName                = Locality Name (eg, city)
-localityName_default        = RH
-
-organizationName            = Organization Name (eg, company)
-organizationName_default    = Test CA
-
-commonName         = Common Name (e.g. server FQDN or YOUR name)
-commonName_default = Test CA
-
-####################################################################
-[ ca_extensions ]
-
-subjectKeyIdentifier   = hash
-authorityKeyIdentifier = keyid:always, issuer
-basicConstraints       = critical, CA:true
-keyUsage               = keyCertSign, cRLSign
-
-####################################################################
-[ signing_policy ]
-countryName            = optional
-stateOrProvinceName    = optional
-localityName           = optional
-organizationName       = optional
-organizationalUnitName = optional
-commonName             = supplied
-emailAddress           = optional
-
-####################################################################
-[ signing_req ]
-subjectKeyIdentifier   = hash
-authorityKeyIdentifier = keyid,issuer
-basicConstraints       = CA:FALSE
-keyUsage               = digitalSignature, keyEncipherment
-
-#openssl pkcs12 -export -in servercert.pem -inkey serverkey.pem -certfile 
cacert.pem -name "test" -out keystore.p12 -passout pass:test
diff --git a/components/camel-milo/src/test/resources/openssl-server.cnf 
b/components/camel-milo/src/test/resources/openssl-server.cnf
deleted file mode 100644
index dd3cd0e..0000000
--- a/components/camel-milo/src/test/resources/openssl-server.cnf
+++ /dev/null
@@ -1,39 +0,0 @@
-HOME            = .
-RANDFILE        = $ENV::HOME/.rnd
-
-####################################################################
-[ req ]
-default_bits       = 2048
-default_keyfile    = cert/serverkey.pem
-distinguished_name = server_distinguished_name
-req_extensions     = server_req_extensions
-string_mask        = utf8only
-
-####################################################################
-[ server_distinguished_name ]
-countryName         = Country Name (2 letter code)
-countryName_default = RH
-
-stateOrProvinceName         = State or Province Name (full name)
-stateOrProvinceName_default = RH
-
-localityName         = Locality Name (eg, city)
-localityName_default = RH
-
-commonName           = Common Name (e.g. server FQDN or YOUR name)
-commonName_default   = milo-test
-
-
-####################################################################
-[ server_req_extensions ]
-
-subjectKeyIdentifier = hash
-basicConstraints     = CA:FALSE
-keyUsage             = digitalSignature, keyEncipherment
-subjectAltName       = @alternate_names
-nsComment            = "OpenSSL Generated Certificate"
-
-####################################################################
-[ alternate_names ]
-
-URI.1  = http://camel.apache.org/EclipseMilo/Client
diff --git a/components/camel-milo/src/test/resources/run.sh 
b/components/camel-milo/src/test/resources/run.sh
deleted file mode 100755
index a6d1620..0000000
--- a/components/camel-milo/src/test/resources/run.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-# script which prepares all needed certificates and keystore
-# properties of certificates has to be confirmed
-# password to be filled in the last step has to be 'test'
-
-mkdir cert
-mkdir ca
-
-#generate ca certificate and key
-openssl req -x509 -config openssl-ca.cnf -newkey rsa:4096 -sha256 -nodes -out 
ca/cacert.pem -outform PEM
-
-#generate csr
-openssl req -config openssl-server.cnf -newkey rsa:2048 -sha256 -nodes -out 
cert/servercert.csr -outform PEM
-
-#sign
-touch ca/index.txt
-echo '01' > ca/serial.txt
-openssl ca -config openssl-ca.cnf -policy signing_policy -extensions 
signing_req -out cert/servercert.pem -infiles cert/servercert.csr
-
-#import into keystore
-openssl pkcs12 -export -in cert/servercert.pem -inkey cert/serverkey.pem 
-certfile ca/cacert.pem -name "test" -out keystore.p12 -passout pass:test
-keytool -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 
-destkeystore keystore -deststoretype JKS -storepass testtest
diff --git a/docs/components/modules/ROOT/pages/milo-client-component.adoc 
b/docs/components/modules/ROOT/pages/milo-client-component.adoc
index 3517f7e..634f914 100644
--- a/docs/components/modules/ROOT/pages/milo-client-component.adoc
+++ b/docs/components/modules/ROOT/pages/milo-client-component.adoc
@@ -11,9 +11,6 @@
 The Milo Client component provides access to OPC UA servers using the
 http://eclipse.org/milo[Eclipse Milo™] implementation.
 
-*Important*: To successfully use certificates for secured communication,
-JCE Jurisdiction Policy File Default has to be *Unlimited* (which is by 
default since jdk 9+).
-
 Maven users will need to add the following dependency to their `pom.xml`
 for this component:
 
@@ -56,13 +53,13 @@ The URI syntax of the endpoint is:
 
 [source]
 ------------------------
-milo-client:opc.tcp://[user:password@]host:port/path/to/service?node=RAW(nsu=urn:foo:bar;s=item-1)
+milo-client:tcp://[user:password@]host:port/path/to/service?node=RAW(nsu=urn:foo:bar;s=item-1)
 ------------------------
 
 If the server does not use a path, then it is possible to simply omit it:
 
 ------------------------
-milo-client:opc.tcp://[user:password@]host:port?node=RAW(nsu=urn:foo:bar;s=item-1)
+milo-client:tcp://[user:password@]host:port?node=RAW(nsu=urn:foo:bar;s=item-1)
 ------------------------
 
 If no user credentials are provided the client will switch to anonymous mode.
@@ -243,7 +240,7 @@ As the values generated by the syntax cannot be 
transparently encoded into a URI
 However Camel allows to wrap the actual value inside `RAW(…)`, which makes 
escaping unnecessary. For example:
 
 ------------------------
-milo-client:opc.tcp://user:password@localhost:12345?node=RAW(nsu=http://foo.bar;s=foo/bar)
+milo-client:tcp://user:password@localhost:12345?node=RAW(nsu=http://foo.bar;s=foo/bar)
 ------------------------
 
 === Method ID
diff --git a/docs/components/modules/ROOT/pages/milo-server-component.adoc 
b/docs/components/modules/ROOT/pages/milo-server-component.adoc
index 072675e..861c31c 100644
--- a/docs/components/modules/ROOT/pages/milo-server-component.adoc
+++ b/docs/components/modules/ROOT/pages/milo-server-component.adoc
@@ -31,7 +31,7 @@ Value write requests from OPC UA Client will trigger messages 
which are sent int
 
 
 // component options: START
-The OPC UA Server component supports 20 options, which are listed below.
+The OPC UA Server component supports 22 options, which are listed below.
 
 
 
@@ -40,10 +40,12 @@ The OPC UA Server component supports 20 options, which are 
listed below.
 | Name | Description | Default | Type
 | *namespaceUri* (common) | The URI of the namespace, defaults to 
urn:org:apache:camel |  | String
 | *applicationName* (common) | The application name |  | String
-| *path* (common) | The path to be appended to the end of the endpoint url. 
(doesn't need to start with '/') |  | String
 | *applicationUri* (common) | The application URI |  | String
 | *productUri* (common) | The product URI |  | String
 | *bindPort* (common) | The TCP port the server binds to |  | int
+| *strictEndpointUrlsEnabled* (common) | Set whether strict endpoint URLs are 
enforced | false | boolean
+| *serverName* (common) | Server name |  | String
+| *hostname* (common) | Server hostname |  | String
 | *securityPolicies* (common) | Security policies |  | Set
 | *securityPoliciesById* (common) | Security policies by URI or name |  | 
Collection
 | *userAuthenticationCredentials* (common) | Set user password combinations in 
the form of user1:pwd1,user2:pwd2 Usernames and passwords will be URL decoded | 
 | String
diff --git a/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide.adoc
index 4f75f8b..33abb55 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide.adoc
@@ -41,27 +41,6 @@ The `camel-irc` component has changed its endpoint syntax 
and removed option #ro
 irc:nick@host[:port]?[options]
 ----
 
-=== camel-milo
-
-The `camel-milo` client component has changed its endpoint syntax from 
`milo-client:tcp` to `milo-client:opc.tcp`.
-For example before
-
-[source,text]
-----
-milo-client:tcp://foo:bar@localhost:1234
-----
-
-Should be changed to
-----
-milo-client:opc.tcp://foo:bar@localhost:1234
-----
-
-The `camel-milo` server component requires Java 9 at runtime. 
-Property `strictEndpointUrlsEnabled` is no longer supported.
-Properties`hostName` and `serverName` are replaced by `path`.
-To successfully use certificates for secured communication, JCE Jurisdiction 
Policy File Default
-has to be *Unlimited* (which is by default since Java 9+).
-
 === camel-nats
 
 The `camel-nats` component has changed its endpoint syntax from `nats:servers` 
to `nats:topic`.
diff --git a/parent/pom.xml b/parent/pom.xml
index 1cb3e58..c86d053 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -164,8 +164,6 @@
         <derby-version>10.14.2.0</derby-version>
         <digitalocean-api-client-version>2.17</digitalocean-api-client-version>
         
<digitalocean-api-client-bundle-version>2.17_1</digitalocean-api-client-bundle-version>
-        <digitalpetri-fsm-client>0.2</digitalpetri-fsm-client>
-        <digitalpetri-netty-client>0.3</digitalpetri-netty-client>
         <directory-watcher-version>0.9.9</directory-watcher-version>
         <disruptor-version>3.4.2</disruptor-version>
         <dnsjava-version>2.1.9</dnsjava-version>
@@ -460,8 +458,7 @@
         <microprofile-config-version>1.3</microprofile-config-version>
         <microprofile-metrics-version>2.2.1</microprofile-metrics-version>
         <microprofile-health-version>2.1</microprofile-health-version>
-        <milo-version>0.3.7</milo-version>
-        <milo-guava-version>26.0-jre</milo-guava-version>
+        <milo-version>0.2.5</milo-version>
         <mimepull-version>1.9.12</mimepull-version>
         <mina-version>2.1.3</mina-version>
         <minidns-version>0.3.4</minidns-version>
diff --git a/platforms/karaf/features/src/main/resources/features.xml 
b/platforms/karaf/features/src/main/resources/features.xml
index ae3b5e9..a183476 100644
--- a/platforms/karaf/features/src/main/resources/features.xml
+++ b/platforms/karaf/features/src/main/resources/features.xml
@@ -1750,26 +1750,19 @@
     <bundle dependency='true'>mvn:org.jooq/jool/${jool-version}</bundle>
     <bundle 
dependency='true'>mvn:com.google.code.findbugs/jsr305/${google-findbugs-jsr305-version}</bundle>
     <bundle 
dependency='true'>mvn:com.google.code.findbugs/annotations/${google-findbugs-annotations2-version}</bundle>
-    <bundle 
dependency='true'>mvn:org.bouncycastle/bcprov-jdk15on/${bouncycastle-version}</bundle>
-    <bundle 
dependency='true'>mvn:org.bouncycastle/bcpkix-jdk15on/${bouncycastle-version}</bundle>
     
-    <bundle 
dependency='true'>mvn:org.bouncycastle/bcmail-jdk15on/${bouncycastle-version}</bundle>
    
-    <bundle 
dependency='true'>mvn:io.netty/netty-common/${netty-version}</bundle>
-    <bundle 
dependency='true'>mvn:io.netty/netty-buffer/${netty-version}</bundle>
-    <bundle 
dependency='true'>mvn:io.netty/netty-resolver/${netty-version}</bundle>
-    <bundle 
dependency='true'>mvn:io.netty/netty-transport/${netty-version}</bundle>    
-    <bundle 
dependency='true'>mvn:io.netty/netty-handler/${netty-version}</bundle>    
-    <bundle 
dependency='true'>mvn:io.netty/netty-codec/${netty-version}</bundle>
-    <bundle 
dependency='true'>mvn:io.netty/netty-codec-http/${netty-version}</bundle>
-    <bundle 
dependency='true'>wrap:mvn:com.digitalpetri.fsm/strict-machine/${digitalpetri-fsm-client}</bundle>
-    <bundle 
dependency='true'>wrap:mvn:com.digitalpetri.netty/netty-channel-fsm/${digitalpetri-netty-client}</bundle>
-    <bundle 
dependency='true'>mvn:com.google.guava/guava/${milo-guava-version}</bundle>
+    <bundle 
dependency='true'>mvn:io.netty/netty-common/${netty40-version}</bundle>
+    <bundle 
dependency='true'>mvn:io.netty/netty-buffer/${netty40-version}</bundle>
+    <bundle 
dependency='true'>mvn:io.netty/netty-handler/${netty40-version}</bundle>
+    <bundle 
dependency='true'>mvn:io.netty/netty-transport/${netty40-version}</bundle>
+    <bundle 
dependency='true'>mvn:io.netty/netty-codec/${netty40-version}</bundle>
+    <bundle 
dependency='true'>mvn:com.google.guava/guava/${google-guava-version}</bundle>
     <bundle 
dependency='true'>mvn:org.eclipse.milo/stack-core/${milo-version}</bundle>
     <bundle 
dependency='true'>mvn:org.eclipse.milo/stack-server/${milo-version}</bundle>
     <bundle 
dependency='true'>mvn:org.eclipse.milo/stack-client/${milo-version}</bundle>
     <bundle 
dependency='true'>mvn:org.eclipse.milo/sdk-core/${milo-version}</bundle>
-    <bundle 
dependency='true'>mvn:org.eclipse.milo/sdk-server/${milo-version}</bundle>    
-    <bundle 
dependency='true'>mvn:org.eclipse.milo/bsd-parser-core/${milo-version}</bundle>
+    <bundle 
dependency='true'>mvn:org.eclipse.milo/sdk-server/${milo-version}</bundle>
     <bundle 
dependency='true'>mvn:org.eclipse.milo/sdk-client/${milo-version}</bundle>
+    <bundle 
dependency='true'>mvn:org.eclipse.milo/bsd-parser-core/${milo-version}</bundle>
     <bundle 
dependency='true'>mvn:org.eclipse.milo/bsd-parser-gson/${milo-version}</bundle>
     <bundle>mvn:org.apache.camel/camel-milo/${project.version}</bundle>
   </feature>
diff --git 
a/tests/camel-itest-karaf/src/test/java/org/apache/camel/itest/karaf/CamelMiloTest.java
 
b/tests/camel-itest-karaf/src/test/java/org/apache/camel/itest/karaf/CamelMiloTest.java
index a66342c..60d881c 100644
--- 
a/tests/camel-itest-karaf/src/test/java/org/apache/camel/itest/karaf/CamelMiloTest.java
+++ 
b/tests/camel-itest-karaf/src/test/java/org/apache/camel/itest/karaf/CamelMiloTest.java
@@ -16,22 +16,12 @@
  */
 package org.apache.camel.itest.karaf;
 
-import org.junit.Assume;
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.junit.PaxExam;
 
 @RunWith(PaxExam.class)
 public class CamelMiloTest extends BaseKarafTest {
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        Assume.assumeTrue("Requires java 9+", isJavaVersionSatisfied(9));
-    }
-
     @Test
     public void testClient() throws Exception {
         testComponent("milo", "milo-client");
@@ -40,22 +30,4 @@ public class CamelMiloTest extends BaseKarafTest {
     public void testServer() throws Exception {
         testComponent("milo", "milo-server");
     }
-
-    /**
-     * Return true, if java version (defined by method 
getRequiredJavaVersion()) is satisfied.
-     * Works for java versions 9+
-     */
-    boolean isJavaVersionSatisfied(int requiredVersion) {
-        String version = System.getProperty("java.version");
-        if (!version.startsWith("1.")) {
-            int dot = version.indexOf(".");
-            if (dot != -1) {
-                version = version.substring(0, dot);
-            }
-            if (Integer.parseInt(version) >= requiredVersion) {
-                return true;
-            }
-        }
-        return false;
-    }
 }

Reply via email to