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

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


The following commit(s) were added to refs/heads/master by this push:
     new ae5c586  KNOX-2395 - Make Gateway Services Pluggable (#358)
ae5c586 is described below

commit ae5c586de678712dfa575121f6811ac7759c0514
Author: Sandor Molnar <[email protected]>
AuthorDate: Tue Jul 14 12:01:25 2020 +0200

    KNOX-2395 - Make Gateway Services Pluggable (#358)
---
 gateway-release/home/conf/gateway-site.xml         |   4 +
 gateway-server/pom.xml                             |   4 +
 .../org/apache/knox/gateway/GatewayMessages.java   |   6 +
 .../gateway/config/impl/GatewayConfigImpl.java     |   7 ++
 .../knox/gateway/services/CLIGatewayServices.java  |  57 ++-------
 .../gateway/services/DefaultGatewayServices.java   | 129 +++++----------------
 .../gateway/services/GatewayServiceFactory.java    |  61 ++++++++++
 .../services/factory/AbstractServiceFactory.java   | 114 ++++++++++++++++++
 .../services/factory/AliasServiceFactory.java      |  75 ++++++++++++
 .../ClusterConfigurationMonitorServiceFactory.java |  54 +++++++++
 .../services/factory/CryptoServiceFactory.java     |  54 +++++++++
 .../factory/HostMappingServiceFactory.java         |  48 ++++++++
 .../services/factory/KeystoreServiceFactory.java   |  53 +++++++++
 .../services/factory/MasterServiceFactory.java     |  62 ++++++++++
 .../services/factory/MetricsServiceFactory.java    |  48 ++++++++
 .../RemoteRegistryClientServiceFactory.java        |  67 +++++++++++
 .../services/factory/ServerInfoServiceFactory.java |  48 ++++++++
 .../factory/ServiceDefinitionRegistryFactory.java  |  48 ++++++++
 .../factory/ServiceRegistryServiceFactory.java     |  53 +++++++++
 .../services/factory/SslServiceFactory.java        |  54 +++++++++
 .../services/factory/TokenServiceFactory.java      |  54 +++++++++
 .../services/factory/TokenStateServiceFactory.java |  66 +++++++++++
 .../services/factory/TopologyServiceFactory.java   |  53 +++++++++
 .../security/impl/DefaultCryptoService.java        |  22 ++--
 .../security/impl/DefaultKeystoreService.java      |   3 +-
 .../services/security/impl/JettySSLService.java    |  30 ++---
 .../token/impl/DefaultTokenAuthorityService.java   |  18 +--
 ...org.apache.knox.gateway.services.ServiceFactory |  33 ++++++
 .../gateway/config/impl/GatewayConfigImplTest.java |  20 +++-
 .../apache/knox/gateway/services/TestService.java  |  38 ++++++
 .../services/factory/AliasServiceFactoryTest.java  |  74 ++++++++++++
 ...sterConfigurationMonitorServiceFactoryTest.java |  51 ++++++++
 .../services/factory/CryptoServiceFactoryTest.java |  49 ++++++++
 .../factory/HostMappingServiceFactoryTest.java     |  48 ++++++++
 .../factory/KeystoreServiceFactoryTest.java        |  48 ++++++++
 .../services/factory/MasterServiceFactoryTest.java |  57 +++++++++
 .../factory/MetricsServiceFactoryTest.java         |  48 ++++++++
 .../factory/ServerInfoServiceFactoryTest.java      |  48 ++++++++
 .../ServiceDefinitionRegistryFactoryTest.java      |  50 ++++++++
 .../services/factory/ServiceFactoryTest.java       | 115 ++++++++++++++++++
 .../services/factory/SslServiceFactoryTest.java    |  50 ++++++++
 .../services/factory/TokenServiceFactoryTest.java  |  49 ++++++++
 .../factory/TokenStateServiceFactoryTest.java      |  64 ++++++++++
 .../factory/TopologyServiceFactoryTest.java        |  49 ++++++++
 .../apache/knox/gateway/websockets/BadUrlTest.java |   2 +
 .../gateway/websockets/WebsocketEchoTestBase.java  |   1 +
 .../WebsocketMultipleConnectionTest.java           |   2 +
 .../apache/knox/gateway/config/GatewayConfig.java  |   5 +
 .../knox/gateway/services/ServiceFactory.java      |  31 +++++
 .../apache/knox/gateway/services/ServiceType.java  |   8 ++
 .../gateway/services/security/KeystoreService.java |   4 +-
 .../org/apache/knox/gateway/GatewayTestConfig.java |   5 +
 52 files changed, 2056 insertions(+), 185 deletions(-)

diff --git a/gateway-release/home/conf/gateway-site.xml 
b/gateway-release/home/conf/gateway-site.xml
index 2b214da..7ca8705 100644
--- a/gateway-release/home/conf/gateway-site.xml
+++ b/gateway-release/home/conf/gateway-site.xml
@@ -19,6 +19,10 @@ limitations under the License.
 <configuration>
 
     <property>
+        <name>gateway.service.alias.impl</name>
+        
<value>org.apache.knox.gateway.services.security.impl.RemoteAliasService</value>
+    </property>
+    <property>
         <name>gateway.port</name>
         <value>8443</value>
         <description>The HTTP port for the Gateway.</description>
diff --git a/gateway-server/pom.xml b/gateway-server/pom.xml
index 5afed31..142101e 100644
--- a/gateway-server/pom.xml
+++ b/gateway-server/pom.xml
@@ -71,6 +71,10 @@
         </dependency>
         <dependency>
             <groupId>org.apache.knox</groupId>
+            <artifactId>gateway-service-hashicorp-vault</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.knox</groupId>
             <artifactId>gateway-i18n</artifactId>
         </dependency>
         <dependency>
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java 
b/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java
index 18c3a4b..3c18484 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java
@@ -698,4 +698,10 @@ public interface GatewayMessages {
 
   @Message(level = MessageLevel.ERROR, text = "Error creating provider 
descriptor {0} from topology {1}, cause: {2}")
   void errorSavingDescriptorConfiguration(String providerPath, String 
topologyName, String message);
+
+  @Message(level = MessageLevel.ERROR, text = "No service found by type {0}")
+  void noServiceFound(String serviceType);
+
+  @Message(level = MessageLevel.INFO, text = "Using {0} implementation for 
{1}")
+  void usingServiceImplementation(String implementation, String serviceType);
 }
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
index d03deec..2968b44 100644
--- 
a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
@@ -97,6 +97,7 @@ public class GatewayConfigImpl extends Configuration 
implements GatewayConfig {
 
   private static final String[] GATEWAY_CONFIG_FILENAMES = 
{GATEWAY_CONFIG_FILE_PREFIX + "-default.xml", GATEWAY_CONFIG_FILE_PREFIX + 
"-site.xml"};
 
+  private static final String GATEWAY_SERVICE_PREFIX = 
GATEWAY_CONFIG_FILE_PREFIX + ".service.";
   public static final String HTTP_HOST = GATEWAY_CONFIG_FILE_PREFIX + ".host";
   public static final String HTTP_PORT = GATEWAY_CONFIG_FILE_PREFIX + ".port";
   public static final String HTTP_PATH = GATEWAY_CONFIG_FILE_PREFIX + ".path";
@@ -1165,4 +1166,10 @@ public class GatewayConfigImpl extends Configuration 
implements GatewayConfig {
     return getBoolean(KNOX_TOKEN_PERMISSIVE_VALIDATION_ENABLED,
         KNOX_TOKEN_PERMISSIVE_VALIDATION_ENABLED_DEFAULT);
   }
+
+  @Override
+  public String getServiceParameter(String service, String parameter) {
+    return get(GATEWAY_SERVICE_PREFIX + service + "." + parameter, "");
+  }
+
 }
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/CLIGatewayServices.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/CLIGatewayServices.java
index 1223be1..4fdbf55 100644
--- 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/CLIGatewayServices.java
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/CLIGatewayServices.java
@@ -17,44 +17,28 @@
  */
 package org.apache.knox.gateway.services;
 
+import java.util.List;
+import java.util.Map;
+
 import org.apache.knox.gateway.config.GatewayConfig;
 import org.apache.knox.gateway.deploy.DeploymentContext;
 import org.apache.knox.gateway.descriptor.FilterParamDescriptor;
 import org.apache.knox.gateway.descriptor.ResourceDescriptor;
-import 
org.apache.knox.gateway.service.config.remote.RemoteConfigurationRegistryClientServiceFactory;
-import 
org.apache.knox.gateway.services.config.client.RemoteConfigurationRegistryClientService;
-import org.apache.knox.gateway.services.security.impl.RemoteAliasService;
-import org.apache.knox.gateway.services.topology.impl.DefaultTopologyService;
-import org.apache.knox.gateway.services.security.impl.DefaultAliasService;
-import org.apache.knox.gateway.services.security.impl.DefaultCryptoService;
-import org.apache.knox.gateway.services.security.impl.DefaultKeystoreService;
 import org.apache.knox.gateway.services.security.impl.CLIMasterService;
 import org.apache.knox.gateway.topology.Provider;
 
-import java.util.List;
-import java.util.Map;
-
 public class CLIGatewayServices extends AbstractGatewayServices {
 
+  private final GatewayServiceFactory gatewayServiceFactory = new 
GatewayServiceFactory();
+
   public CLIGatewayServices() {
     super("Services", "GatewayServices");
   }
 
   @Override
   public void init(GatewayConfig config, Map<String,String> options) throws 
ServiceLifecycleException {
-    CLIMasterService ms = new CLIMasterService();
-    ms.init(config, options);
-    addService(ServiceType.MASTER_SERVICE, ms);
-
-    DefaultKeystoreService ks = new DefaultKeystoreService();
-    ks.setMasterService(ms);
-    ks.init(config, options);
-    addService(ServiceType.KEYSTORE_SERVICE, ks);
-
-    DefaultAliasService defaultAlias = new DefaultAliasService();
-    defaultAlias.setKeystoreService(ks);
-    defaultAlias.setMasterService(ms);
-    defaultAlias.init(config, options);
+    addService(ServiceType.MASTER_SERVICE, gatewayServiceFactory.create(this, 
ServiceType.MASTER_SERVICE, config, options, CLIMasterService.class.getName()));
+    addService(ServiceType.KEYSTORE_SERVICE, 
gatewayServiceFactory.create(this, ServiceType.KEYSTORE_SERVICE, config, 
options));
 
     /*
     Doesn't make sense for this to be set to the remote alias service since 
the impl could
@@ -62,32 +46,13 @@ public class CLIGatewayServices extends 
AbstractGatewayServices {
     IE: If ZK digest auth and using ZK remote alias service, then wouldn't be 
able to connect
     to ZK anyway due to the circular dependency.
      */
-    final RemoteConfigurationRegistryClientService registryClientService =
-        RemoteConfigurationRegistryClientServiceFactory.newInstance(config);
-    registryClientService.setAliasService(defaultAlias);
-    registryClientService.init(config, options);
-    addService(ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE, 
registryClientService);
+    addService(ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE, 
gatewayServiceFactory.create(this, ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE, 
config, options));
 
+    addService(ServiceType.ALIAS_SERVICE, gatewayServiceFactory.create(this, 
ServiceType.ALIAS_SERVICE, config, options));
 
-    /* create an instance so that it can be passed to other services */
-    final RemoteAliasService alias = new RemoteAliasService(defaultAlias, ms);
-    /*
-     * Setup and initialize remote Alias Service.
-     * NOTE: registryClientService.init() needs to
-     * be called before alias.start();
-     */
-    alias.init(config, options);
-    addService(ServiceType.ALIAS_SERVICE, alias);
-
-    DefaultCryptoService crypto = new DefaultCryptoService();
-    crypto.setKeystoreService(ks);
-    crypto.setAliasService(alias);
-    crypto.init(config, options);
-    addService(ServiceType.CRYPTO_SERVICE, crypto);
+    addService(ServiceType.CRYPTO_SERVICE, gatewayServiceFactory.create(this, 
ServiceType.CRYPTO_SERVICE, config, options));
 
-    DefaultTopologyService tops = new DefaultTopologyService();
-    tops.init(  config, options  );
-    addService(ServiceType.TOPOLOGY_SERVICE, tops);
+    addService(ServiceType.TOPOLOGY_SERVICE, 
gatewayServiceFactory.create(this, ServiceType.TOPOLOGY_SERVICE, config, 
options));
   }
 
   @Override
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/DefaultGatewayServices.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/DefaultGatewayServices.java
index b120dec..0517763 100644
--- 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/DefaultGatewayServices.java
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/DefaultGatewayServices.java
@@ -17,37 +17,22 @@
  */
 package org.apache.knox.gateway.services;
 
+import java.util.List;
+import java.util.Map;
+
 import org.apache.knox.gateway.GatewayMessages;
 import org.apache.knox.gateway.config.GatewayConfig;
 import org.apache.knox.gateway.deploy.DeploymentContext;
 import org.apache.knox.gateway.descriptor.FilterParamDescriptor;
 import org.apache.knox.gateway.descriptor.ResourceDescriptor;
 import org.apache.knox.gateway.i18n.messages.MessagesFactory;
-import 
org.apache.knox.gateway.service.config.remote.RemoteConfigurationRegistryClientServiceFactory;
-import 
org.apache.knox.gateway.services.config.client.RemoteConfigurationRegistryClientService;
-import 
org.apache.knox.gateway.services.registry.impl.DefaultServiceDefinitionRegistry;
-import org.apache.knox.gateway.services.metrics.impl.DefaultMetricsService;
 import org.apache.knox.gateway.services.security.KeystoreService;
-import org.apache.knox.gateway.services.security.impl.RemoteAliasService;
-import org.apache.knox.gateway.services.token.impl.AliasBasedTokenStateService;
-import 
org.apache.knox.gateway.services.topology.impl.DefaultClusterConfigurationMonitorService;
-import org.apache.knox.gateway.services.topology.impl.DefaultTopologyService;
-import org.apache.knox.gateway.services.hostmap.impl.DefaultHostMapperService;
-import 
org.apache.knox.gateway.services.registry.impl.DefaultServiceRegistryService;
 import org.apache.knox.gateway.services.security.KeystoreServiceException;
-import org.apache.knox.gateway.services.security.impl.DefaultAliasService;
-import org.apache.knox.gateway.services.security.impl.DefaultCryptoService;
-import org.apache.knox.gateway.services.security.impl.DefaultKeystoreService;
-import org.apache.knox.gateway.services.security.impl.DefaultMasterService;
-import org.apache.knox.gateway.services.security.impl.JettySSLService;
-import 
org.apache.knox.gateway.services.token.impl.DefaultTokenAuthorityService;
 import org.apache.knox.gateway.topology.Provider;
 
-import java.util.List;
-import java.util.Map;
-
 public class DefaultGatewayServices extends AbstractGatewayServices {
   private static GatewayMessages log = MessagesFactory.get( 
GatewayMessages.class );
+  private final GatewayServiceFactory gatewayServiceFactory = new 
GatewayServiceFactory();
 
   public DefaultGatewayServices() {
     super("Services", "GatewayServices");
@@ -55,19 +40,9 @@ public class DefaultGatewayServices extends 
AbstractGatewayServices {
 
   @Override
   public void init(GatewayConfig config, Map<String,String> options) throws 
ServiceLifecycleException {
-    DefaultMasterService ms = new DefaultMasterService();
-    ms.init(config, options);
-    addService(ServiceType.MASTER_SERVICE, ms);
-
-    DefaultKeystoreService ks = new DefaultKeystoreService();
-    ks.setMasterService(ms);
-    ks.init(config, options);
-    addService(ServiceType.KEYSTORE_SERVICE, ks);
-
-    final DefaultAliasService defaultAlias = new DefaultAliasService();
-    defaultAlias.setKeystoreService(ks);
-    defaultAlias.setMasterService(ms);
-    defaultAlias.init(config, options);
+    //order is important: different service factory implementations may use 
already added services
+    addService(ServiceType.MASTER_SERVICE, gatewayServiceFactory.create(this, 
ServiceType.MASTER_SERVICE, config, options));
+    addService(ServiceType.KEYSTORE_SERVICE, 
gatewayServiceFactory.create(this, ServiceType.KEYSTORE_SERVICE, config, 
options));
 
     /*
     Doesn't make sense for this to be set to the remote alias service since 
the impl could
@@ -75,80 +50,34 @@ public class DefaultGatewayServices extends 
AbstractGatewayServices {
     IE: If ZK digest auth and using ZK remote alias service, then wouldn't be 
able to connect
     to ZK anyway due to the circular dependency.
      */
-    final RemoteConfigurationRegistryClientService registryClientService =
-        RemoteConfigurationRegistryClientServiceFactory.newInstance(config);
-    registryClientService.setAliasService(defaultAlias);
-    registryClientService.init(config, options);
-    addService(ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE, 
registryClientService);
+    addService(ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE, 
gatewayServiceFactory.create(this, ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE, 
config, options));
 
+    addService(ServiceType.ALIAS_SERVICE, gatewayServiceFactory.create(this, 
ServiceType.ALIAS_SERVICE, config, options));
 
-    /* create an instance so that it can be passed to other services */
-    final RemoteAliasService alias = new RemoteAliasService(defaultAlias, ms);
-    /*
-     * Setup and initialize remote Alias Service.
-     * NOTE: registryClientService.init() needs to
-     * be called before alias.start();
-     */
-    alias.init(config, options);
-    addService(ServiceType.ALIAS_SERVICE, alias);
+    addService(ServiceType.CRYPTO_SERVICE, gatewayServiceFactory.create(this, 
ServiceType.CRYPTO_SERVICE, config, options));
 
-    DefaultCryptoService crypto = new DefaultCryptoService();
-    crypto.setKeystoreService(ks);
-    crypto.setAliasService(alias);
-    crypto.init(config, options);
-    addService(ServiceType.CRYPTO_SERVICE, crypto);
-
-    JettySSLService ssl = new JettySSLService();
-    ssl.setAliasService(alias);
-    ssl.setKeystoreService(ks);
-    ssl.init(config, options);
-    addService(ServiceType.SSL_SERVICE, ssl);
+    addService(ServiceType.SSL_SERVICE, gatewayServiceFactory.create(this, 
ServiceType.SSL_SERVICE, config, options));
 
     // The DefaultTokenAuthorityService needs to be initialized after the 
JettySSLService to ensure
     // that the signing keystore is available for it.
-    DefaultTokenAuthorityService ts = new DefaultTokenAuthorityService();
-    ts.setAliasService(alias);
-    ts.setKeystoreService(ks);
-    ts.init(config, options);
-    // prolly should not allow the token service to be looked up?
-    addService(ServiceType.TOKEN_SERVICE, ts);
-
-    AliasBasedTokenStateService tss = new AliasBasedTokenStateService();
-    tss.setAliasService(alias);
-    tss.init(config, options);
-    addService(ServiceType.TOKEN_STATE_SERVICE, tss);
-
-    DefaultServiceRegistryService sr = new DefaultServiceRegistryService();
-    sr.setCryptoService( crypto );
-    sr.init( config, options );
-    addService(ServiceType.SERVICE_REGISTRY_SERVICE, sr);
-
-    DefaultHostMapperService hm = new DefaultHostMapperService();
-    hm.init( config, options );
-    addService(ServiceType.HOST_MAPPING_SERVICE, hm );
-
-    DefaultServerInfoService sis = new DefaultServerInfoService();
-    sis.init( config, options );
-    addService(ServiceType.SERVER_INFO_SERVICE, sis );
-
-    DefaultClusterConfigurationMonitorService ccs = new 
DefaultClusterConfigurationMonitorService();
-    ccs.setAliasService(alias);
-    ccs.setKeystoreService(ks);
-    ccs.init(config, options);
-    addService(ServiceType.CLUSTER_CONFIGURATION_MONITOR_SERVICE, ccs);
-
-    DefaultTopologyService tops = new DefaultTopologyService();
-    tops.setAliasService(alias);
-    tops.init(  config, options  );
-    addService(ServiceType.TOPOLOGY_SERVICE, tops  );
-
-    DefaultServiceDefinitionRegistry sdr = new 
DefaultServiceDefinitionRegistry();
-    sdr.init( config, options );
-    addService(ServiceType.SERVICE_DEFINITION_REGISTRY, sdr );
-
-    DefaultMetricsService metricsService = new DefaultMetricsService();
-    metricsService.init( config, options );
-    addService(ServiceType.METRICS_SERVICE, metricsService );
+    // probably should not allow the token service to be looked up?
+    addService(ServiceType.TOKEN_SERVICE, gatewayServiceFactory.create(this, 
ServiceType.TOKEN_SERVICE, config, options));
+
+    addService(ServiceType.TOKEN_STATE_SERVICE, 
gatewayServiceFactory.create(this, ServiceType.TOKEN_STATE_SERVICE, config, 
options));
+
+    addService(ServiceType.SERVICE_REGISTRY_SERVICE, 
gatewayServiceFactory.create(this, ServiceType.SERVICE_REGISTRY_SERVICE, 
config, options));
+
+    addService(ServiceType.HOST_MAPPING_SERVICE, 
gatewayServiceFactory.create(this, ServiceType.HOST_MAPPING_SERVICE, config, 
options));
+
+    addService(ServiceType.SERVER_INFO_SERVICE, 
gatewayServiceFactory.create(this, ServiceType.SERVER_INFO_SERVICE, config, 
options));
+
+    addService(ServiceType.CLUSTER_CONFIGURATION_MONITOR_SERVICE, 
gatewayServiceFactory.create(this, 
ServiceType.CLUSTER_CONFIGURATION_MONITOR_SERVICE, config, options));
+
+    addService(ServiceType.TOPOLOGY_SERVICE, 
gatewayServiceFactory.create(this, ServiceType.TOPOLOGY_SERVICE, config, 
options));
+
+    addService(ServiceType.SERVICE_DEFINITION_REGISTRY, 
gatewayServiceFactory.create(this, ServiceType.SERVICE_DEFINITION_REGISTRY, 
config, options));
+
+    addService(ServiceType.METRICS_SERVICE, gatewayServiceFactory.create(this, 
ServiceType.METRICS_SERVICE, config, options));
   }
 
   @Override
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/GatewayServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/GatewayServiceFactory.java
new file mode 100644
index 0000000..3e43bc2
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/GatewayServiceFactory.java
@@ -0,0 +1,61 @@
+/*
+ * 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.knox.gateway.services;
+
+import java.util.Map;
+import java.util.ServiceLoader;
+
+import org.apache.knox.gateway.GatewayMessages;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+
+public class GatewayServiceFactory implements ServiceFactory {
+  private static final GatewayMessages LOG = 
MessagesFactory.get(GatewayMessages.class);
+  private ServiceLoader<ServiceFactory> serviceFactories;
+
+  @Override
+  public Service create(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options) throws 
ServiceLifecycleException {
+    return create(gatewayServices, serviceType, gatewayConfig, options, null);
+  }
+
+  @Override
+  public Service create(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    for (ServiceFactory serviceFactory : getServiceFactories()) {
+      service = implementation == null ? 
serviceFactory.create(gatewayServices, serviceType, gatewayConfig, options)
+          : serviceFactory.create(gatewayServices, serviceType, gatewayConfig, 
options, implementation);
+      if (service != null) {
+        break;
+      }
+    }
+    if (service != null) {
+      service.init(gatewayConfig, options);
+    } else {
+      LOG.noServiceFound(serviceType.getServiceTypeName());
+    }
+    return service;
+  }
+
+  private ServiceLoader<ServiceFactory> getServiceFactories() {
+    if (serviceFactories == null) {
+      serviceFactories = ServiceLoader.load(ServiceFactory.class);
+    }
+    return serviceFactories;
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AbstractServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AbstractServiceFactory.java
new file mode 100644
index 0000000..ab02ec0
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AbstractServiceFactory.java
@@ -0,0 +1,114 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.knox.gateway.GatewayMessages;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceFactory;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.KeystoreService;
+import org.apache.knox.gateway.services.security.MasterService;
+
+public abstract class AbstractServiceFactory implements ServiceFactory {
+
+  private static final GatewayMessages LOG = 
MessagesFactory.get(GatewayMessages.class);
+  private static final String IMPLEMENTATION_PARAM_NAME = "impl";
+  private static final String EMPTY_DEFAULT_IMPLEMENTATION = "";
+
+  @Override
+  public Service create(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options) throws 
ServiceLifecycleException {
+    return create(gatewayServices, serviceType, gatewayConfig, options, 
getImplementation(gatewayConfig));
+  }
+
+  @Override
+  public Service create(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (getServiceType() == serviceType) {
+      service = createService(gatewayServices, serviceType, gatewayConfig, 
options, implementation);
+      if (service == null && StringUtils.isNotBlank(implementation)) {
+        // no known service implementation created, try to create the custom 
one
+        try {
+          service = 
Service.class.cast(Class.forName(implementation).newInstance());
+          logServiceUsage(implementation, serviceType);
+        } catch (InstantiationException | IllegalAccessException | 
ClassNotFoundException e) {
+          throw new ServiceLifecycleException("Errror while instantiating " + 
serviceType.getShortName() + " service implementation " + implementation, e);
+        }
+      }
+    }
+    return service;
+  }
+
+  protected String getImplementation(GatewayConfig gatewayConfig) {
+    return gatewayConfig.getServiceParameter(getServiceType().getShortName(), 
IMPLEMENTATION_PARAM_NAME);
+  }
+
+  protected boolean matchesImplementation(String implementation, Class<? 
extends Object> clazz) {
+    return matchesImplementation(implementation, clazz, false);
+  }
+
+  protected boolean matchesImplementation(String implementation, Class<? 
extends Object> clazz, boolean acceptEmptyImplementation) {
+    boolean match = clazz.getName().equals(implementation);
+    if (!match && acceptEmptyImplementation) {
+      match = isEmptyDefaultImplementation(implementation);
+    }
+    return match;
+  }
+
+  private boolean isEmptyDefaultImplementation(String implementation) {
+    return EMPTY_DEFAULT_IMPLEMENTATION.equals(implementation);
+  }
+
+  protected boolean shouldCreateService(String implementation) {
+    return implementation == null || 
isEmptyDefaultImplementation(implementation) || 
getKnownImplementations().contains(implementation);
+  }
+
+  protected MasterService getMasterService(GatewayServices gatewayServices) {
+    return gatewayServices.getService(ServiceType.MASTER_SERVICE);
+  }
+
+  protected KeystoreService getKeystoreService(GatewayServices 
gatewayServices) {
+    return gatewayServices.getService(ServiceType.KEYSTORE_SERVICE);
+  }
+
+  protected AliasService getAliasService(GatewayServices gatewayServices) {
+    return gatewayServices.getService(ServiceType.ALIAS_SERVICE);
+  }
+
+  protected void logServiceUsage(String implementation, ServiceType 
serviceType) {
+    LOG.usingServiceImplementation("".equals(implementation) ? "default" : 
implementation, serviceType.getServiceTypeName());
+  }
+
+  // abstract methods
+
+  protected abstract Service createService(GatewayServices gatewayServices, 
ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> 
options,
+      String implementation) throws ServiceLifecycleException;
+
+  protected abstract ServiceType getServiceType();
+
+  protected abstract Collection<String> getKnownImplementations();
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AliasServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AliasServiceFactory.java
new file mode 100644
index 0000000..d3e3227
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AliasServiceFactory.java
@@ -0,0 +1,75 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableList;
+
+import java.util.Collection;
+import java.util.Map;
+
+import 
org.apache.knox.gateway.backend.hashicorp.vault.HashicorpVaultAliasService;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.impl.DefaultAliasService;
+import org.apache.knox.gateway.services.security.impl.RemoteAliasService;
+import 
org.apache.knox.gateway.services.security.impl.ZookeeperRemoteAliasService;
+import 
org.apache.knox.gateway.services.security.impl.ZookeeperRemoteAliasServiceProvider;
+
+public class AliasServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      final AliasService defaultAliasService = new DefaultAliasService();
+      ((DefaultAliasService) 
defaultAliasService).setMasterService(getMasterService(gatewayServices));
+      ((DefaultAliasService) 
defaultAliasService).setKeystoreService(getKeystoreService(gatewayServices));
+      defaultAliasService.init(gatewayConfig, options); // invoking init on 
DefaultAliasService twice is ok (in case implementation is set to 'default')
+
+      if (matchesImplementation(implementation, DefaultAliasService.class, 
true)) {
+        service = defaultAliasService;
+      } else if (matchesImplementation(implementation, 
HashicorpVaultAliasService.class)) {
+        service = new HashicorpVaultAliasService(defaultAliasService);
+      } else if (matchesImplementation(implementation, 
RemoteAliasService.class)) {
+        service = new RemoteAliasService(defaultAliasService, 
getMasterService(gatewayServices));
+      } else if (matchesImplementation(implementation, 
ZookeeperRemoteAliasService.class)) {
+        service = new 
ZookeeperRemoteAliasServiceProvider().newInstance(defaultAliasService, 
getMasterService(gatewayServices));
+      }
+
+      logServiceUsage(implementation, serviceType);
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.ALIAS_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return unmodifiableList(
+        asList(DefaultAliasService.class.getName(), 
HashicorpVaultAliasService.class.getName(), RemoteAliasService.class.getName(), 
ZookeeperRemoteAliasService.class.getName()));
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ClusterConfigurationMonitorServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ClusterConfigurationMonitorServiceFactory.java
new file mode 100644
index 0000000..14fe584
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ClusterConfigurationMonitorServiceFactory.java
@@ -0,0 +1,54 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import 
org.apache.knox.gateway.services.topology.impl.DefaultClusterConfigurationMonitorService;
+
+public class ClusterConfigurationMonitorServiceFactory extends 
AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = new DefaultClusterConfigurationMonitorService();
+      ((DefaultClusterConfigurationMonitorService) 
service).setAliasService(getAliasService(gatewayServices));
+      ((DefaultClusterConfigurationMonitorService) 
service).setKeystoreService(getKeystoreService(gatewayServices));
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.CLUSTER_CONFIGURATION_MONITOR_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return 
Collections.singleton(DefaultClusterConfigurationMonitorService.class.getName());
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/CryptoServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/CryptoServiceFactory.java
new file mode 100644
index 0000000..59daca1
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/CryptoServiceFactory.java
@@ -0,0 +1,54 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.impl.DefaultCryptoService;
+
+public class CryptoServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = new DefaultCryptoService();
+      ((DefaultCryptoService) 
service).setKeystoreService(getKeystoreService(gatewayServices));
+      ((DefaultCryptoService) 
service).setAliasService(getAliasService(gatewayServices));
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.CRYPTO_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultCryptoService.class.getName());
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/HostMappingServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/HostMappingServiceFactory.java
new file mode 100644
index 0000000..549abd2
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/HostMappingServiceFactory.java
@@ -0,0 +1,48 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.hostmap.impl.DefaultHostMapperService;
+
+public class HostMappingServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    return shouldCreateService(implementation) ? new 
DefaultHostMapperService() : null;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.HOST_MAPPING_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultHostMapperService.class.getName());
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/KeystoreServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/KeystoreServiceFactory.java
new file mode 100644
index 0000000..ee83c22
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/KeystoreServiceFactory.java
@@ -0,0 +1,53 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.impl.DefaultKeystoreService;
+
+public class KeystoreServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = new DefaultKeystoreService();
+      ((DefaultKeystoreService) 
service).setMasterService(getMasterService(gatewayServices));
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.KEYSTORE_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultKeystoreService.class.getName());
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/MasterServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/MasterServiceFactory.java
new file mode 100644
index 0000000..4b7d167
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/MasterServiceFactory.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableList;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.impl.CLIMasterService;
+import org.apache.knox.gateway.services.security.impl.DefaultMasterService;
+
+public class MasterServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      if (matchesImplementation(implementation, DefaultMasterService.class, 
true)) {
+        service = new DefaultMasterService();
+      } else if (matchesImplementation(implementation, 
CLIMasterService.class)) {
+        service = new CLIMasterService();
+      }
+
+      logServiceUsage(implementation, serviceType);
+    }
+
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.MASTER_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return unmodifiableList(asList(DefaultMasterService.class.getName(), 
CLIMasterService.class.getName()));
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/MetricsServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/MetricsServiceFactory.java
new file mode 100644
index 0000000..af200e1
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/MetricsServiceFactory.java
@@ -0,0 +1,48 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.metrics.impl.DefaultMetricsService;
+
+public class MetricsServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    return shouldCreateService(implementation) ? new DefaultMetricsService() : 
null;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.METRICS_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultMetricsService.class.getName());
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/RemoteRegistryClientServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/RemoteRegistryClientServiceFactory.java
new file mode 100644
index 0000000..1ae7fe8
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/RemoteRegistryClientServiceFactory.java
@@ -0,0 +1,67 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import 
org.apache.knox.gateway.service.config.remote.RemoteConfigurationRegistryClientServiceFactory;
+import org.apache.knox.gateway.service.config.remote.zk.ZooKeeperClientService;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import 
org.apache.knox.gateway.services.config.client.RemoteConfigurationRegistryClientService;
+import org.apache.knox.gateway.services.security.AliasService;
+
+// There are two implementations of 'RemoteConfigurationRegistryClientService':
+// - LocalFileSystemRemoteConfigurationRegistryClientService
+// - CuratorClientService
+// However, the first one - local - is for test-only purposes
+public class RemoteRegistryClientServiceFactory extends AbstractServiceFactory 
{
+
+  private final AliasServiceFactory aliasServiceFactory = new 
AliasServiceFactory();
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = 
RemoteConfigurationRegistryClientServiceFactory.newInstance(gatewayConfig);
+      // it should be the 'default' alias service
+      final AliasService localAliasService = (AliasService) 
aliasServiceFactory.create(gatewayServices, ServiceType.ALIAS_SERVICE, 
gatewayConfig, options, "");
+      localAliasService.init(gatewayConfig, options);
+      ((RemoteConfigurationRegistryClientService) 
service).setAliasService(localAliasService);
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(ZooKeeperClientService.class.getName());
+  }
+
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServerInfoServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServerInfoServiceFactory.java
new file mode 100644
index 0000000..b9605a0
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServerInfoServiceFactory.java
@@ -0,0 +1,48 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.DefaultServerInfoService;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+
+public class ServerInfoServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    return shouldCreateService(implementation) ? new 
DefaultServerInfoService() : null;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.SERVER_INFO_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultServerInfoService.class.getName());
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServiceDefinitionRegistryFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServiceDefinitionRegistryFactory.java
new file mode 100644
index 0000000..7961f07
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServiceDefinitionRegistryFactory.java
@@ -0,0 +1,48 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import 
org.apache.knox.gateway.services.registry.impl.DefaultServiceDefinitionRegistry;
+
+public class ServiceDefinitionRegistryFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    return shouldCreateService(implementation) ? new 
DefaultServiceDefinitionRegistry() : null;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.SERVICE_DEFINITION_REGISTRY;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return 
Collections.singleton(DefaultServiceDefinitionRegistry.class.getName());
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServiceRegistryServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServiceRegistryServiceFactory.java
new file mode 100644
index 0000000..f1be4e3
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServiceRegistryServiceFactory.java
@@ -0,0 +1,53 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import 
org.apache.knox.gateway.services.registry.impl.DefaultServiceRegistryService;
+
+public class ServiceRegistryServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = new DefaultServiceRegistryService();
+      ((DefaultServiceRegistryService) 
service).setCryptoService(gatewayServices.getService(ServiceType.CRYPTO_SERVICE));
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.SERVICE_REGISTRY_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return 
Collections.singleton(DefaultServiceRegistryService.class.getName());
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/SslServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/SslServiceFactory.java
new file mode 100644
index 0000000..f1792f0
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/SslServiceFactory.java
@@ -0,0 +1,54 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.impl.JettySSLService;
+
+public class SslServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = new JettySSLService();
+      ((JettySSLService) 
service).setKeystoreService(getKeystoreService(gatewayServices));
+      ((JettySSLService) 
service).setAliasService(getAliasService(gatewayServices));
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.SSL_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(JettySSLService.class.getName());
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TokenServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TokenServiceFactory.java
new file mode 100644
index 0000000..f03deeb
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TokenServiceFactory.java
@@ -0,0 +1,54 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import 
org.apache.knox.gateway.services.token.impl.DefaultTokenAuthorityService;
+
+public class TokenServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = new DefaultTokenAuthorityService();
+      ((DefaultTokenAuthorityService) 
service).setKeystoreService(getKeystoreService(gatewayServices));
+      ((DefaultTokenAuthorityService) 
service).setAliasService(getAliasService(gatewayServices));
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.TOKEN_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultTokenAuthorityService.class.getName());
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TokenStateServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TokenStateServiceFactory.java
new file mode 100644
index 0000000..800fcb2
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TokenStateServiceFactory.java
@@ -0,0 +1,66 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableList;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.token.impl.AliasBasedTokenStateService;
+import org.apache.knox.gateway.services.token.impl.DefaultTokenStateService;
+import 
org.apache.knox.gateway.services.token.impl.JournalBasedTokenStateService;
+
+public class TokenStateServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      if (matchesImplementation(implementation, 
DefaultTokenStateService.class, true)) {
+        service = new DefaultTokenStateService();
+      } else if (matchesImplementation(implementation, 
AliasBasedTokenStateService.class)) {
+        service = new AliasBasedTokenStateService();
+        ((AliasBasedTokenStateService) 
service).setAliasService(getAliasService(gatewayServices));
+      } else if (matchesImplementation(implementation, 
JournalBasedTokenStateService.class)) {
+        service = new JournalBasedTokenStateService();
+      }
+
+      logServiceUsage(implementation, serviceType);
+    }
+
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.TOKEN_STATE_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return unmodifiableList(asList(DefaultTokenStateService.class.getName(), 
AliasBasedTokenStateService.class.getName(), 
JournalBasedTokenStateService.class.getName()));
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TopologyServiceFactory.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TopologyServiceFactory.java
new file mode 100644
index 0000000..74dffd5
--- /dev/null
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TopologyServiceFactory.java
@@ -0,0 +1,53 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.topology.impl.DefaultTopologyService;
+
+public class TopologyServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType 
serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String 
implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = new DefaultTopologyService();
+      ((DefaultTopologyService) 
service).setAliasService(getAliasService(gatewayServices));
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.TOPOLOGY_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultTopologyService.class.getName());
+  }
+}
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultCryptoService.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultCryptoService.java
index 755eb60..788055f 100644
--- 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultCryptoService.java
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultCryptoService.java
@@ -43,23 +43,23 @@ public class DefaultCryptoService implements CryptoService {
 
   private static final Map<String,ConfigurableEncryptor> ENCRYPTOR_CACHE = new 
HashMap<>();
 
-  private AliasService as;
-  private KeystoreService ks;
+  private AliasService aliasService;
+  private KeystoreService keystoreService;
   private GatewayConfig config;
 
   public void setKeystoreService(KeystoreService ks) {
-    this.ks = ks;
+    this.keystoreService = ks;
   }
 
   public void setAliasService(AliasService as) {
-    this.as = as;
+    this.aliasService = as;
   }
 
   @Override
   public void init(GatewayConfig config, Map<String, String> options)
       throws ServiceLifecycleException {
     this.config = config;
-  if (as == null) {
+  if (aliasService == null) {
       throw new ServiceLifecycleException("Alias service is not set");
     }
   }
@@ -77,7 +77,7 @@ public class DefaultCryptoService implements CryptoService {
   @Override
   public void createAndStoreEncryptionKeyForCluster(String clusterName, String 
alias) {
     try {
-      as.generateAliasForCluster(clusterName, alias);
+      aliasService.generateAliasForCluster(clusterName, alias);
     } catch (AliasServiceException e) {
       e.printStackTrace();
     }
@@ -87,7 +87,7 @@ public class DefaultCryptoService implements CryptoService {
   public EncryptionResult encryptForCluster(String clusterName, String alias, 
byte[] clear) {
     char[] password = null;
     try {
-      password = as.getPasswordFromAliasForCluster(clusterName, alias);
+      password = aliasService.getPasswordFromAliasForCluster(clusterName, 
alias);
     } catch (AliasServiceException e2) {
       e2.printStackTrace();
     }
@@ -111,7 +111,7 @@ public class DefaultCryptoService implements CryptoService {
     try {
       char[] password;
       ConfigurableEncryptor encryptor;
-        password = as.getPasswordFromAliasForCluster(clusterName, alias);
+        password = aliasService.getPasswordFromAliasForCluster(clusterName, 
alias);
         if (password != null) {
           encryptor = getEncryptor(clusterName,password );
           try {
@@ -134,7 +134,7 @@ public class DefaultCryptoService implements CryptoService {
     boolean verified = false;
     try {
       Signature sig=Signature.getInstance(algorithm);
-      sig.initVerify(ks.getCertificateForGateway().getPublicKey());
+      
sig.initVerify(keystoreService.getCertificateForGateway().getPublicKey());
       sig.update(signed.getBytes(StandardCharsets.UTF_8));
       verified = sig.verify(signature);
     } catch (SignatureException | KeystoreServiceException | 
InvalidKeyException | NoSuchAlgorithmException | KeyStoreException e) {
@@ -148,8 +148,8 @@ public class DefaultCryptoService implements CryptoService {
   public byte[] sign(String algorithm, String payloadToSign) {
     try {
       char[] passphrase;
-      passphrase = as.getGatewayIdentityPassphrase();
-      PrivateKey privateKey = (PrivateKey) ks.getKeyForGateway(passphrase);
+      passphrase = aliasService.getGatewayIdentityPassphrase();
+      PrivateKey privateKey = (PrivateKey) 
keystoreService.getKeyForGateway(passphrase);
       Signature signature = Signature.getInstance(algorithm);
       signature.initSign(privateKey);
       signature.update(payloadToSign.getBytes(StandardCharsets.UTF_8));
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java
index 5a58029..546d53d 100644
--- 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java
@@ -26,7 +26,6 @@ import org.apache.knox.gateway.GatewayResources;
 import org.apache.knox.gateway.config.GatewayConfig;
 import org.apache.knox.gateway.i18n.messages.MessagesFactory;
 import org.apache.knox.gateway.i18n.resources.ResourcesFactory;
-import org.apache.knox.gateway.services.Service;
 import org.apache.knox.gateway.services.ServiceLifecycleException;
 import org.apache.knox.gateway.services.security.KeystoreService;
 import org.apache.knox.gateway.services.security.KeystoreServiceException;
@@ -68,7 +67,7 @@ import java.util.concurrent.TimeUnit;
 
 import javax.crypto.spec.SecretKeySpec;
 
-public class DefaultKeystoreService implements KeystoreService, Service {
+public class DefaultKeystoreService implements KeystoreService {
   private static final String DN_TEMPLATE = 
"CN={0},OU=Test,O=Hadoop,L=Test,ST=Test,C=US";
   private static final String CREDENTIALS_SUFFIX = "-credentials.jceks";
   private static final String CREDENTIALS_STORE_TYPE = "JCEKS";
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/JettySSLService.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/JettySSLService.java
index 6e79f36..867e3df 100644
--- 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/JettySSLService.java
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/JettySSLService.java
@@ -43,15 +43,15 @@ public class JettySSLService implements SSLService {
   private static final String GATEWAY_CREDENTIAL_STORE_NAME = "__gateway";
   private static GatewayMessages log = MessagesFactory.get( 
GatewayMessages.class );
 
-  private KeystoreService ks;
-  private AliasService as;
+  private KeystoreService keystoreService;
+  private AliasService aliasService;
 
   public void setAliasService(AliasService as) {
-    this.as = as;
+    this.aliasService = as;
   }
 
   public void setKeystoreService(KeystoreService ks) {
-    this.ks = ks;
+    this.keystoreService = ks;
   }
 
   @Override
@@ -60,9 +60,9 @@ public class JettySSLService implements SSLService {
     // set any JSSE or security related system properties
     System.setProperty(EPHEMERAL_DH_KEY_SIZE_PROPERTY, 
config.getEphemeralDHKeySize());
     try {
-      if 
(!ks.isCredentialStoreForClusterAvailable(GATEWAY_CREDENTIAL_STORE_NAME)) {
+      if 
(!keystoreService.isCredentialStoreForClusterAvailable(GATEWAY_CREDENTIAL_STORE_NAME))
 {
         log.creatingCredentialStoreForGateway();
-        ks.createCredentialStoreForCluster(GATEWAY_CREDENTIAL_STORE_NAME);
+        
keystoreService.createCredentialStoreForCluster(GATEWAY_CREDENTIAL_STORE_NAME);
         // LET'S NOT GENERATE A DIFFERENT KEY PASSPHRASE BY DEFAULT ANYMORE
         // IF A DEPLOYMENT WANTS TO CHANGE THE KEY PASSPHRASE TO MAKE IT MORE 
SECURE THEN
         // THEY CAN ADD THE ALIAS EXPLICITLY WITH THE CLI
@@ -76,16 +76,16 @@ public class JettySSLService implements SSLService {
     }
 
     try {
-      if (!ks.isKeystoreForGatewayAvailable()) {
+      if (!keystoreService.isKeystoreForGatewayAvailable()) {
         log.creatingKeyStoreForGateway();
-        ks.createKeystoreForGateway();
+        keystoreService.createKeystoreForGateway();
         char[] passphrase;
         try {
-          passphrase = as.getGatewayIdentityPassphrase();
+          passphrase = aliasService.getGatewayIdentityPassphrase();
         } catch (AliasServiceException e) {
           throw new ServiceLifecycleException("Error accessing credential 
store for the gateway.", e);
         }
-        ks.addSelfSignedCertForGateway(config.getIdentityKeyAlias(), 
passphrase);
+        
keystoreService.addSelfSignedCertForGateway(config.getIdentityKeyAlias(), 
passphrase);
       }
       else {
         log.keyStoreForGatewayFoundNotCreating();
@@ -101,7 +101,7 @@ public class JettySSLService implements SSLService {
     Certificate cert;
     final String identityKeyAlias = config.getIdentityKeyAlias();
     try {
-      cert = as.getCertificateForGateway(identityKeyAlias);
+      cert = aliasService.getCertificateForGateway(identityKeyAlias);
     } catch (AliasServiceException e) {
       throw new ServiceLifecycleException("Cannot Retreive Gateway SSL 
Certificate. Server will not start.", e);
     }
@@ -143,7 +143,7 @@ public class JettySSLService implements SSLService {
 
     char[] keystorePasswordChars;
     try {
-      keystorePasswordChars = as.getGatewayIdentityKeystorePassword();
+      keystorePasswordChars = 
aliasService.getGatewayIdentityKeystorePassword();
     } catch (AliasServiceException e) {
       log.failedToGetPasswordForGatewayIdentityKeystore(e);
       throw e;
@@ -154,7 +154,7 @@ public class JettySSLService implements SSLService {
 
     char[] keypass;
     try {
-      keypass = as.getGatewayIdentityPassphrase();
+      keypass = aliasService.getGatewayIdentityPassphrase();
     } catch (AliasServiceException e) {
       log.failedToGetPassphraseForGatewayIdentityKey(e);
       throw e;
@@ -175,7 +175,7 @@ public class JettySSLService implements SSLService {
         trustStoreType = config.getTruststoreType();
 
         try {
-          truststorePassword = 
as.getPasswordFromAliasForGateway(trustStorePasswordAlias);
+          truststorePassword = 
aliasService.getPasswordFromAliasForGateway(trustStorePasswordAlias);
         } catch (AliasServiceException e) {
           log.failedToGetPasswordForGatewayTruststore(trustStorePasswordAlias, 
e);
           throw e;
@@ -188,7 +188,7 @@ public class JettySSLService implements SSLService {
         trustStoreType = identityKeystoreType;
 
         try {
-          truststorePassword = as.getGatewayIdentityKeystorePassword();
+          truststorePassword = 
aliasService.getGatewayIdentityKeystorePassword();
         } catch (AliasServiceException e) {
           
log.failedToGetPasswordForGatewayTruststore(config.getIdentityKeystorePasswordAlias(),
 e);
           throw e;
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityService.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityService.java
index 465e370..a6f83ea 100644
--- 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityService.java
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityService.java
@@ -73,8 +73,8 @@ public class DefaultTokenAuthorityService implements 
JWTokenAuthority, Service {
   private static final GatewayResources RESOURCES = 
ResourcesFactory.get(GatewayResources.class);
 
   private static final Set<String> SUPPORTED_SIG_ALGS = new HashSet<>();
-  private AliasService as;
-  private KeystoreService ks;
+  private AliasService aliasService;
+  private KeystoreService keystoreService;
   private GatewayConfig config;
 
   private char[] cachedSigningKeyPassphrase;
@@ -92,11 +92,11 @@ public class DefaultTokenAuthorityService implements 
JWTokenAuthority, Service {
   }
 
   public void setKeystoreService(KeystoreService ks) {
-    this.ks = ks;
+    this.keystoreService = ks;
   }
 
   public void setAliasService(AliasService as) {
-    this.as = as;
+    this.aliasService = as;
   }
 
   @Override
@@ -144,7 +144,7 @@ public class DefaultTokenAuthorityService implements 
JWTokenAuthority, Service {
           throws KeystoreServiceException, TokenServiceException {
 
     if (signingKeystorePassphrase != null) {
-      return (RSAPrivateKey) ks.getSigningKey(signingKeystoreName,
+      return (RSAPrivateKey) keystoreService.getSigningKey(signingKeystoreName,
               getSigningKeyAlias(signingKeystoreAlias),
               getSigningKeyPassphrase(signingKeystorePassphrase));
     }
@@ -217,7 +217,7 @@ public class DefaultTokenAuthorityService implements 
JWTokenAuthority, Service {
     PublicKey key;
     try {
       if (publicKey == null) {
-        key = 
ks.getSigningKeystore().getCertificate(getSigningKeyAlias()).getPublicKey();
+        key = 
keystoreService.getSigningKeystore().getCertificate(getSigningKeyAlias()).getPublicKey();
       }
       else {
         key = publicKey;
@@ -261,7 +261,7 @@ public class DefaultTokenAuthorityService implements 
JWTokenAuthority, Service {
   @Override
   public void init(GatewayConfig config, Map<String, String> options)
       throws ServiceLifecycleException {
-    if (as == null || ks == null) {
+    if (aliasService == null || keystoreService == null) {
       throw new ServiceLifecycleException("Alias or Keystore service is not 
set");
     }
     this.config = config;
@@ -272,7 +272,7 @@ public class DefaultTokenAuthorityService implements 
JWTokenAuthority, Service {
     // Ensure that the default signing keystore is available
     KeyStore keystore;
     try {
-      keystore = ks.getSigningKeystore();
+      keystore = keystoreService.getSigningKeystore();
       if (keystore == null) {
         throw new 
ServiceLifecycleException(RESOURCES.signingKeystoreNotAvailable(config.getSigningKeystorePath()));
       }
@@ -282,7 +282,7 @@ public class DefaultTokenAuthorityService implements 
JWTokenAuthority, Service {
 
     // Ensure that the password for the signing key is available
     try {
-      cachedSigningKeyPassphrase = as.getSigningKeyPassphrase();
+      cachedSigningKeyPassphrase = aliasService.getSigningKeyPassphrase();
       if (cachedSigningKeyPassphrase == null) {
         throw new 
ServiceLifecycleException(RESOURCES.signingKeyPassphraseNotAvailable(config.getSigningKeyPassphraseAlias()));
       }
diff --git 
a/gateway-server/src/main/resources/META-INF/services/org.apache.knox.gateway.services.ServiceFactory
 
b/gateway-server/src/main/resources/META-INF/services/org.apache.knox.gateway.services.ServiceFactory
new file mode 100644
index 0000000..02275ea
--- /dev/null
+++ 
b/gateway-server/src/main/resources/META-INF/services/org.apache.knox.gateway.services.ServiceFactory
@@ -0,0 +1,33 @@
+##########################################################################
+# 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.
+##########################################################################
+
+org.apache.knox.gateway.services.factory.AliasServiceFactory
+org.apache.knox.gateway.services.factory.ClusterConfigurationMonitorServiceFactory
+org.apache.knox.gateway.services.factory.CryptoServiceFactory
+org.apache.knox.gateway.services.factory.HostMappingServiceFactory
+org.apache.knox.gateway.services.factory.KeystoreServiceFactory
+org.apache.knox.gateway.services.factory.MasterServiceFactory
+org.apache.knox.gateway.services.factory.MetricsServiceFactory
+org.apache.knox.gateway.services.factory.RemoteRegistryClientServiceFactory
+org.apache.knox.gateway.services.factory.ServerInfoServiceFactory
+org.apache.knox.gateway.services.factory.ServiceDefinitionRegistryFactory
+org.apache.knox.gateway.services.factory.ServiceRegistryServiceFactory
+org.apache.knox.gateway.services.factory.SslServiceFactory
+org.apache.knox.gateway.services.factory.TokenServiceFactory
+org.apache.knox.gateway.services.factory.TokenStateServiceFactory
+org.apache.knox.gateway.services.factory.TopologyServiceFactory
\ No newline at end of file
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/config/impl/GatewayConfigImplTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/config/impl/GatewayConfigImplTest.java
index 3e418b5..f449d05 100644
--- 
a/gateway-server/src/test/java/org/apache/knox/gateway/config/impl/GatewayConfigImplTest.java
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/config/impl/GatewayConfigImplTest.java
@@ -38,7 +38,7 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+  import static org.junit.Assert.assertTrue;
 
 public class GatewayConfigImplTest {
 
@@ -405,4 +405,22 @@ public class GatewayConfigImplTest {
     assertEquals(ZookeeperRemoteAliasService.TYPE, 
remoteAliasServiceConfiguration.get(REMOTE_ALIAS_SERVICE_TYPE));
   }
 
+  @Test
+  public void testGetServiceParameter() throws Exception {
+    final GatewayConfigImpl gatewayConfig = new GatewayConfigImpl();
+
+    // should return an empty string if 'gateway.service.alias.impl' is not set
+    assertEquals("", gatewayConfig.getServiceParameter("alias", "impl"));
+
+    gatewayConfig.set("gateway.service.alias.impl", "myAliasService");
+    gatewayConfig.set("gateway.service.tokenstate.impl", 
"myTokenStateService");
+
+    // should return an empty string if the given service is not defined
+    assertEquals("", gatewayConfig.getServiceParameter("notListedService", 
"impl"));
+
+    //should return the declared implementations
+    assertEquals("myAliasService", gatewayConfig.getServiceParameter("alias", 
"impl"));
+    assertEquals("myTokenStateService", 
gatewayConfig.getServiceParameter("tokenstate", "impl"));
+  }
+
 }
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/TestService.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/TestService.java
new file mode 100644
index 0000000..cae8ad9
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/TestService.java
@@ -0,0 +1,38 @@
+/*
+ * 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.knox.gateway.services;
+
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+
+public class TestService implements Service {
+
+  @Override
+  public void init(GatewayConfig config, Map<String, String> options) throws 
ServiceLifecycleException {
+  }
+
+  @Override
+  public void start() throws ServiceLifecycleException {
+  }
+
+  @Override
+  public void stop() throws ServiceLifecycleException {
+  }
+
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/AliasServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/AliasServiceFactoryTest.java
new file mode 100644
index 0000000..3dfdd14
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/AliasServiceFactoryTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static org.apache.knox.gateway.services.ServiceType.ALIAS_SERVICE;
+import static org.junit.Assert.assertTrue;
+
+import 
org.apache.knox.gateway.backend.hashicorp.vault.HashicorpVaultAliasService;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.impl.DefaultAliasService;
+import org.apache.knox.gateway.services.security.impl.RemoteAliasService;
+import 
org.apache.knox.gateway.services.security.impl.ZookeeperRemoteAliasService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AliasServiceFactoryTest extends ServiceFactoryTest {
+
+  private final AliasServiceFactory serviceFactory = new AliasServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, 
ServiceType.ALIAS_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultAliasService() throws Exception {
+    AliasService aliasService = (AliasService) 
serviceFactory.create(gatewayServices, ServiceType.ALIAS_SERVICE, 
gatewayConfig, options, DefaultAliasService.class.getName());
+    assertTrue(aliasService instanceof DefaultAliasService);
+    assertTrue(isMasterServiceSet(aliasService));
+    assertTrue(isKeystoreServiceSet(aliasService));
+
+    aliasService = (AliasService) serviceFactory.create(gatewayServices, 
ServiceType.ALIAS_SERVICE, gatewayConfig, options, "");
+    assertTrue(aliasService instanceof DefaultAliasService);
+    assertTrue(isMasterServiceSet(aliasService));
+    assertTrue(isKeystoreServiceSet(aliasService));
+  }
+
+  @Test
+  public void shouldReturnHashicorpVaultAliasService() throws Exception {
+    assertTrue(serviceFactory.create(gatewayServices, ALIAS_SERVICE, 
gatewayConfig, options, HashicorpVaultAliasService.class.getName()) instanceof 
HashicorpVaultAliasService);
+  }
+
+  @Test
+  public void shouldReturnRemoteAliasService() throws Exception {
+    assertTrue(serviceFactory.create(gatewayServices, ALIAS_SERVICE, 
gatewayConfig, options, RemoteAliasService.class.getName()) instanceof 
RemoteAliasService);
+  }
+
+  @Test
+  public void shouldReturnZookeeperAliasService() throws Exception {
+    assertTrue(serviceFactory.create(gatewayServices, ALIAS_SERVICE, 
gatewayConfig, options, ZookeeperRemoteAliasService.class.getName()) instanceof 
ZookeeperRemoteAliasService);
+  }
+
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ClusterConfigurationMonitorServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ClusterConfigurationMonitorServiceFactoryTest.java
new file mode 100644
index 0000000..46e4ca7
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ClusterConfigurationMonitorServiceFactoryTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import 
org.apache.knox.gateway.services.topology.impl.DefaultClusterConfigurationMonitorService;
+import org.apache.knox.gateway.topology.ClusterConfigurationMonitorService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ClusterConfigurationMonitorServiceFactoryTest extends 
ServiceFactoryTest {
+
+  private final ClusterConfigurationMonitorServiceFactory serviceFactory = new 
ClusterConfigurationMonitorServiceFactory();
+
+  @Before
+  public void setUp() {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, 
ServiceType.CLUSTER_CONFIGURATION_MONITOR_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultClusterConfigurationMonitorService() throws 
Exception {
+    final ClusterConfigurationMonitorService 
clusterConfigurationMonitorService = (ClusterConfigurationMonitorService) 
serviceFactory.create(gatewayServices,
+        ServiceType.CLUSTER_CONFIGURATION_MONITOR_SERVICE, gatewayConfig, 
options);
+    assertTrue(clusterConfigurationMonitorService instanceof 
DefaultClusterConfigurationMonitorService);
+    assertTrue(isAliasServiceSet(clusterConfigurationMonitorService));
+    assertTrue(isKeystoreServiceSet(clusterConfigurationMonitorService));
+  }
+
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/CryptoServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/CryptoServiceFactoryTest.java
new file mode 100644
index 0000000..e8dad07
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/CryptoServiceFactoryTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.CryptoService;
+import org.apache.knox.gateway.services.security.impl.DefaultCryptoService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CryptoServiceFactoryTest extends ServiceFactoryTest {
+  private final CryptoServiceFactory serviceFactory = new 
CryptoServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, 
ServiceType.CRYPTO_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultCryptoService() throws Exception {
+    final CryptoService cryptoService = (CryptoService) 
serviceFactory.create(gatewayServices, ServiceType.CRYPTO_SERVICE, 
gatewayConfig, options);
+    assertTrue(cryptoService instanceof DefaultCryptoService);
+    assertTrue(isKeystoreServiceSet(cryptoService));
+    assertTrue(isAliasServiceSet(cryptoService));
+  }
+
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/HostMappingServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/HostMappingServiceFactoryTest.java
new file mode 100644
index 0000000..3205be1
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/HostMappingServiceFactoryTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.hostmap.HostMapperService;
+import org.apache.knox.gateway.services.hostmap.impl.DefaultHostMapperService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class HostMappingServiceFactoryTest extends ServiceFactoryTest {
+
+  private final HostMappingServiceFactory serviceFactory = new 
HostMappingServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, 
ServiceType.HOST_MAPPING_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultHostMapperService() throws Exception {
+    final HostMapperService hostMapperService = (HostMapperService) 
serviceFactory.create(gatewayServices, ServiceType.HOST_MAPPING_SERVICE, 
gatewayConfig, options);
+    assertTrue(hostMapperService instanceof DefaultHostMapperService);
+  }
+
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/KeystoreServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/KeystoreServiceFactoryTest.java
new file mode 100644
index 0000000..a19ff73
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/KeystoreServiceFactoryTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.KeystoreService;
+import org.apache.knox.gateway.services.security.impl.DefaultKeystoreService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class KeystoreServiceFactoryTest extends ServiceFactoryTest {
+
+  private final KeystoreServiceFactory serviceFactory = new 
KeystoreServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, 
ServiceType.KEYSTORE_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultKeystoreService() throws Exception {
+    final KeystoreService keystoreService = (KeystoreService) 
serviceFactory.create(gatewayServices, ServiceType.KEYSTORE_SERVICE, 
gatewayConfig, options);
+    assertTrue(keystoreService instanceof DefaultKeystoreService);
+    assertTrue(isMasterServiceSet(keystoreService));
+  }
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/MasterServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/MasterServiceFactoryTest.java
new file mode 100644
index 0000000..36beaca
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/MasterServiceFactoryTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.MasterService;
+import org.apache.knox.gateway.services.security.impl.CLIMasterService;
+import org.apache.knox.gateway.services.security.impl.DefaultMasterService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MasterServiceFactoryTest extends ServiceFactoryTest {
+
+  private final MasterServiceFactory serviceFactory = new 
MasterServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, 
ServiceType.CLUSTER_CONFIGURATION_MONITOR_SERVICE, ServiceType.MASTER_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultMasterService() throws Exception {
+    MasterService masterService = (MasterService) 
serviceFactory.create(gatewayServices, ServiceType.MASTER_SERVICE, null, null, 
DefaultMasterService.class.getName());
+    assertTrue(masterService instanceof DefaultMasterService);
+
+    masterService = (MasterService) serviceFactory.create(gatewayServices, 
ServiceType.MASTER_SERVICE, null, null, "");
+    assertTrue(masterService instanceof DefaultMasterService);
+  }
+
+  @Test
+  public void shouldReturnCliMasterService() throws Exception {
+    MasterService masterService = (MasterService) 
serviceFactory.create(gatewayServices, ServiceType.MASTER_SERVICE, null, null, 
CLIMasterService.class.getName());
+    assertTrue(masterService instanceof CLIMasterService);
+  }
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/MetricsServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/MetricsServiceFactoryTest.java
new file mode 100644
index 0000000..95eaea6
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/MetricsServiceFactoryTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.metrics.MetricsService;
+import org.apache.knox.gateway.services.metrics.impl.DefaultMetricsService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MetricsServiceFactoryTest extends ServiceFactoryTest {
+
+  private final MetricsServiceFactory serviceFactory = new 
MetricsServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, 
ServiceType.METRICS_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultMetricsService() throws Exception {
+    final MetricsService metricsService = (MetricsService) 
serviceFactory.create(gatewayServices, ServiceType.METRICS_SERVICE, 
gatewayConfig, options);
+    assertTrue(metricsService instanceof DefaultMetricsService);
+  }
+
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServerInfoServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServerInfoServiceFactoryTest.java
new file mode 100644
index 0000000..a97e490
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServerInfoServiceFactoryTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.DefaultServerInfoService;
+import org.apache.knox.gateway.services.ServerInfoService;
+import org.apache.knox.gateway.services.ServiceType;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ServerInfoServiceFactoryTest extends ServiceFactoryTest {
+
+  private final ServerInfoServiceFactory serviceFactory = new 
ServerInfoServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, 
ServiceType.SERVER_INFO_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultServerInfoService() throws Exception {
+    final ServerInfoService serverInfoService = (ServerInfoService) 
serviceFactory.create(gatewayServices, ServiceType.SERVER_INFO_SERVICE, 
gatewayConfig, options);
+    assertTrue(serverInfoService instanceof DefaultServerInfoService);
+  }
+
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServiceDefinitionRegistryFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServiceDefinitionRegistryFactoryTest.java
new file mode 100644
index 0000000..67e0a67
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServiceDefinitionRegistryFactoryTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static 
org.apache.knox.gateway.services.ServiceType.SERVICE_DEFINITION_REGISTRY;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.registry.ServiceDefinitionRegistry;
+import 
org.apache.knox.gateway.services.registry.impl.DefaultServiceDefinitionRegistry;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ServiceDefinitionRegistryFactoryTest extends ServiceFactoryTest {
+
+  private final ServiceDefinitionRegistryFactory serviceFactory = new 
ServiceDefinitionRegistryFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, 
SERVICE_DEFINITION_REGISTRY);
+  }
+
+  @Test
+  public void shouldReturnDefaultServiceDefinitionRegistry() throws Exception {
+    final ServiceDefinitionRegistry serviceDefinitionRegistry = 
(ServiceDefinitionRegistry) serviceFactory.create(gatewayServices, 
SERVICE_DEFINITION_REGISTRY, gatewayConfig,
+        options);
+    assertTrue(serviceDefinitionRegistry instanceof 
DefaultServiceDefinitionRegistry);
+  }
+
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServiceFactoryTest.java
new file mode 100644
index 0000000..c7dbced
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServiceFactoryTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static org.easymock.EasyMock.anyString;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.CoreMatchers.isA;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.TestService;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.KeystoreService;
+import org.apache.knox.gateway.services.security.MasterService;
+import org.easymock.EasyMock;
+import org.junit.Rule;
+import org.junit.rules.ExpectedException;
+
+class ServiceFactoryTest {
+
+  @SuppressWarnings("deprecation")
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  protected final GatewayServices gatewayServices = 
EasyMock.createNiceMock(GatewayServices.class);
+  protected final GatewayConfig gatewayConfig = 
EasyMock.createNiceMock(GatewayConfig.class);
+  protected final Map<String, String> options = Collections.emptyMap();
+
+  protected void initConfig() {
+    final MasterService masterService = 
EasyMock.createNiceMock(MasterService.class);
+    
expect(gatewayServices.getService(ServiceType.MASTER_SERVICE)).andReturn(masterService).anyTimes();
+    final KeystoreService keystoreservice = 
EasyMock.createNiceMock(KeystoreService.class);
+    
expect(gatewayServices.getService(ServiceType.KEYSTORE_SERVICE)).andReturn(keystoreservice).anyTimes();
+    final AliasService aliasService = 
EasyMock.createNiceMock(AliasService.class);
+    
expect(gatewayServices.getService(ServiceType.ALIAS_SERVICE)).andReturn(aliasService).anyTimes();
+    replay(gatewayServices);
+    expect(gatewayConfig.getServiceParameter(anyString(), 
anyString())).andReturn("").anyTimes();
+    replay(gatewayConfig);
+  }
+
+  protected void testBasics(AbstractServiceFactory serviceFactory, ServiceType 
nonMatchingServiceType, ServiceType matchingServiceType) throws Exception {
+    shouldReturnCorrectServiceType(serviceFactory, matchingServiceType);
+    shouldReturnNullForNonMatchingServiceType(serviceFactory, 
nonMatchingServiceType);
+    shouldReturnCustomImplementation(serviceFactory, matchingServiceType);
+    
shouldFailWithClassNotFoundExceptionForUnknownImplementationWithClassNotOnClasspath(serviceFactory,
 matchingServiceType);
+  }
+
+  private void shouldReturnCorrectServiceType(AbstractServiceFactory 
serviceFactory, ServiceType serviceType) {
+    assertEquals(serviceType, serviceFactory.getServiceType());
+  }
+
+  private void 
shouldReturnNullForNonMatchingServiceType(AbstractServiceFactory 
serviceFactory, ServiceType serviceType) throws Exception {
+    assertNull(serviceFactory.create(gatewayServices, serviceType, 
gatewayConfig, options));
+  }
+
+  private void 
shouldFailWithClassNotFoundExceptionForUnknownImplementationWithClassNotOnClasspath(AbstractServiceFactory
 serviceFactory, ServiceType serviceType)
+      throws Exception {
+    expectedException.expect(ServiceLifecycleException.class);
+    final String implementation = "this.is.my.non.existing.Service";
+    expectedException.expectMessage(String.format(Locale.ROOT, "Errror while 
instantiating %s service implementation %s", serviceType.getShortName(), 
implementation));
+    expectedException.expectCause(isA(ClassNotFoundException.class));
+    serviceFactory.create(gatewayServices, serviceType, null, null, 
implementation);
+  }
+
+  private void shouldReturnCustomImplementation(AbstractServiceFactory 
serviceFactory, ServiceType matchingServiceType) throws Exception {
+    final Service service = serviceFactory.create(gatewayServices, 
matchingServiceType, null, null, 
"org.apache.knox.gateway.services.TestService");
+    assertTrue(service instanceof TestService);
+  }
+
+  protected boolean isMasterServiceSet(Service serviceToCheck) throws 
Exception {
+    return isServiceSet(serviceToCheck, "masterService");
+  }
+
+  protected boolean isKeystoreServiceSet(Service serviceToCheck) throws 
Exception {
+    return isServiceSet(serviceToCheck, "keystoreService");
+  }
+
+  protected boolean isAliasServiceSet(Service serviceToCheck) throws Exception 
{
+    return isServiceSet(serviceToCheck, "aliasService");
+  }
+
+  private boolean isServiceSet(Service serviceToCheck, String 
expectedServiceName) throws Exception {
+    final Field aliasServiceField = 
FieldUtils.getDeclaredField(serviceToCheck.getClass(), expectedServiceName, 
true);
+    final Object aliasServiceValue = aliasServiceField.get(serviceToCheck);
+    return aliasServiceValue != null;
+  }
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/SslServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/SslServiceFactoryTest.java
new file mode 100644
index 0000000..76b15fd
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/SslServiceFactoryTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.SSLService;
+import org.apache.knox.gateway.services.security.impl.JettySSLService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SslServiceFactoryTest extends ServiceFactoryTest {
+
+  private final SslServiceFactory serviceFactory = new SslServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, 
ServiceType.SSL_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnJettySslService() throws Exception {
+    final SSLService keystoreService = (SSLService) 
serviceFactory.create(gatewayServices, ServiceType.SSL_SERVICE, gatewayConfig, 
options);
+    assertTrue(keystoreService instanceof JettySSLService);
+    assertTrue(isKeystoreServiceSet(keystoreService));
+    assertTrue(isAliasServiceSet(keystoreService));
+  }
+
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TokenServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TokenServiceFactoryTest.java
new file mode 100644
index 0000000..425a2a7
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TokenServiceFactoryTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import 
org.apache.knox.gateway.services.token.impl.DefaultTokenAuthorityService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TokenServiceFactoryTest extends ServiceFactoryTest {
+
+  private final TokenServiceFactory serviceFactory = new TokenServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, 
ServiceType.TOKEN_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultTokenService() throws Exception {
+    final DefaultTokenAuthorityService keystoreService = 
(DefaultTokenAuthorityService) serviceFactory.create(gatewayServices, 
ServiceType.TOKEN_SERVICE, gatewayConfig, options);
+    assertTrue(keystoreService instanceof DefaultTokenAuthorityService);
+    assertTrue(isKeystoreServiceSet(keystoreService));
+    assertTrue(isAliasServiceSet(keystoreService));
+  }
+
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TokenStateServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TokenStateServiceFactoryTest.java
new file mode 100644
index 0000000..7625d50
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TokenStateServiceFactoryTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.token.TokenStateService;
+import org.apache.knox.gateway.services.token.impl.AliasBasedTokenStateService;
+import org.apache.knox.gateway.services.token.impl.DefaultTokenStateService;
+import 
org.apache.knox.gateway.services.token.impl.JournalBasedTokenStateService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TokenStateServiceFactoryTest extends ServiceFactoryTest {
+
+  private final TokenStateServiceFactory serviceFactory = new 
TokenStateServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, 
ServiceType.TOKEN_STATE_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultAliasService() throws Exception {
+    TokenStateService tokenStateService = (TokenStateService) 
serviceFactory.create(gatewayServices, ServiceType.TOKEN_STATE_SERVICE, null, 
null, DefaultTokenStateService.class.getName());
+    assertTrue(tokenStateService instanceof DefaultTokenStateService);
+
+    tokenStateService = (TokenStateService) 
serviceFactory.create(gatewayServices, ServiceType.TOKEN_STATE_SERVICE, null, 
null, "");
+    assertTrue(tokenStateService instanceof DefaultTokenStateService);
+  }
+
+  @Test
+  public void shouldReturnAliasBasedTokenStateService() throws Exception {
+    final TokenStateService tokenStateService = (TokenStateService) 
serviceFactory.create(gatewayServices, ServiceType.TOKEN_STATE_SERVICE, null, 
null, AliasBasedTokenStateService.class.getName());
+    assertTrue(tokenStateService instanceof AliasBasedTokenStateService);
+    assertTrue(isAliasServiceSet(tokenStateService));
+  }
+
+  @Test
+  public void shouldReturnHJournalTokenStateService() throws Exception {
+    assertTrue(serviceFactory.create(gatewayServices, 
ServiceType.TOKEN_STATE_SERVICE, null, null, 
JournalBasedTokenStateService.class.getName()) instanceof 
JournalBasedTokenStateService);
+  }
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TopologyServiceFactoryTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TopologyServiceFactoryTest.java
new file mode 100644
index 0000000..151d42d
--- /dev/null
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TopologyServiceFactoryTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.topology.TopologyService;
+import org.apache.knox.gateway.services.topology.impl.DefaultTopologyService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TopologyServiceFactoryTest extends ServiceFactoryTest {
+
+  private final TopologyServiceFactory serviceFactory = new 
TopologyServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, 
ServiceType.TOPOLOGY_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultTopologyService() throws Exception {
+    TopologyService topologyService = (TopologyService) 
serviceFactory.create(gatewayServices, ServiceType.TOPOLOGY_SERVICE, 
gatewayConfig, null);
+    assertTrue(topologyService instanceof DefaultTopologyService);
+    assertTrue(isAliasServiceSet(topologyService));
+  }
+
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/websockets/BadUrlTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/websockets/BadUrlTest.java
index 7e1105d..2fca3c5 100644
--- 
a/gateway-server/src/test/java/org/apache/knox/gateway/websockets/BadUrlTest.java
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/websockets/BadUrlTest.java
@@ -310,6 +310,8 @@ public class BadUrlTest {
         .andReturn(TEST_KEY_ALIAS)
         .anyTimes();
 
+    EasyMock.expect(gatewayConfig.getServiceParameter(EasyMock.anyString(), 
EasyMock.anyString())).andReturn("").anyTimes();
+
     EasyMock.replay(gatewayConfig);
 
     try {
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketEchoTestBase.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketEchoTestBase.java
index 86a580a..bf11748 100644
--- 
a/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketEchoTestBase.java
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketEchoTestBase.java
@@ -336,6 +336,7 @@ public class WebsocketEchoTestBase {
         .andReturn(TEST_KEY_ALIAS)
         .anyTimes();
 
+    EasyMock.expect(gatewayConfig.getServiceParameter(EasyMock.anyString(), 
EasyMock.anyString())).andReturn("").anyTimes();
 
     EasyMock.replay(gatewayConfig);
 
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketMultipleConnectionTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketMultipleConnectionTest.java
index a2a4ae7..d7db608 100644
--- 
a/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketMultipleConnectionTest.java
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketMultipleConnectionTest.java
@@ -373,6 +373,8 @@ public class WebsocketMultipleConnectionTest {
         .andReturn(TEST_KEY_ALIAS)
         .anyTimes();
 
+    EasyMock.expect(gatewayConfig.getServiceParameter(EasyMock.anyString(), 
EasyMock.anyString())).andReturn("").anyTimes();
+
     EasyMock.replay(gatewayConfig);
 
     try {
diff --git 
a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java 
b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
index 7825e7b..4e533ad 100644
--- 
a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
+++ 
b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
@@ -693,4 +693,9 @@ public interface GatewayConfig {
    * @return returns whether know token permissive validation is enabled
    */
   boolean isKnoxTokenPermissiveValidationEnabled();
+
+  /**
+   * @return the value of the given parameter for the given service if 
declared; an empty String otherwise
+   */
+  String getServiceParameter(String service, String parameter);
 }
diff --git 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceFactory.java
 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceFactory.java
new file mode 100644
index 0000000..ca0301e
--- /dev/null
+++ 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceFactory.java
@@ -0,0 +1,31 @@
+/*
+ * 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.knox.gateway.services;
+
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+
+public interface ServiceFactory {
+
+  Service create(GatewayServices gatewayServices, ServiceType serviceType, 
GatewayConfig gatewayConfig, Map<String, String> options) throws 
ServiceLifecycleException;
+
+  Service create(GatewayServices gatewayServices, ServiceType serviceType, 
GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException;
+
+}
diff --git 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceType.java 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceType.java
index 736ecad..38767f8 100644
--- 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceType.java
+++ 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceType.java
@@ -18,6 +18,8 @@
 
 package org.apache.knox.gateway.services;
 
+import java.util.Locale;
+
 public enum ServiceType {
   ALIAS_SERVICE("AliasService"),
   CLUSTER_CONFIGURATION_MONITOR_SERVICE("ClusterConfigurationMonitorService"),
@@ -36,12 +38,18 @@ public enum ServiceType {
   TOPOLOGY_SERVICE("TopologyService");
 
   private final String serviceTypeName;
+  private final String shortName;
 
   ServiceType(String serviceTypeName) {
     this.serviceTypeName = serviceTypeName;
+    this.shortName = 
serviceTypeName.toLowerCase(Locale.ROOT).replace("service", "");
   }
 
   public String getServiceTypeName() {
     return serviceTypeName;
   }
+
+  public String getShortName() {
+    return shortName;
+  }
 }
diff --git 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/KeystoreService.java
 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/KeystoreService.java
index 95c1f71..68fb637 100644
--- 
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/KeystoreService.java
+++ 
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/KeystoreService.java
@@ -24,7 +24,9 @@ import java.security.cert.Certificate;
 import java.util.Map;
 import java.util.Set;
 
-public interface KeystoreService {
+import org.apache.knox.gateway.services.Service;
+
+public interface KeystoreService extends Service {
 
   void createKeystoreForGateway() throws KeystoreServiceException;
 
diff --git 
a/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
 
b/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
index e3dbeaa..499fe3f 100644
--- 
a/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
+++ 
b/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
@@ -812,4 +812,9 @@ public class GatewayTestConfig extends Configuration 
implements GatewayConfig {
   public boolean isKnoxTokenPermissiveValidationEnabled() {
     return false;
   }
+
+  @Override
+  public String getServiceParameter(String service, String parameter) {
+    return "";
+  }
 }

Reply via email to