/*
 * 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.config.impl;

import org.apache.knox.gateway.config.GatewayConfig;
import org.apache.knox.gateway.services.security.impl.ZookeeperRemoteAliasService;
import org.apache.knox.test.TestUtils;
import org.hamcrest.CoreMatchers;
import org.junit.Test;

import java.nio.file.Paths;
import java.security.KeyStore;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static org.apache.knox.gateway.services.security.impl.RemoteAliasService.REMOTE_ALIAS_SERVICE_TYPE;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertEquals;
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;

public class GatewayConfigImplTest {

  @Test( timeout = TestUtils.SHORT_TIMEOUT )
  public void testHttpServerSettings() {
    GatewayConfigImpl config = new GatewayConfigImpl();

    // Check the defaults.
    assertThat( config.getHttpServerRequestBuffer(), is( 16*1024 ) );
    assertThat( config.getHttpServerRequestHeaderBuffer(), is( 8*1024 ) );
    assertThat( config.getHttpServerResponseBuffer(), is( 32*1024 ) );
    assertThat( config.getHttpServerResponseHeaderBuffer(), is( 8*1024 ) );

    assertThat( GatewayConfigImpl.HTTP_SERVER_REQUEST_BUFFER, is( "gateway.httpserver.requestBuffer" ) );
    assertThat( GatewayConfigImpl.HTTP_SERVER_REQUEST_HEADER_BUFFER, is( "gateway.httpserver.requestHeaderBuffer" ) );
    assertThat( GatewayConfigImpl.HTTP_SERVER_RESPONSE_BUFFER, is( "gateway.httpserver.responseBuffer" ) );
    assertThat( GatewayConfigImpl.HTTP_SERVER_RESPONSE_HEADER_BUFFER, is( "gateway.httpserver.responseHeaderBuffer" ) );

    config.setInt( GatewayConfigImpl.HTTP_SERVER_REQUEST_BUFFER, 32*1024 );
    assertThat( config.getHttpServerRequestBuffer(), is( 32*1024 ) );

    config.setInt( GatewayConfigImpl.HTTP_SERVER_REQUEST_HEADER_BUFFER, 4*1024 );
    assertThat( config.getHttpServerRequestHeaderBuffer(), is( 4*1024 ) );

    config.setInt( GatewayConfigImpl.HTTP_SERVER_RESPONSE_BUFFER, 16*1024 );
    assertThat( config.getHttpServerResponseBuffer(), is( 16*1024 ) );

    config.setInt( GatewayConfigImpl.HTTP_SERVER_RESPONSE_HEADER_BUFFER, 6*1024 );
    assertThat( config.getHttpServerResponseHeaderBuffer(), is( 6*1024 ) );

    // Restore the defaults.
    config.setInt( GatewayConfigImpl.HTTP_SERVER_REQUEST_BUFFER, 16*1024 );
    config.setInt( GatewayConfigImpl.HTTP_SERVER_REQUEST_HEADER_BUFFER, 8*1024 );
    config.setInt( GatewayConfigImpl.HTTP_SERVER_RESPONSE_BUFFER, 32*1024 );
    config.setInt( GatewayConfigImpl.HTTP_SERVER_RESPONSE_HEADER_BUFFER, 8*1024 );
  }

  @Test( timeout = TestUtils.SHORT_TIMEOUT )
  public void testGetGatewayDeploymentsBackupVersionLimit() {
    GatewayConfigImpl config = new GatewayConfigImpl();
    assertThat( config.getGatewayDeploymentsBackupVersionLimit(), is(5) );

    config.setInt( config.DEPLOYMENTS_BACKUP_VERSION_LIMIT, 3 );
    assertThat( config.getGatewayDeploymentsBackupVersionLimit(), is(3) );

    config.setInt( config.DEPLOYMENTS_BACKUP_VERSION_LIMIT, -3 );
    assertThat( config.getGatewayDeploymentsBackupVersionLimit(), is(-1) );

    config.setInt( config.DEPLOYMENTS_BACKUP_VERSION_LIMIT, 0 );
    assertThat( config.getGatewayDeploymentsBackupVersionLimit(), is(0) );
  }

  @Test( timeout = TestUtils.SHORT_TIMEOUT )
  public void testGetGatewayDeploymentsBackupAgeLimit() {
    GatewayConfigImpl config = new GatewayConfigImpl();
    assertThat( config.getGatewayDeploymentsBackupAgeLimit(), is(-1L) );

    config.set( config.DEPLOYMENTS_BACKUP_AGE_LIMIT, "1" );
    assertThat( config.getGatewayDeploymentsBackupAgeLimit(), is(86400000L) );

    config.set( config.DEPLOYMENTS_BACKUP_AGE_LIMIT, "2" );
    assertThat( config.getGatewayDeploymentsBackupAgeLimit(), is(86400000L*2L) );

    config.set( config.DEPLOYMENTS_BACKUP_AGE_LIMIT, "0" );
    assertThat( config.getGatewayDeploymentsBackupAgeLimit(), is(0L) );

    config.set( config.DEPLOYMENTS_BACKUP_AGE_LIMIT, "X" );
    assertThat( config.getGatewayDeploymentsBackupAgeLimit(), is(-1L) );
  }


  @Test
  public void testSSLCiphers() {
    GatewayConfigImpl config = new GatewayConfigImpl();
    List<String> list;

    list = config.getIncludedSSLCiphers();
    assertThat( list, is(nullValue()) );

    config.set( "ssl.include.ciphers", "none" );
    assertThat( config.getIncludedSSLCiphers(), is(nullValue()) );

    config.set( "ssl.include.ciphers", "" );
    assertThat( config.getIncludedSSLCiphers(), is(nullValue()) );

    config.set( "ssl.include.ciphers", "ONE" );
    assertThat( config.getIncludedSSLCiphers(), is(hasItems("ONE")) );

    config.set( "ssl.include.ciphers", " ONE " );
    assertThat( config.getIncludedSSLCiphers(), is(hasItems("ONE")) );

    config.set( "ssl.include.ciphers", "ONE,TWO" );
    assertThat( config.getIncludedSSLCiphers(), is(hasItems("ONE","TWO")) );

    config.set( "ssl.include.ciphers", "ONE,TWO,THREE" );
    assertThat( config.getIncludedSSLCiphers(), is(hasItems("ONE","TWO","THREE")) );

    config.set( "ssl.include.ciphers", " ONE , TWO , THREE " );
    assertThat( config.getIncludedSSLCiphers(), is(hasItems("ONE","TWO","THREE")) );

    list = config.getExcludedSSLCiphers();
    assertThat( list, is(nullValue()) );

    config.set( "ssl.exclude.ciphers", "none" );
    assertThat( config.getExcludedSSLCiphers(), is(nullValue()) );

    config.set( "ssl.exclude.ciphers", "" );
    assertThat( config.getExcludedSSLCiphers(), is(nullValue()) );

    config.set( "ssl.exclude.ciphers", "ONE" );
    assertThat( config.getExcludedSSLCiphers(), is(hasItems("ONE")) );

    config.set( "ssl.exclude.ciphers", " ONE " );
    assertThat( config.getExcludedSSLCiphers(), is(hasItems("ONE")) );

    config.set( "ssl.exclude.ciphers", "ONE,TWO" );
    assertThat( config.getExcludedSSLCiphers(), is(hasItems("ONE","TWO")) );

    config.set( "ssl.exclude.ciphers", "ONE,TWO,THREE" );
    assertThat( config.getExcludedSSLCiphers(), is(hasItems("ONE","TWO","THREE")) );

    config.set( "ssl.exclude.ciphers", " ONE , TWO , THREE " );
    assertThat( config.getExcludedSSLCiphers(), is(hasItems("ONE","TWO","THREE")) );
  }

  // KNOX-2772
  @Test
  public void testisSSLRenegotiationAllowed() {
    GatewayConfigImpl config = new GatewayConfigImpl();
    boolean isSSLRenegotiationAllowed = config.isSSLRenegotiationAllowed();
    assertThat( isSSLRenegotiationAllowed, is(true));

    config.set("ssl.renegotiation", "false");
    isSSLRenegotiationAllowed = config.isSSLRenegotiationAllowed();
    assertThat( isSSLRenegotiationAllowed, is(false));
  }

  @Test( timeout = TestUtils.SHORT_TIMEOUT )
  public void testGlobalRulesServices() {
    GatewayConfigImpl config = new GatewayConfigImpl();
    List<String> list;

    list = config.getGlobalRulesServices();
    assertThat( list, is(notNullValue()) );

    assertThat( list, is( CoreMatchers.hasItems("NAMENODE","JOBTRACKER", "WEBHDFS", "WEBHCAT", "OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER", "RESOURCEMANAGERAPI")));


    config.set( GatewayConfigImpl.GLOBAL_RULES_SERVICES, "none" );
    assertThat( config.getGlobalRulesServices(), is( CoreMatchers.hasItems("NAMENODE","JOBTRACKER", "WEBHDFS", "WEBHCAT", "OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER", "RESOURCEMANAGERAPI")) );

    config.set( GatewayConfigImpl.GLOBAL_RULES_SERVICES, "" );
    assertThat( config.getGlobalRulesServices(), is( CoreMatchers.hasItems("NAMENODE","JOBTRACKER", "WEBHDFS", "WEBHCAT", "OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER", "RESOURCEMANAGERAPI")) );

    config.set( GatewayConfigImpl.GLOBAL_RULES_SERVICES, "ONE" );
    assertThat( config.getGlobalRulesServices(), is(hasItems("ONE")) );

    config.set( GatewayConfigImpl.GLOBAL_RULES_SERVICES, "ONE,TWO,THREE" );
    assertThat( config.getGlobalRulesServices(), is(hasItems("ONE","TWO","THREE")) );

    config.set( GatewayConfigImpl.GLOBAL_RULES_SERVICES, " ONE , TWO , THREE " );
    assertThat( config.getGlobalRulesServices(), is(hasItems("ONE","TWO","THREE")) );
  }

  @Test( timeout = TestUtils.SHORT_TIMEOUT )
  public void testMetricsSettings() {
    GatewayConfigImpl config = new GatewayConfigImpl();
    //test defaults
    assertThat(config.isMetricsEnabled(), is(false));
    assertThat(config.isJmxMetricsReportingEnabled(), is(false));
    assertThat(config.isGraphiteMetricsReportingEnabled(), is(false));
    assertThat(config.getGraphiteHost(), is("localhost"));
    assertThat(config.getGraphitePort(), is(32772));
  }

  @Test( timeout = TestUtils.SHORT_TIMEOUT )
  public void testGatewayIdleTimeout() {
    GatewayConfigImpl config = new GatewayConfigImpl();
    long idleTimeout;

    idleTimeout = config.getGatewayIdleTimeout();
    assertThat( idleTimeout, is(300000L));

    config.set( GatewayConfigImpl.GATEWAY_IDLE_TIMEOUT, "15000" );
    idleTimeout = config.getGatewayIdleTimeout();
    assertThat( idleTimeout, is(15000L));
  }

  @Test( timeout = TestUtils.SHORT_TIMEOUT )
  public void testGatewayServerHeaderEnabled() {
    GatewayConfigImpl config = new GatewayConfigImpl();
    boolean serverHeaderEnabled;

    serverHeaderEnabled = config.isGatewayServerHeaderEnabled();
    assertThat( serverHeaderEnabled, is(false));

    config.set( GatewayConfigImpl.SERVER_HEADER_ENABLED, "true");
    serverHeaderEnabled = config.isGatewayServerHeaderEnabled();
    assertThat( serverHeaderEnabled, is(true));
  }


  @Test
  public void testGetRemoteConfigurationRegistryNames() {
    GatewayConfigImpl config = new GatewayConfigImpl();

    List<String> registryNames = config.getRemoteRegistryConfigurationNames();
    assertNotNull(registryNames);
    assertTrue(registryNames.isEmpty());

    config.set(GatewayConfigImpl.CONFIG_REGISTRY_PREFIX + ".test1",
               "type=ZooKeeper;address=host1:2181;authType=digest;principal=itsme;credentialAlias=testAlias");
    registryNames = config.getRemoteRegistryConfigurationNames();
    assertNotNull(registryNames);
    assertFalse(registryNames.isEmpty());
    assertEquals(1, registryNames.size());

    config.set(GatewayConfigImpl.CONFIG_REGISTRY_PREFIX + ".test2",
               "type=ZooKeeper;address=host2:2181,host3:2181,host4:2181");
    registryNames = config.getRemoteRegistryConfigurationNames();
    assertNotNull(registryNames);
    assertFalse(registryNames.isEmpty());
    assertEquals(registryNames.size(), 2);
  }


  @Test
  public void testHTTPDefaultTimeouts() {
    final GatewayConfigImpl config = new GatewayConfigImpl();

    assertNotEquals(config.getHttpClientConnectionTimeout(), -1);
    assertNotEquals(config.getHttpClientSocketTimeout(), -1);

    assertEquals(TimeUnit.SECONDS.toMillis(20), config.getHttpClientConnectionTimeout());
    assertEquals(TimeUnit.SECONDS.toMillis(20), config.getHttpClientSocketTimeout());
  }


  // KNOX-1322
  @Test
  public void testGetReadOnlyOverrideTopologyNames() {
    GatewayConfigImpl config = new GatewayConfigImpl();

    List<String> names = config.getReadOnlyOverrideTopologyNames();
    assertNotNull(names);
    assertTrue(names.isEmpty());

    config.set(GatewayConfigImpl.READ_ONLY_OVERRIDE_TOPOLOGIES, "");
    names = config.getReadOnlyOverrideTopologyNames();
    assertNotNull(names);
    assertTrue(names.isEmpty());

    config.set(GatewayConfigImpl.READ_ONLY_OVERRIDE_TOPOLOGIES, "admin");
    names = config.getReadOnlyOverrideTopologyNames();
    assertNotNull(names);
    assertFalse(names.isEmpty());
    assertEquals(1, names.size());
    assertEquals("admin", names.get(0));

    config.set(GatewayConfigImpl.READ_ONLY_OVERRIDE_TOPOLOGIES, "admin, sandbox, test ,default");
    names = config.getReadOnlyOverrideTopologyNames();
    assertNotNull(names);
    assertFalse(names.isEmpty());
    assertEquals(4, names.size());
    assertTrue(names.contains("admin"));
    assertTrue(names.contains("sandbox"));
    assertTrue(names.contains("test"));
    assertTrue(names.contains("default"));
  }

  // KNOX-1756
  @Test
  public void testCustomIdentityKeystoreOptions() {
    GatewayConfigImpl config = new GatewayConfigImpl();

    // Validate default options (backwards compatibility)
    assertEquals("gateway-identity", config.getIdentityKeyAlias());
    assertEquals("gateway-identity-passphrase", config.getIdentityKeyPassphraseAlias());
    assertEquals("gateway-identity", config.getSigningKeyAlias());
    assertEquals("gateway-identity-passphrase", config.getSigningKeyPassphraseAlias());
    assertNull(config.getSigningKeystoreName());

    // Validate default options (new)
    assertEquals(GatewayConfig.DEFAULT_IDENTITY_KEYSTORE_PASSWORD_ALIAS, config.getIdentityKeystorePasswordAlias());
    assertEquals(GatewayConfig.DEFAULT_IDENTITY_KEYSTORE_TYPE, config.getIdentityKeystoreType());
    assertEquals(Paths.get(config.getGatewayKeystoreDir(), "gateway.jks").toAbsolutePath().toString(),
        config.getIdentityKeystorePath());

    // By default the signing keystore name will not be set, so the values will be taken from the identity's configs
    assertEquals(config.getIdentityKeystorePath(), config.getSigningKeystorePath());
    assertEquals(config.getIdentityKeystorePasswordAlias(), config.getSigningKeystorePasswordAlias());
    assertEquals(config.getIdentityKeystoreType(), config.getSigningKeystoreType());
    assertEquals(config.getIdentityKeyAlias(), config.getSigningKeyAlias());
    assertEquals(config.getIdentityKeyPassphraseAlias(), config.getSigningKeyPassphraseAlias());

    String tlsKeystorePath = Paths.get("custom", "keystore", "path", "keystore.p12").toString();

    // Validate changed options
    config.set("gateway.tls.key.alias", "custom_key_alias");
    config.set("gateway.tls.key.passphrase.alias", "custom_key_passphrase_alias");
    config.set("gateway.tls.keystore.path", tlsKeystorePath);
    config.set("gateway.tls.keystore.type", "PKCS12");
    config.set("gateway.tls.keystore.password.alias", "custom_keystore_password_alias");

    config.set("gateway.signing.key.alias", "custom_key_alias");
    config.set("gateway.signing.key.passphrase.alias", "custom_key_passphrase_alias");
    config.set("gateway.signing.keystore.name", "custom_keystore_name");
    config.set("gateway.signing.keystore.type", "PKCS12");
    config.set("gateway.signing.keystore.password.alias", "custom_keystore_password_alias");

    assertEquals("custom_key_alias", config.getIdentityKeyAlias());
    assertEquals("custom_key_passphrase_alias", config.getIdentityKeyPassphraseAlias());
    assertEquals(tlsKeystorePath, config.getIdentityKeystorePath());
    assertEquals("PKCS12", config.getIdentityKeystoreType());
    assertEquals("custom_keystore_password_alias", config.getIdentityKeystorePasswordAlias());

    assertEquals("custom_key_alias", config.getSigningKeyAlias());
    assertEquals("custom_key_passphrase_alias", config.getSigningKeyPassphraseAlias());
    assertEquals("custom_keystore_name", config.getSigningKeystoreName());
    assertEquals("PKCS12", config.getSigningKeystoreType());
    assertEquals("custom_keystore_password_alias", config.getSigningKeystorePasswordAlias());
  }

  @Test
  public void testHttpClientTruststoreOptions() {
    GatewayConfigImpl config = new GatewayConfigImpl();

    // Validate default options (backwards compatibility)
    assertEquals("gateway-httpclient-truststore-password", config.getHttpClientTruststorePasswordAlias());
    assertEquals(KeyStore.getDefaultType(), config.getHttpClientTruststoreType());
    assertNull(config.getHttpClientTruststorePath());

    // Validate changed options
    config.set("gateway.httpclient.truststore.password.alias", "custom_password_alias");
    config.set("gateway.httpclient.truststore.path", "custom_path");
    config.set("gateway.httpclient.truststore.type", "custom_type");

    assertEquals("custom_password_alias", config.getHttpClientTruststorePasswordAlias());
    assertEquals("custom_path", config.getHttpClientTruststorePath());
    assertEquals("custom_type", config.getHttpClientTruststoreType());
  }

  @Test
  public void testGatewayTruststoreOptions() {
    GatewayConfigImpl config = new GatewayConfigImpl();

    // Validate default options (backwards compatibility)
    assertEquals("gateway-truststore-password", config.getTruststorePasswordAlias());
    assertEquals(KeyStore.getDefaultType(), config.getTruststoreType());
    assertNull(config.getTruststorePath());

    // Validate changed options
    config.set("gateway.truststore.password.alias", "custom_password_alias");
    config.set("gateway.truststore.path", "custom_path");
    config.set("gateway.truststore.type", "custom_type");

    assertEquals("custom_password_alias", config.getTruststorePasswordAlias());
    assertEquals("custom_path", config.getTruststorePath());
    assertEquals("custom_type", config.getTruststoreType());
  }

  @Test
  public void shouldReturnUserConfiguredRemoteAliasConfigType() throws Exception {
    final String remoteAliasServiceType = "testServiceType";
    GatewayConfigImpl config = new GatewayConfigImpl();
    config.set(config.getRemoteAliasServiceConfigurationPrefix() + REMOTE_ALIAS_SERVICE_TYPE, "testServiceType");
    final Map<String, String> remoteAliasServiceConfiguration = config.getRemoteAliasServiceConfiguration();
    assertTrue(remoteAliasServiceConfiguration.containsKey(REMOTE_ALIAS_SERVICE_TYPE));
    assertEquals(remoteAliasServiceType, remoteAliasServiceConfiguration.get(REMOTE_ALIAS_SERVICE_TYPE));
  }

  @Test
  public void shouldReturnZookeeperAsRemoteAliasConfigTypeIfItIsUnset() throws Exception {
    final Map<String, String> remoteAliasServiceConfiguration = new GatewayConfigImpl().getRemoteAliasServiceConfiguration();
    assertTrue(remoteAliasServiceConfiguration.containsKey(REMOTE_ALIAS_SERVICE_TYPE));
    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"));
  }

  @Test
  public void testDefaultConcurrentSessionLimitParameters() {
    GatewayConfigImpl config = new GatewayConfigImpl();

    assertThat(config.getPrivilegedUsersConcurrentSessionLimit(), is(3));
    assertThat(config.getNonPrivilegedUsersConcurrentSessionLimit(), is(2));
    assertThat(config.getPrivilegedUsers(), is(new HashSet<>()));
    assertThat(config.getNonPrivilegedUsers(), is(new HashSet<>()));
  }

  @Test
  public void testNormalConcurrentSessionLimitParameters() {
    GatewayConfigImpl config = new GatewayConfigImpl();

    config.set("gateway.privileged.users.concurrent.session.limit", "5");
    assertThat(config.getPrivilegedUsersConcurrentSessionLimit(), is(5));
    config.set("gateway.non.privileged.users.concurrent.session.limit", "6");
    assertThat(config.getNonPrivilegedUsersConcurrentSessionLimit(), is(6));
    config.set("gateway.privileged.users", "admin,jeff");
    assertThat(config.getPrivilegedUsers(), is(new HashSet<>(Arrays.asList("admin", "jeff"))));
    config.set("gateway.non.privileged.users", "tom,sam");
    assertThat(config.getNonPrivilegedUsers(), is(new HashSet<>(Arrays.asList("tom", "sam"))));
  }

  @Test
  public void testAbnormalConcurrentSessionLimitParameters() {
    GatewayConfigImpl config = new GatewayConfigImpl();

    config.set("gateway.privileged.users", "");
    assertThat(config.getPrivilegedUsers(), is(new HashSet<>()));
    config.set("gateway.non.privileged.users", "");
    config.set("gateway.privileged.users", "   ");
    assertThat(config.getPrivilegedUsers(), is(new HashSet<>()));
    config.set("gateway.non.privileged.users", "   ");
    assertThat(config.getNonPrivilegedUsers(), is(new HashSet<>()));

    config.set("gateway.privileged.users", " admin , jeff ");
    assertThat(config.getPrivilegedUsers(), is(new HashSet<>(Arrays.asList("admin", "jeff"))));
    config.set("gateway.non.privileged.users", " tom , sam ");
    assertThat(config.getNonPrivilegedUsers(), is(new HashSet<>(Arrays.asList("tom", "sam"))));
    config.set("gateway.privileged.users", "  guest  ");
    assertThat(config.getPrivilegedUsers(), is(new HashSet<>(Arrays.asList("guest"))));
    config.set("gateway.non.privileged.users", "  guest  ");
    assertThat(config.getNonPrivilegedUsers(), is(new HashSet<>(Arrays.asList("guest"))));
  }
}
