knox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From m...@apache.org
Subject [41/49] knox git commit: Merge branch 'master' into KNOX-998-Package_Restructuring
Date Thu, 14 Dec 2017 21:13:28 GMT
http://git-wip-us.apache.org/repos/asf/knox/blob/22a7304a/gateway-discovery-ambari/src/test/java/org/apache/knox/gateway/topology/discovery/ambari/AmbariServiceDiscoveryTest.java
----------------------------------------------------------------------
diff --cc gateway-discovery-ambari/src/test/java/org/apache/knox/gateway/topology/discovery/ambari/AmbariServiceDiscoveryTest.java
index 21627ad,0000000..05fc4eb
mode 100644,000000..100644
--- a/gateway-discovery-ambari/src/test/java/org/apache/knox/gateway/topology/discovery/ambari/AmbariServiceDiscoveryTest.java
+++ b/gateway-discovery-ambari/src/test/java/org/apache/knox/gateway/topology/discovery/ambari/AmbariServiceDiscoveryTest.java
@@@ -1,858 -1,0 +1,870 @@@
 +/**
 + * 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.topology.discovery.ambari;
 +
 +import net.minidev.json.JSONObject;
 +import net.minidev.json.JSONValue;
 +import org.apache.knox.gateway.topology.discovery.ServiceDiscovery;
 +import org.apache.knox.gateway.topology.discovery.ServiceDiscoveryConfig;
 +import org.easymock.EasyMock;
 +import org.junit.Test;
 +
 +import java.util.HashMap;
 +import java.util.List;
 +import java.util.Map;
 +
 +import static org.junit.Assert.assertNotNull;
 +import static org.junit.Assert.assertEquals;
 +import static org.junit.Assert.assertTrue;
 +
 +
 +/**
 + * Test the Ambari ServiceDiscovery implementation.
 + *
 + * N.B. These tests do NOT verify Ambari API responses. They DO validate the Ambari ServiceDiscovery implementation's
 + *      treatment of the responses as they were observed at the time the tests are developed.
 + */
 +public class AmbariServiceDiscoveryTest {
 +
 +    @Test
 +    public void testSingleClusterDiscovery() throws Exception {
 +        final String discoveryAddress = "http://ambarihost:8080";
 +        final String clusterName = "testCluster";
 +        ServiceDiscovery sd = new TestAmbariServiceDiscovery(clusterName);
 +
 +        ServiceDiscoveryConfig sdc = EasyMock.createNiceMock(ServiceDiscoveryConfig.class);
 +        EasyMock.expect(sdc.getAddress()).andReturn(discoveryAddress).anyTimes();
 +        EasyMock.expect(sdc.getUser()).andReturn(null).anyTimes();
 +        EasyMock.replay(sdc);
 +
 +        ServiceDiscovery.Cluster cluster = sd.discover(sdc, clusterName);
 +        assertNotNull(cluster);
 +        assertEquals(clusterName, cluster.getName());
 +        assertTrue(AmbariCluster.class.isAssignableFrom(cluster.getClass()));
 +        assertEquals(6, ((AmbariCluster) cluster).getComponents().size());
 +
 +//        printServiceURLs(cluster);
 +    }
 +
 +
 +    @Test
 +    public void testBulkClusterDiscovery() throws Exception {
 +        final String discoveryAddress = "http://ambarihost:8080";
 +        final String clusterName = "anotherCluster";
 +        ServiceDiscovery sd = new TestAmbariServiceDiscovery(clusterName);
 +
 +        ServiceDiscoveryConfig sdc = EasyMock.createNiceMock(ServiceDiscoveryConfig.class);
 +        EasyMock.expect(sdc.getAddress()).andReturn(discoveryAddress).anyTimes();
 +        EasyMock.expect(sdc.getUser()).andReturn(null).anyTimes();
 +        EasyMock.replay(sdc);
 +
 +        Map<String, ServiceDiscovery.Cluster> clusters = sd.discover(sdc);
 +        assertNotNull(clusters);
 +        assertEquals(1, clusters.size());
 +        ServiceDiscovery.Cluster cluster = clusters.get(clusterName);
 +        assertNotNull(cluster);
 +        assertEquals(clusterName, cluster.getName());
 +        assertTrue(AmbariCluster.class.isAssignableFrom(cluster.getClass()));
 +        assertEquals(6, ((AmbariCluster) cluster).getComponents().size());
 +
 +//        printServiceURLs(cluster, "NAMENODE", "WEBHCAT", "OOZIE", "RESOURCEMANAGER");
 +    }
 +
 +
 +    private static void printServiceURLs(ServiceDiscovery.Cluster cluster) {
 +        final String[] services = new String[]{"NAMENODE",
 +                                               "JOBTRACKER",
 +                                               "WEBHDFS",
 +                                               "WEBHCAT",
 +                                               "OOZIE",
 +                                               "WEBHBASE",
 +                                               "HIVE",
 +                                               "RESOURCEMANAGER"};
 +        printServiceURLs(cluster, services);
 +    }
 +
 +
 +    private static void printServiceURLs(ServiceDiscovery.Cluster cluster, String...services) {
 +        for (String name : services) {
 +            StringBuilder sb = new StringBuilder();
 +            List<String> urls = cluster.getServiceURLs(name);
 +            if (urls != null && !urls.isEmpty()) {
 +                for (String url : urls) {
 +                    sb.append(url);
 +                    sb.append(" ");
 +                }
 +            }
 +            System.out.println(String.format("%18s: %s", name, sb.toString()));
 +        }
 +    }
 +
 +
 +    /**
 +     * ServiceDiscovery implementation derived from AmbariServiceDiscovery, so the invokeREST method can be overridden
 +     * to eliminate the need to perform actual HTTP interactions with a real Ambari endpoint.
 +     */
 +    private static final class TestAmbariServiceDiscovery extends AmbariServiceDiscovery {
 +
++        final static String CLUSTER_PLACEHOLDER = TestRESTInvoker.CLUSTER_PLACEHOLDER;
++
++        TestAmbariServiceDiscovery(String clusterName) {
++            super(new TestRESTInvoker(clusterName));
++        }
++
++    }
++
++    private static final class TestRESTInvoker extends RESTInvoker {
++
 +        final static String CLUSTER_PLACEHOLDER = "CLUSTER_NAME";
 +
 +        private Map<String, JSONObject> cannedResponses = new HashMap<>();
 +
-         TestAmbariServiceDiscovery(String clusterName) {
-             cannedResponses.put(AMBARI_CLUSTERS_URI,
-                                 (JSONObject) JSONValue.parse(CLUSTERS_JSON_TEMPLATE.replaceAll(CLUSTER_PLACEHOLDER,
-                                                                                                clusterName)));
++        TestRESTInvoker(String clusterName) {
++            super(null);
++
++            cannedResponses.put(AmbariServiceDiscovery.AMBARI_CLUSTERS_URI,
++                    (JSONObject) JSONValue.parse(CLUSTERS_JSON_TEMPLATE.replaceAll(CLUSTER_PLACEHOLDER,
++                            clusterName)));
 +
-             cannedResponses.put(String.format(AMBARI_HOSTROLES_URI, clusterName),
-                                 (JSONObject) JSONValue.parse(HOSTROLES_JSON_TEMPLATE.replaceAll(CLUSTER_PLACEHOLDER,
-                                                                                                 clusterName)));
++            cannedResponses.put(String.format(AmbariServiceDiscovery.AMBARI_HOSTROLES_URI, clusterName),
++                    (JSONObject) JSONValue.parse(HOSTROLES_JSON_TEMPLATE.replaceAll(CLUSTER_PLACEHOLDER,
++                            clusterName)));
 +
-             cannedResponses.put(String.format(AMBARI_SERVICECONFIGS_URI, clusterName),
-                                 (JSONObject) JSONValue.parse(SERVICECONFIGS_JSON_TEMPLATE.replaceAll(CLUSTER_PLACEHOLDER,
-                                                                                                      clusterName)));
++            cannedResponses.put(String.format(AmbariServiceDiscovery.AMBARI_SERVICECONFIGS_URI, clusterName),
++                    (JSONObject) JSONValue.parse(SERVICECONFIGS_JSON_TEMPLATE.replaceAll(CLUSTER_PLACEHOLDER,
++                            clusterName)));
 +        }
 +
 +        @Override
-         protected JSONObject invokeREST(String url, String username, String passwordAlias) {
++        JSONObject invoke(String url, String username, String passwordAlias) {
 +            return cannedResponses.get(url.substring(url.indexOf("/api")));
 +        }
 +    }
 +
 +
 +    ////////////////////////////////////////////////////////////////////////
 +    //  JSON response templates, based on actual response content excerpts
 +    ////////////////////////////////////////////////////////////////////////
 +
 +    private static final String CLUSTERS_JSON_TEMPLATE =
 +    "{\n" +
 +    "  \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters\",\n" +
 +    "  \"items\" : [\n" +
 +    "    {\n" +
 +    "      \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "      \"Clusters\" : {\n" +
 +    "        \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "        \"version\" : \"HDP-2.6\"\n" +
 +    "      }\n" +
 +    "    }\n" +
 +    "  ]" +
 +    "}";
 +
 +
 +    private static final String HOSTROLES_JSON_TEMPLATE =
 +    "{\n" +
 +    "  \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services?fields=components/host_components/HostRoles\",\n" +
 +    "  \"items\" : [\n" +
 +    "    {\n" +
 +    "      \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/AMBARI_METRICS\",\n" +
 +    "      \"ServiceInfo\" : {\n" +
 +    "        \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "        \"service_name\" : \"AMBARI_METRICS\"\n" +
 +    "      },\n" +
 +    "      \"components\" : [\n" +
 +    "        {\n" +
 +    "          \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/AMBARI_METRICS/components/METRICS_COLLECTOR\",\n" +
 +    "          \"ServiceComponentInfo\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"component_name\" : \"METRICS_COLLECTOR\",\n" +
 +    "            \"service_name\" : \"AMBARI_METRICS\"\n" +
 +    "          },\n" +
 +    "          \"host_components\" : [\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6403.ambari.apache.org/host_components/METRICS_COLLECTOR\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"METRICS_COLLECTOR\",\n" +
 +    "                \"host_name\" : \"c6403.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6403.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"AMBARI_METRICS\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\",\n" +
 +    "              }\n" +
 +    "            }\n" +
 +    "          ]\n" +
 +    "        },\n" +
 +    "        {\n" +
 +    "          \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/HBASE/components/HBASE_MASTER\",\n" +
 +    "          \"ServiceComponentInfo\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"component_name\" : \"HBASE_MASTER\",\n" +
 +    "            \"service_name\" : \"HBASE\"\n" +
 +    "          },\n" +
 +    "          \"host_components\" : [\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6401.ambari.apache.org/host_components/HBASE_MASTER\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"HBASE_MASTER\",\n" +
 +    "                \"host_name\" : \"c6401.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6401.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"HBASE\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\",\n" +
 +    "              }\n" +
 +    "            }\n" +
 +    "          ]\n" +
 +    "        }\n" +
 +    "      ]\n" +
 +    "    },\n" +
 +    "    {\n" +
 +    "      \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/HDFS\",\n" +
 +    "      \"ServiceInfo\" : {\n" +
 +    "        \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "        \"service_name\" : \"HDFS\"\n" +
 +    "      },\n" +
 +    "      \"components\" : [\n" +
 +    "        {\n" +
 +    "          \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/HDFS/components/NAMENODE\",\n" +
 +    "          \"ServiceComponentInfo\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"component_name\" : \"NAMENODE\",\n" +
 +    "            \"service_name\" : \"HDFS\"\n" +
 +    "          },\n" +
 +    "          \"host_components\" : [\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6401.ambari.apache.org/host_components/NAMENODE\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"NAMENODE\",\n" +
 +    "                \"host_name\" : \"c6401.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6401.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"HDFS\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\",\n" +
 +    "              }\n" +
 +    "            }\n" +
 +    "          ]\n" +
 +    "        },\n" +
 +    "        {\n" +
 +    "          \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/HDFS/components/SECONDARY_NAMENODE\",\n" +
 +    "          \"ServiceComponentInfo\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"component_name\" : \"SECONDARY_NAMENODE\",\n" +
 +    "            \"service_name\" : \"HDFS\"\n" +
 +    "          },\n" +
 +    "          \"host_components\" : [\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6402.ambari.apache.org/host_components/SECONDARY_NAMENODE\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"SECONDARY_NAMENODE\",\n" +
 +    "                \"host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"HDFS\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\",\n" +
 +    "              }\n" +
 +    "            }\n" +
 +    "          ]\n" +
 +    "        }\n" +
 +    "      ]\n" +
 +    "    },\n" +
 +    "    {\n" +
 +    "      \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/HIVE\",\n" +
 +    "      \"ServiceInfo\" : {\n" +
 +    "        \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "        \"service_name\" : \"HIVE\"\n" +
 +    "      },\n" +
 +    "      \"components\" : [\n" +
 +    "        {\n" +
 +    "          \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/HIVE/components/HCAT\",\n" +
 +    "          \"ServiceComponentInfo\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"component_name\" : \"HCAT\",\n" +
 +    "            \"service_name\" : \"HIVE\"\n" +
 +    "          },\n" +
 +    "          \"host_components\" : [\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6403.ambari.apache.org/host_components/HCAT\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"HCAT\",\n" +
 +    "                \"host_name\" : \"c6403.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6403.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"HIVE\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\",\n" +
 +    "              }\n" +
 +    "            }\n" +
 +    "          ]\n" +
 +    "        }\n" +
 +    "        {\n" +
 +    "          \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/HIVE/components/HIVE_METASTORE\",\n" +
 +    "          \"ServiceComponentInfo\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"component_name\" : \"HIVE_METASTORE\",\n" +
 +    "            \"service_name\" : \"HIVE\"\n" +
 +    "          },\n" +
 +    "          \"host_components\" : [\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6402.ambari.apache.org/host_components/HIVE_METASTORE\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"HIVE_METASTORE\",\n" +
 +    "                \"host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"HIVE\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\",\n" +
 +    "              }\n" +
 +    "            }\n" +
 +    "          ]\n" +
 +    "        },\n" +
 +    "        {\n" +
 +    "          \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/HIVE/components/HIVE_SERVER\",\n" +
 +    "          \"ServiceComponentInfo\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"component_name\" : \"HIVE_SERVER\",\n" +
 +    "            \"service_name\" : \"HIVE\"\n" +
 +    "          },\n" +
 +    "          \"host_components\" : [\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6402.ambari.apache.org/host_components/HIVE_SERVER\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"HIVE_SERVER\",\n" +
 +    "                \"host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"HIVE\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\",\n" +
 +    "              }\n" +
 +    "            }\n" +
 +    "          ]\n" +
 +    "        },\n" +
 +    "        {\n" +
 +    "          \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/HIVE/components/WEBHCAT_SERVER\",\n" +
 +    "          \"ServiceComponentInfo\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"component_name\" : \"WEBHCAT_SERVER\",\n" +
 +    "            \"service_name\" : \"HIVE\"\n" +
 +    "          },\n" +
 +    "          \"host_components\" : [\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6402.ambari.apache.org/host_components/WEBHCAT_SERVER\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"WEBHCAT_SERVER\",\n" +
 +    "                \"host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"HIVE\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\",\n" +
 +    "              }\n" +
 +    "            }\n" +
 +    "          ]\n" +
 +    "        }\n" +
 +    "      ]\n" +
 +    "    },\n" +
 +    "    {\n" +
 +    "      \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/OOZIE\",\n" +
 +    "      \"ServiceInfo\" : {\n" +
 +    "        \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "        \"service_name\" : \"OOZIE\"\n" +
 +    "      },\n" +
 +    "      \"components\" : [\n" +
 +    "        {\n" +
 +    "          \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/OOZIE/components/OOZIE_SERVER\",\n" +
 +    "          \"ServiceComponentInfo\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"component_name\" : \"OOZIE_SERVER\",\n" +
 +    "            \"service_name\" : \"OOZIE\"\n" +
 +    "          },\n" +
 +    "          \"host_components\" : [\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6402.ambari.apache.org/host_components/OOZIE_SERVER\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"OOZIE_SERVER\",\n" +
 +    "                \"host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"OOZIE\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\"\n" +
 +    "              }\n" +
 +    "            }\n" +
 +    "          ]\n" +
 +    "        }\n" +
 +    "      ]\n" +
 +    "    },\n" +
 +    "    {\n" +
 +    "      \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/YARN\",\n" +
 +    "      \"ServiceInfo\" : {\n" +
 +    "        \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "        \"service_name\" : \"YARN\"\n" +
 +    "      },\n" +
 +    "      \"components\" : [\n" +
 +    "        {\n" +
 +    "          \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/YARN/components/APP_TIMELINE_SERVER\",\n" +
 +    "          \"ServiceComponentInfo\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"component_name\" : \"APP_TIMELINE_SERVER\",\n" +
 +    "            \"service_name\" : \"YARN\"\n" +
 +    "          },\n" +
 +    "          \"host_components\" : [\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6402.ambari.apache.org/host_components/APP_TIMELINE_SERVER\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"APP_TIMELINE_SERVER\",\n" +
 +    "                \"host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"YARN\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\"\n" +
 +    "              }\n" +
 +    "            }\n" +
 +    "          ]\n" +
 +    "        },\n" +
 +    "        {\n" +
 +    "          \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/YARN/components/NODEMANAGER\",\n" +
 +    "          \"ServiceComponentInfo\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"component_name\" : \"NODEMANAGER\",\n" +
 +    "            \"service_name\" : \"YARN\"\n" +
 +    "          },\n" +
 +    "          \"host_components\" : [\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6403.ambari.apache.org/host_components/NODEMANAGER\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"NODEMANAGER\",\n" +
 +    "                \"host_name\" : \"c6403.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6403.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"YARN\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\"\n" +
 +    "              }\n" +
 +    "            }\n" +
 +    "          ]\n" +
 +    "        },\n" +
 +    "        {\n" +
 +    "          \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/YARN/components/RESOURCEMANAGER\",\n" +
 +    "          \"ServiceComponentInfo\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"component_name\" : \"RESOURCEMANAGER\",\n" +
 +    "            \"service_name\" : \"YARN\"\n" +
 +    "          },\n" +
 +    "          \"host_components\" : [\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6402.ambari.apache.org/host_components/RESOURCEMANAGER\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"RESOURCEMANAGER\",\n" +
 +    "                \"ha_state\" : \"ACTIVE\",\n" +
 +    "                \"host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"YARN\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\"\n" +
 +    "              }\n" +
 +    "            }\n" +
 +    "          ]\n" +
 +    "        }\n" +
 +    "      ]\n" +
 +    "    },\n" +
 +    "    {\n" +
 +    "      \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/ZOOKEEPER\",\n" +
 +    "      \"ServiceInfo\" : {\n" +
 +    "        \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "        \"service_name\" : \"ZOOKEEPER\"\n" +
 +    "      },\n" +
 +    "      \"components\" : [\n" +
 +    "        {\n" +
 +    "          \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/services/ZOOKEEPER/components/ZOOKEEPER_SERVER\",\n" +
 +    "          \"ServiceComponentInfo\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"component_name\" : \"ZOOKEEPER_SERVER\",\n" +
 +    "            \"service_name\" : \"ZOOKEEPER\"\n" +
 +    "          },\n" +
 +    "          \"host_components\" : [\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6401.ambari.apache.org/host_components/ZOOKEEPER_SERVER\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"ZOOKEEPER_SERVER\",\n" +
 +    "                \"host_name\" : \"c6401.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6401.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"ZOOKEEPER\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\"\n" +
 +    "              }\n" +
 +    "            },\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6402.ambari.apache.org/host_components/ZOOKEEPER_SERVER\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"ZOOKEEPER_SERVER\",\n" +
 +    "                \"host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6402.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"ZOOKEEPER\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\"\n" +
 +    "              }\n" +
 +    "            },\n" +
 +    "            {\n" +
 +    "              \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/hosts/c6403.ambari.apache.org/host_components/ZOOKEEPER_SERVER\",\n" +
 +    "              \"HostRoles\" : {\n" +
 +    "                \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "                \"component_name\" : \"ZOOKEEPER_SERVER\",\n" +
 +    "                \"host_name\" : \"c6403.ambari.apache.org\",\n" +
 +    "                \"public_host_name\" : \"c6403.ambari.apache.org\",\n" +
 +    "                \"service_name\" : \"ZOOKEEPER\",\n" +
 +    "                \"stack_id\" : \"HDP-2.6\"\n" +
 +    "              }\n" +
 +    "            }\n" +
 +    "          ]\n" +
 +    "        }\n" +
 +    "      ]\n" +
 +    "    }\n" +
 +    "  ]\n" +
 +    "}\n";
 +
 +
 +    private static final String SERVICECONFIGS_JSON_TEMPLATE =
 +    "{\n" +
 +    "  \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/configurations/service_config_versions?is_current=true\",\n" +
 +    "  \"items\" : [\n" +
 +    "    {\n" +
 +    "      \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/configurations/service_config_versions?service_name=HBASE&service_config_version=1\",\n" +
 +    "      \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "      \"configurations\" : [\n" +
 +    "        {\n" +
 +    "          \"Config\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"stack_id\" : \"HDP-2.6\"\n" +
 +    "          },\n" +
 +    "          \"type\" : \"hbase-site\",\n" +
 +    "          \"tag\" : \"version1503410563715\",\n" +
 +    "          \"version\" : 1,\n" +
 +    "          \"properties\" : {\n" +
 +    "            \"hbase.master.info.bindAddress\" : \"0.0.0.0\",\n" +
 +    "            \"hbase.master.info.port\" : \"16010\",\n" +
 +    "            \"hbase.master.port\" : \"16000\",\n" +
 +    "            \"hbase.regionserver.info.port\" : \"16030\",\n" +
 +    "            \"hbase.regionserver.port\" : \"16020\",\n" +
 +    "            \"hbase.zookeeper.property.clientPort\" : \"2181\",\n" +
 +    "            \"hbase.zookeeper.quorum\" : \"c6403.ambari.apache.org,c6402.ambari.apache.org,c6401.ambari.apache.org\",\n" +
 +    "            \"hbase.zookeeper.useMulti\" : \"true\",\n" +
 +    "            \"zookeeper.znode.parent\" : \"/hbase-unsecure\"\n" +
 +    "          },\n" +
 +    "          \"properties_attributes\" : { }\n" +
 +    "        },\n" +
 +    "      ],\n" +
 +    "      \"is_current\" : true,\n" +
 +    "      \"service_config_version\" : 1,\n" +
 +    "      \"service_config_version_note\" : \"Initial configurations for HBase\",\n" +
 +    "      \"service_name\" : \"HBASE\",\n" +
 +    "      \"stack_id\" : \"HDP-2.6\",\n" +
 +    "      \"user\" : \"admin\"\n" +
 +    "    },\n" +
 +    "    {\n" +
 +    "      \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/configurations/service_config_versions?service_name=HDFS&service_config_version=2\",\n" +
 +    "      \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "      \"configurations\" : [\n" +
 +    "        {\n" +
 +    "          \"Config\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"stack_id\" : \"HDP-2.6\"\n" +
 +    "          },\n" +
 +    "          \"type\" : \"hdfs-site\",\n" +
 +    "          \"tag\" : \"version1\",\n" +
 +    "          \"version\" : 1,\n" +
 +    "          \"properties\" : {\n" +
 +    "            \"dfs.cluster.administrators\" : \" hdfs\",\n" +
 +    "            \"dfs.datanode.address\" : \"0.0.0.0:50010\",\n" +
 +    "            \"dfs.datanode.http.address\" : \"0.0.0.0:50075\",\n" +
 +    "            \"dfs.datanode.https.address\" : \"0.0.0.0:50475\",\n" +
 +    "            \"dfs.datanode.ipc.address\" : \"0.0.0.0:8010\",\n" +
 +    "            \"dfs.http.policy\" : \"HTTP_ONLY\",\n" +
 +    "            \"dfs.https.port\" : \"50470\",\n" +
 +    "            \"dfs.journalnode.http-address\" : \"0.0.0.0:8480\",\n" +
 +    "            \"dfs.journalnode.https-address\" : \"0.0.0.0:8481\",\n" +
 +    "            \"dfs.namenode.http-address\" : \"c6401.ambari.apache.org:50070\",\n" +
 +    "            \"dfs.namenode.https-address\" : \"c6401.ambari.apache.org:50470\",\n" +
 +    "            \"dfs.namenode.rpc-address\" : \"c6401.ambari.apache.org:8020\",\n" +
 +    "            \"dfs.namenode.secondary.http-address\" : \"c6402.ambari.apache.org:50090\",\n" +
 +    "            \"dfs.webhdfs.enabled\" : \"true\"\n" +
 +    "          },\n" +
 +    "          \"properties_attributes\" : {\n" +
 +    "            \"final\" : {\n" +
 +    "              \"dfs.webhdfs.enabled\" : \"true\",\n" +
 +    "              \"dfs.namenode.http-address\" : \"true\",\n" +
 +    "              \"dfs.support.append\" : \"true\",\n" +
 +    "              \"dfs.namenode.name.dir\" : \"true\",\n" +
 +    "              \"dfs.datanode.failed.volumes.tolerated\" : \"true\",\n" +
 +    "              \"dfs.datanode.data.dir\" : \"true\"\n" +
 +    "            }\n" +
 +    "          }\n" +
 +    "        },\n" +
 +    "        {\n" +
 +    "          \"Config\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"stack_id\" : \"HDP-2.6\"\n" +
 +    "          },\n" +
 +    "          \"type\" : \"core-site\",\n" +
 +    "          \"tag\" : \"version1502131215159\",\n" +
 +    "          \"version\" : 2,\n" +
 +    "          \"properties\" : {\n" +
 +    "            \"hadoop.http.authentication.simple.anonymous.allowed\" : \"true\",\n" +
 +    "            \"net.topology.script.file.name\" : \"/etc/hadoop/conf/topology_script.py\"\n" +
 +    "          },\n" +
 +    "          \"properties_attributes\" : {\n" +
 +    "            \"final\" : {\n" +
 +    "              \"fs.defaultFS\" : \"true\"\n" +
 +    "            }\n" +
 +    "          }\n" +
 +    "        }\n" +
 +    "      ],\n" +
 +    "      \"is_current\" : true,\n" +
 +    "      \"service_config_version\" : 2,\n" +
 +    "      \"service_config_version_note\" : \"knox trusted proxy support\",\n" +
 +    "      \"service_name\" : \"HDFS\",\n" +
 +    "      \"stack_id\" : \"HDP-2.6\",\n" +
 +    "      \"user\" : \"admin\"\n" +
 +    "    },\n" +
 +    "    {\n" +
 +    "      \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/configurations/service_config_versions?service_name=HIVE&service_config_version=3\",\n" +
 +    "      \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "      \"configurations\" : [\n" +
 +    "        {\n" +
 +    "          \"Config\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"stack_id\" : \"HDP-2.6\"\n" +
 +    "          },\n" +
 +    "          \"type\" : \"hive-env\",\n" +
 +    "          \"tag\" : \"version1\",\n" +
 +    "          \"version\" : 1,\n" +
 +    "          \"properties\" : {\n" +
 +    "            \"hive_security_authorization\" : \"None\",\n" +
 +    "            \"webhcat_user\" : \"hcat\"\n" +
 +    "          },\n" +
 +    "          \"properties_attributes\" : { }\n" +
 +    "        },\n" +
 +    "        {\n" +
 +    "          \"Config\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"stack_id\" : \"HDP-2.6\"\n" +
 +    "          },\n" +
 +    "          \"type\" : \"hiveserver2-site\",\n" +
 +    "          \"tag\" : \"version1\",\n" +
 +    "          \"version\" : 1,\n" +
 +    "          \"properties\" : {\n" +
 +    "            \"hive.metastore.metrics.enabled\" : \"true\",\n" +
 +    "            \"hive.security.authorization.enabled\" : \"false\",\n" +
 +    "            \"hive.service.metrics.hadoop2.component\" : \"hiveserver2\",\n" +
 +    "            \"hive.service.metrics.reporter\" : \"HADOOP2\"\n" +
 +    "          },\n" +
 +    "          \"properties_attributes\" : { }\n" +
 +    "        },\n" +
 +    "        {\n" +
 +    "          \"Config\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"stack_id\" : \"HDP-2.6\"\n" +
 +    "          },\n" +
 +    "          \"type\" : \"hive-interactive-site\",\n" +
 +    "          \"tag\" : \"version1\",\n" +
 +    "          \"version\" : 1,\n" +
 +    "          \"properties\" : {\n" +
 +    "            \"hive.server2.enable.doAs\" : \"false\",\n" +
 +    "            \"hive.server2.tez.default.queues\" : \"default\",\n" +
 +    "            \"hive.server2.tez.initialize.default.sessions\" : \"true\",\n" +
 +    "            \"hive.server2.tez.sessions.custom.queue.allowed\" : \"ignore\",\n" +
 +    "            \"hive.server2.tez.sessions.per.default.queue\" : \"1\",\n" +
 +    "            \"hive.server2.tez.sessions.restricted.configs\" : \"hive.execution.mode,hive.execution.engine\",\n" +
 +    "            \"hive.server2.thrift.http.port\" : \"10501\",\n" +
 +    "            \"hive.server2.thrift.port\" : \"10500\",\n" +
 +    "            \"hive.server2.webui.port\" : \"10502\",\n" +
 +    "            \"hive.server2.webui.use.ssl\" : \"false\",\n" +
 +    "            \"hive.server2.zookeeper.namespace\" : \"hiveserver2-hive2\"\n" +
 +    "          },\n" +
 +    "          \"properties_attributes\" : { }\n" +
 +    "        },\n" +
 +    "        {\n" +
 +    "          \"Config\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"stack_id\" : \"HDP-2.6\"\n" +
 +    "          },\n" +
 +    "          \"type\" : \"tez-interactive-site\",\n" +
 +    "          \"tag\" : \"version1\",\n" +
 +    "          \"version\" : 1,\n" +
 +    "          \"properties\" : {\n" +
 +    "            \"tez.am.am-rm.heartbeat.interval-ms.max\" : \"10000\",\n" +
 +    "            \"tez.am.client.heartbeat.poll.interval.millis\" : \"6000\",\n" +
 +    "            \"tez.am.client.heartbeat.timeout.secs\" : \"90\"\n" +
 +    "          },\n" +
 +    "          \"properties_attributes\" : { }\n" +
 +    "        },\n" +
 +    "        {\n" +
 +    "          \"Config\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"stack_id\" : \"HDP-2.6\"\n" +
 +    "          },\n" +
 +    "          \"type\" : \"hive-site\",\n" +
 +    "          \"tag\" : \"version1502130841736\",\n" +
 +    "          \"version\" : 2,\n" +
 +    "          \"properties\" : {\n" +
 +    "            \"hive.metastore.sasl.enabled\" : \"false\",\n" +
 +    "            \"hive.metastore.server.max.threads\" : \"100000\",\n" +
 +    "            \"hive.metastore.uris\" : \"thrift://c6402.ambari.apache.org:9083\",\n" +
 +    "            \"hive.server2.allow.user.substitution\" : \"true\",\n" +
 +    "            \"hive.server2.authentication\" : \"NONE\",\n" +
 +    "            \"hive.server2.authentication.spnego.keytab\" : \"HTTP/_HOST@EXAMPLE.COM\",\n" +
 +    "            \"hive.server2.authentication.spnego.principal\" : \"/etc/security/keytabs/spnego.service.keytab\",\n" +
 +    "            \"hive.server2.enable.doAs\" : \"true\",\n" +
 +    "            \"hive.server2.support.dynamic.service.discovery\" : \"true\",\n" +
 +    "            \"hive.server2.thrift.http.path\" : \"cliservice\",\n" +
 +    "            \"hive.server2.thrift.http.port\" : \"10001\",\n" +
 +    "            \"hive.server2.thrift.max.worker.threads\" : \"500\",\n" +
 +    "            \"hive.server2.thrift.port\" : \"10000\",\n" +
 +    "            \"hive.server2.thrift.sasl.qop\" : \"auth\",\n" +
 +    "            \"hive.server2.transport.mode\" : \"http\",\n" +
 +    "            \"hive.server2.use.SSL\" : \"false\",\n" +
 +    "            \"hive.server2.zookeeper.namespace\" : \"hiveserver2\"\n" +
 +    "          },\n" +
 +    "          \"properties_attributes\" : {\n" +
 +    "            \"hidden\" : {\n" +
 +    "              \"javax.jdo.option.ConnectionPassword\" : \"HIVE_CLIENT,WEBHCAT_SERVER,HCAT,CONFIG_DOWNLOAD\"\n" +
 +    "            }\n" +
 +    "          }\n" +
 +    "        },\n" +
 +    "        {\n" +
 +    "          \"Config\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"stack_id\" : \"HDP-2.6\"\n" +
 +    "          },\n" +
 +    "          \"type\" : \"webhcat-site\",\n" +
 +    "          \"tag\" : \"version1502131111746\",\n" +
 +    "          \"version\" : 2,\n" +
 +    "          \"properties\" : {\n" +
 +    "            \"templeton.port\" : \"50111\",\n" +
 +    "            \"templeton.zookeeper.hosts\" : \"c6403.ambari.apache.org:2181,c6401.ambari.apache.org:2181,c6402.ambari.apache.org:2181\",\n" +
 +    "            \"webhcat.proxyuser.knox.groups\" : \"users\",\n" +
 +    "            \"webhcat.proxyuser.knox.hosts\" : \"*\",\n" +
 +    "            \"webhcat.proxyuser.root.groups\" : \"*\",\n" +
 +    "            \"webhcat.proxyuser.root.hosts\" : \"c6401.ambari.apache.org\"\n" +
 +    "          },\n" +
 +    "          \"properties_attributes\" : { }\n" +
 +    "        }\n" +
 +    "      ],\n" +
 +    "      \"createtime\" : 1502131110745,\n" +
 +    "      \"group_id\" : -1,\n" +
 +    "      \"group_name\" : \"Default\",\n" +
 +    "      \"hosts\" : [ ],\n" +
 +    "      \"is_cluster_compatible\" : true,\n" +
 +    "      \"is_current\" : true,\n" +
 +    "      \"service_config_version\" : 3,\n" +
 +    "      \"service_config_version_note\" : \"knox trusted proxy support\",\n" +
 +    "      \"service_name\" : \"HIVE\",\n" +
 +    "      \"stack_id\" : \"HDP-2.6\",\n" +
 +    "      \"user\" : \"admin\"\n" +
 +    "    },\n" +
 +    "    {\n" +
 +    "      \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/configurations/service_config_versions?service_name=OOZIE&service_config_version=3\",\n" +
 +    "      \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "      \"configurations\" : [\n" +
 +    "        {\n" +
 +    "          \"Config\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"stack_id\" : \"HDP-2.6\"\n" +
 +    "          },\n" +
 +    "          \"type\" : \"oozie-site\",\n" +
 +    "          \"tag\" : \"version1502131137103\",\n" +
 +    "          \"version\" : 3,\n" +
 +    "          \"properties\" : {\n" +
 +    "            \"oozie.base.url\" : \"http://c6402.ambari.apache.org:11000/oozie\",\n" +
 +    "          },\n" +
 +    "          \"properties_attributes\" : { }\n" +
 +    "        }\n" +
 +    "      ],\n" +
 +    "      \"is_current\" : true,\n" +
 +    "      \"service_config_version\" : 3,\n" +
 +    "      \"service_name\" : \"OOZIE\",\n" +
 +    "      \"stack_id\" : \"HDP-2.6\",\n" +
 +    "      \"user\" : \"admin\"\n" +
 +    "    },\n" +
 +    "    {\n" +
 +    "      \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/configurations/service_config_versions?service_name=TEZ&service_config_version=1\",\n" +
 +    "      \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "      \"configurations\" : [\n" +
 +    "        {\n" +
 +    "          \"Config\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"stack_id\" : \"HDP-2.6\"\n" +
 +    "          },\n" +
 +    "          \"type\" : \"tez-site\",\n" +
 +    "          \"tag\" : \"version1\",\n" +
 +    "          \"version\" : 1,\n" +
 +    "          \"properties\" : {\n" +
 +    "            \"tez.use.cluster.hadoop-libs\" : \"false\"\n" +
 +    "          },\n" +
 +    "          \"properties_attributes\" : { }\n" +
 +    "        }\n" +
 +    "      ],\n" +
 +    "      \"createtime\" : 1502122253525,\n" +
 +    "      \"group_id\" : -1,\n" +
 +    "      \"group_name\" : \"Default\",\n" +
 +    "      \"hosts\" : [ ],\n" +
 +    "      \"is_cluster_compatible\" : true,\n" +
 +    "      \"is_current\" : true,\n" +
 +    "      \"service_config_version\" : 1,\n" +
 +    "      \"service_config_version_note\" : \"Initial configurations for Tez\",\n" +
 +    "      \"service_name\" : \"TEZ\",\n" +
 +    "      \"stack_id\" : \"HDP-2.6\",\n" +
 +    "      \"user\" : \"admin\"\n" +
 +    "    },\n" +
 +    "    {\n" +
 +    "      \"href\" : \"http://c6401.ambari.apache.org:8080/api/v1/clusters/"+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"/configurations/service_config_versions?service_name=YARN&service_config_version=1\",\n" +
 +    "      \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "      \"configurations\" : [\n" +
 +    "        {\n" +
 +    "          \"Config\" : {\n" +
 +    "            \"cluster_name\" : \""+TestAmbariServiceDiscovery.CLUSTER_PLACEHOLDER+"\",\n" +
 +    "            \"stack_id\" : \"HDP-2.6\"\n" +
 +    "          },\n" +
 +    "          \"type\" : \"yarn-site\",\n" +
 +    "          \"tag\" : \"version1\",\n" +
 +    "          \"version\" : 1,\n" +
 +    "          \"properties\" : {\n" +
 +    "            \"hadoop.registry.rm.enabled\" : \"true\",\n" +
 +    "            \"hadoop.registry.zk.quorum\" : \"c6403.ambari.apache.org:2181,c6401.ambari.apache.org:2181,c6402.ambari.apache.org:2181\",\n" +
 +    "            \"yarn.acl.enable\" : \"false\",\n" +
 +    "            \"yarn.http.policy\" : \"HTTP_ONLY\",\n" +
 +    "            \"yarn.nodemanager.address\" : \"0.0.0.0:45454\",\n" +
 +    "            \"yarn.nodemanager.bind-host\" : \"0.0.0.0\",\n" +
 +    "            \"yarn.resourcemanager.address\" : \"c6402.ambari.apache.org:8050\",\n" +
 +    "            \"yarn.resourcemanager.admin.address\" : \"c6402.ambari.apache.org:8141\",\n" +
 +    "            \"yarn.resourcemanager.ha.enabled\" : \"false\",\n" +
 +    "            \"yarn.resourcemanager.hostname\" : \"c6402.ambari.apache.org\",\n" +
 +    "            \"yarn.resourcemanager.resource-tracker.address\" : \"c6402.ambari.apache.org:8025\",\n" +
 +    "            \"yarn.resourcemanager.scheduler.address\" : \"c6402.ambari.apache.org:8030\",\n" +
 +    "            \"yarn.resourcemanager.webapp.address\" : \"c6402.ambari.apache.org:8088\",\n" +
 +    "            \"yarn.resourcemanager.webapp.delegation-token-auth-filter.enabled\" : \"false\",\n" +
 +    "            \"yarn.resourcemanager.webapp.https.address\" : \"c6402.ambari.apache.org:8090\",\n" +
 +    "            \"yarn.resourcemanager.zk-address\" : \"c6403.ambari.apache.org:2181,c6401.ambari.apache.org:2181,c6402.ambari.apache.org:2181\"\n" +
 +    "          },\n" +
 +    "          \"properties_attributes\" : { }\n" +
 +    "        }\n" +
 +    "      ],\n" +
 +    "      \"is_current\" : true,\n" +
 +    "      \"service_config_version\" : 1,\n" +
 +    "      \"service_name\" : \"YARN\",\n" +
 +    "      \"stack_id\" : \"HDP-2.6\",\n" +
 +    "      \"user\" : \"admin\"\n" +
 +    "    }\n" +
 +    "  ]\n" +
 +    "}";
 +
 +}

http://git-wip-us.apache.org/repos/asf/knox/blob/22a7304a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java
----------------------------------------------------------------------
diff --cc gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java
index fe39f25,0000000..6e04932
mode 100644,000000..100644
--- a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java
+++ b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jDispatcherFilter.java
@@@ -1,214 -1,0 +1,215 @@@
 +/**
 + * 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.pac4j.filter;
 +
 +import org.apache.knox.gateway.i18n.messages.MessagesFactory;
 +import org.apache.knox.gateway.pac4j.Pac4jMessages;
 +import org.apache.knox.gateway.pac4j.session.KnoxSessionStore;
 +import org.apache.knox.gateway.services.GatewayServices;
 +import org.apache.knox.gateway.services.security.KeystoreService;
 +import org.apache.knox.gateway.services.security.MasterService;
 +import org.apache.knox.gateway.services.security.AliasService;
 +import org.apache.knox.gateway.services.security.AliasServiceException;
 +import org.apache.knox.gateway.services.security.CryptoService;
 +import org.pac4j.config.client.PropertiesConfigFactory;
 +import org.pac4j.core.client.Client;
 +import org.pac4j.core.config.Config;
- import org.pac4j.core.config.ConfigSingleton;
- import org.pac4j.core.context.J2EContext;
 +import org.pac4j.core.util.CommonHelper;
 +import org.pac4j.http.client.indirect.IndirectBasicAuthClient;
 +import org.pac4j.http.credentials.authenticator.test.SimpleTestUsernamePasswordAuthenticator;
 +import org.pac4j.j2e.filter.CallbackFilter;
 +import org.pac4j.j2e.filter.SecurityFilter;
 +
 +import javax.servlet.*;
 +import javax.servlet.http.HttpServletRequest;
 +import javax.servlet.http.HttpServletResponse;
 +import java.io.IOException;
 +import java.util.Enumeration;
 +import java.util.HashMap;
 +import java.util.List;
 +import java.util.Map;
 +
 +/**
 + * <p>This is the main filter for the pac4j provider. The pac4j provider module heavily relies on the j2e-pac4j library (https://github.com/pac4j/j2e-pac4j).</p>
 + * <p>This filter dispatches the HTTP calls between the j2e-pac4j filters:</p>
 + * <ul>
 + *     <li>to the {@link CallbackFilter} if the <code>client_name</code> parameter exists: it finishes the authentication process</li>
 + *     <li>to the {@link RequiresAuthenticationFilter} otherwise: it starts the authentication process (redirection to the identity provider) if the user is not authenticated</li>
 + * </ul>
 + * <p>It uses the {@link KnoxSessionStore} to manage session data. The generated cookies are defined on a domain name
 + * which can be configured via the domain suffix parameter: <code>pac4j.cookie.domain.suffix</code>.</p>
 + * <p>The callback url must be defined to the current protected url (KnoxSSO service for example) via the parameter: <code>pac4j.callbackUrl</code>.</p>
 + *
 + * @since 0.8.0
 + */
 +public class Pac4jDispatcherFilter implements Filter {
 +
 +  private static Pac4jMessages log = MessagesFactory.get(Pac4jMessages.class);
 +
 +  public static final String TEST_BASIC_AUTH = "testBasicAuth";
 +
 +  public static final String PAC4J_CALLBACK_URL = "pac4j.callbackUrl";
 +
 +  public static final String PAC4J_CALLBACK_PARAMETER = "pac4jCallback";
 +
 +  private static final String PAC4J_COOKIE_DOMAIN_SUFFIX_PARAM = "pac4j.cookie.domain.suffix";
 +
++  private static final String PAC4J_CONFIG = "pac4j.config";
++
 +  private CallbackFilter callbackFilter;
 +
 +  private SecurityFilter securityFilter;
 +  private MasterService masterService = null;
 +  private KeystoreService keystoreService = null;
 +  private AliasService aliasService = null;
 +
 +  @Override
 +  public void init( FilterConfig filterConfig ) throws ServletException {
 +    // JWT service
 +    final ServletContext context = filterConfig.getServletContext();
 +    CryptoService cryptoService = null;
 +    String clusterName = null;
 +    if (context != null) {
 +      GatewayServices services = (GatewayServices) context.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
 +      clusterName = (String) context.getAttribute(GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE);
 +      if (services != null) {
 +        keystoreService = (KeystoreService) services.getService(GatewayServices.KEYSTORE_SERVICE);
 +        cryptoService = (CryptoService) services.getService(GatewayServices.CRYPTO_SERVICE);
 +        aliasService = (AliasService) services.getService(GatewayServices.ALIAS_SERVICE);
 +        masterService = (MasterService) services.getService("MasterService");
 +      }
 +    }
 +    // crypto service, alias service and cluster name are mandatory
 +    if (cryptoService == null || aliasService == null || clusterName == null) {
 +      log.cryptoServiceAndAliasServiceAndClusterNameRequired();
 +      throw new ServletException("The crypto service, alias service and cluster name are required.");
 +    }
 +    try {
 +      aliasService.getPasswordFromAliasForCluster(clusterName, KnoxSessionStore.PAC4J_PASSWORD, true);
 +    } catch (AliasServiceException e) {
 +      log.unableToGenerateAPasswordForEncryption(e);
 +      throw new ServletException("Unable to generate a password for encryption.");
 +    }
 +
 +    // url to SSO authentication provider
 +    String pac4jCallbackUrl = filterConfig.getInitParameter(PAC4J_CALLBACK_URL);
 +    if (pac4jCallbackUrl == null) {
 +      log.ssoAuthenticationProviderUrlRequired();
 +      throw new ServletException("Required pac4j callback URL is missing.");
 +    }
 +    // add the callback parameter to know it's a callback
 +    pac4jCallbackUrl = CommonHelper.addParameter(pac4jCallbackUrl, PAC4J_CALLBACK_PARAMETER, "true");
 +
 +    final Config config;
 +    final String clientName;
 +    // client name from servlet parameter (mandatory)
 +    final String clientNameParameter = filterConfig.getInitParameter("clientName");
 +    if (clientNameParameter == null) {
 +      log.clientNameParameterRequired();
 +      throw new ServletException("Required pac4j clientName parameter is missing.");
 +    }
 +    if (TEST_BASIC_AUTH.equalsIgnoreCase(clientNameParameter)) {
 +      // test configuration
 +      final IndirectBasicAuthClient indirectBasicAuthClient = new IndirectBasicAuthClient(new SimpleTestUsernamePasswordAuthenticator());
 +      indirectBasicAuthClient.setRealmName("Knox TEST");
 +      config = new Config(pac4jCallbackUrl, indirectBasicAuthClient);
 +      clientName = "IndirectBasicAuthClient";
 +    } else {
 +      // get clients from the init parameters
 +      final Map<String, String> properties = new HashMap<>();
 +      final Enumeration<String> names = filterConfig.getInitParameterNames();
 +      addDefaultConfig(clientNameParameter, properties);
 +      while (names.hasMoreElements()) {
 +        final String key = names.nextElement();
 +        properties.put(key, filterConfig.getInitParameter(key));
 +      }
 +      final PropertiesConfigFactory propertiesConfigFactory = new PropertiesConfigFactory(pac4jCallbackUrl, properties);
 +      config = propertiesConfigFactory.build();
 +      final List<Client> clients = config.getClients().getClients();
 +      if (clients == null || clients.size() == 0) {
 +        log.atLeastOnePac4jClientMustBeDefined();
 +        throw new ServletException("At least one pac4j client must be defined.");
 +      }
 +      if (CommonHelper.isBlank(clientNameParameter)) {
 +        clientName = clients.get(0).getName();
 +      } else {
 +        clientName = clientNameParameter;
 +      }
 +    }
 +
 +    callbackFilter = new CallbackFilter();
++    callbackFilter.setConfigOnly(config);
 +    securityFilter = new SecurityFilter();
 +    securityFilter.setClients(clientName);
-     securityFilter.setConfig(config);
++    securityFilter.setConfigOnly(config);
 +
 +    final String domainSuffix = filterConfig.getInitParameter(PAC4J_COOKIE_DOMAIN_SUFFIX_PARAM);
 +    config.setSessionStore(new KnoxSessionStore(cryptoService, clusterName, domainSuffix));
-     ConfigSingleton.setConfig(config);
 +  }
 +
 +  private void addDefaultConfig(String clientNameParameter, Map<String, String> properties) {
 +    // add default saml params
 +    if (clientNameParameter.contains("SAML2Client")) {
 +      properties.put(PropertiesConfigFactory.SAML_KEYSTORE_PATH,
 +          keystoreService.getKeystorePath());
 +
 +      properties.put(PropertiesConfigFactory.SAML_KEYSTORE_PASSWORD,
 +          new String(masterService.getMasterSecret()));
 +
 +      // check for provisioned alias for private key
 +      char[] gip = null;
 +      try {
 +        gip = aliasService.getGatewayIdentityPassphrase();
 +      }
 +      catch(AliasServiceException ase) {
 +        log.noPrivateKeyPasshraseProvisioned(ase);
 +      }
 +      if (gip != null) {
 +        properties.put(PropertiesConfigFactory.SAML_PRIVATE_KEY_PASSWORD,
 +            new String(gip));
 +      }
 +      else {
 +        // no alias provisioned then use the master
 +        properties.put(PropertiesConfigFactory.SAML_PRIVATE_KEY_PASSWORD,
 +            new String(masterService.getMasterSecret()));
 +      }
 +    }
 +  }
 +
 +  @Override
 +  public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
 +
 +    final HttpServletRequest request = (HttpServletRequest) servletRequest;
 +    final HttpServletResponse response = (HttpServletResponse) servletResponse;
-     final J2EContext context = new J2EContext(request, response, ConfigSingleton.getConfig().getSessionStore());
++    request.setAttribute(PAC4J_CONFIG, securityFilter.getConfig());
++//    final J2EContext context = new J2EContext(request, response, securityFilter.getConfig().getSessionStore());
 +
 +    // it's a callback from an identity provider
 +    if (request.getParameter(PAC4J_CALLBACK_PARAMETER) != null) {
 +      // apply CallbackFilter
 +      callbackFilter.doFilter(servletRequest, servletResponse, filterChain);
 +    } else {
 +      // otherwise just apply security and requires authentication
 +      // apply RequiresAuthenticationFilter
 +      securityFilter.doFilter(servletRequest, servletResponse, filterChain);
 +    }
 +  }
 +
 +  @Override
 +  public void destroy() { }
 +}

http://git-wip-us.apache.org/repos/asf/knox/blob/22a7304a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jIdentityAdapter.java
----------------------------------------------------------------------
diff --cc gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jIdentityAdapter.java
index 6387a0b,0000000..bc66003
mode 100644,000000..100644
--- a/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jIdentityAdapter.java
+++ b/gateway-provider-security-pac4j/src/main/java/org/apache/knox/gateway/pac4j/filter/Pac4jIdentityAdapter.java
@@@ -1,146 -1,0 +1,161 @@@
 +/**
 + * 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.pac4j.filter;
 +
- import org.apache.knox.gateway.audit.api.Action;
- import org.apache.knox.gateway.audit.api.ActionOutcome;
- import org.apache.knox.gateway.audit.api.AuditService;
- import org.apache.knox.gateway.audit.api.AuditServiceFactory;
- import org.apache.knox.gateway.audit.api.Auditor;
- import org.apache.knox.gateway.audit.api.ResourceType;
++import org.apache.knox.gateway.audit.api.*;
 +import org.apache.knox.gateway.audit.log4j.audit.AuditConstants;
 +import org.apache.knox.gateway.filter.AbstractGatewayFilter;
 +import org.apache.knox.gateway.security.PrimaryPrincipal;
- import org.pac4j.core.config.ConfigSingleton;
++import org.pac4j.core.config.Config;
 +import org.pac4j.core.context.J2EContext;
 +import org.pac4j.core.profile.CommonProfile;
 +import org.pac4j.core.profile.ProfileManager;
 +import org.slf4j.Logger;
 +import org.slf4j.LoggerFactory;
 +
 +import javax.security.auth.Subject;
 +import javax.servlet.Filter;
 +import javax.servlet.FilterChain;
 +import javax.servlet.FilterConfig;
 +import javax.servlet.ServletException;
 +import javax.servlet.ServletRequest;
 +import javax.servlet.ServletResponse;
 +import javax.servlet.http.HttpServletRequest;
 +import javax.servlet.http.HttpServletResponse;
 +import java.io.IOException;
 +import java.security.PrivilegedActionException;
 +import java.security.PrivilegedExceptionAction;
 +import java.util.Optional;
 +
 +/**
 + * <p>This filter retrieves the authenticated user saved by the pac4j provider and injects it into the J2E HTTP request.</p>
 + *
 + * @since 0.8.0
 + */
 +public class Pac4jIdentityAdapter implements Filter {
 +
 +  private static final Logger logger = LoggerFactory.getLogger(Pac4jIdentityAdapter.class);
 +
++  public static final String PAC4J_ID_ATTRIBUTE = "pac4j.id_attribute";
++  private static final String PAC4J_CONFIG = "pac4j.config";
++
 +  private static AuditService auditService = AuditServiceFactory.getAuditService();
 +  private static Auditor auditor = auditService.getAuditor(
 +      AuditConstants.DEFAULT_AUDITOR_NAME, AuditConstants.KNOX_SERVICE_NAME,
 +      AuditConstants.KNOX_COMPONENT_NAME );
 +
 +  private String testIdentifier;
 +
++  private String idAttribute;
++
 +  @Override
 +  public void init( FilterConfig filterConfig ) throws ServletException {
++    idAttribute = filterConfig.getInitParameter(PAC4J_ID_ATTRIBUTE);
 +  }
 +
 +  public void destroy() {
 +  }
 +
 +  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
 +      throws IOException, ServletException {
 +
 +    final HttpServletRequest request = (HttpServletRequest) servletRequest;
 +    final HttpServletResponse response = (HttpServletResponse) servletResponse;
-     final J2EContext context = new J2EContext(request, response, ConfigSingleton.getConfig().getSessionStore());
++    final J2EContext context = new J2EContext(request, response,
++        ((Config)request.getAttribute(PAC4J_CONFIG)).getSessionStore());
 +    final ProfileManager<CommonProfile> manager = new ProfileManager<CommonProfile>(context);
 +    final Optional<CommonProfile> optional = manager.get(true);
 +    if (optional.isPresent()) {
 +      CommonProfile profile = optional.get();
 +      logger.debug("User authenticated as: {}", profile);
 +      manager.remove(true);
-       final String id = profile.getId();
++      String id = null;
++      if (idAttribute != null) {
++        Object attribute = profile.getAttribute(idAttribute);
++        if (attribute != null) {
++          id = attribute.toString();
++        }
++        if (id == null) {
++          logger.error("Invalid attribute_id: {} configured to be used as principal"
++              + " falling back to default id", idAttribute);
++        }
++      }
++      if (id == null) {
++        id = profile.getId();
++      }
 +      testIdentifier = id;
 +      PrimaryPrincipal pp = new PrimaryPrincipal(id);
 +      Subject subject = new Subject();
 +      subject.getPrincipals().add(pp);
 +      auditService.getContext().setUsername(id);
 +      String sourceUri = (String)request.getAttribute( AbstractGatewayFilter.SOURCE_REQUEST_CONTEXT_URL_ATTRIBUTE_NAME );
 +      auditor.audit(Action.AUTHENTICATION, sourceUri, ResourceType.URI, ActionOutcome.SUCCESS);
 +
 +      doAs(request, response, chain, subject);
 +    }
 +  }
 +
 +  private void doAs(final ServletRequest request,
 +      final ServletResponse response, final FilterChain chain, Subject subject)
 +      throws IOException, ServletException {
 +    try {
 +      Subject.doAs(
 +          subject,
 +          new PrivilegedExceptionAction<Object>() {
 +            public Object run() throws Exception {
 +              chain.doFilter(request, response);
 +              return null;
 +            }
 +          }
 +          );
 +    }
 +    catch (PrivilegedActionException e) {
 +      Throwable t = e.getCause();
 +      if (t instanceof IOException) {
 +        throw (IOException) t;
 +      }
 +      else if (t instanceof ServletException) {
 +        throw (ServletException) t;
 +      }
 +      else {
 +        throw new ServletException(t);
 +      }
 +    }
 +  }
 +
 +  /**
 +   * For tests only.
 +   */
 +  public static void setAuditService(AuditService auditService) {
 +    Pac4jIdentityAdapter.auditService = auditService;
 +  }
 +
 +  /**
 +   * For tests only.
 +   */
 +  public static void setAuditor(Auditor auditor) {
 +    Pac4jIdentityAdapter.auditor = auditor;
 +  }
 +
 +  /**
 +   * For tests only.
 +     */
 +  public String getTestIdentifier() {
 +    return testIdentifier;
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/knox/blob/22a7304a/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/MockHttpServletRequest.java
----------------------------------------------------------------------
diff --cc gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/MockHttpServletRequest.java
index 7a3a833,0000000..18f4913
mode 100644,000000..100644
--- a/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/MockHttpServletRequest.java
+++ b/gateway-provider-security-pac4j/src/test/java/org/apache/knox/gateway/pac4j/MockHttpServletRequest.java
@@@ -1,88 -1,0 +1,94 @@@
 +/**
 + * 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.pac4j;
 +
 +import javax.servlet.http.*;
 +
 +import java.util.HashMap;
 +import java.util.Map;
 +
 +import static org.mockito.Mockito.*;
 +
 +public class MockHttpServletRequest extends HttpServletRequestWrapper {
 +
 +    private String requestUrl;
 +    private Cookie[] cookies;
 +    private String serverName;
 +    private Map<String, String> parameters = new HashMap<>();
 +    private Map<String, String> headers = new HashMap<>();
++    private Map<String, Object> attributes = new HashMap<>();
 +
 +    public MockHttpServletRequest() {
 +        super(mock(HttpServletRequest.class));
 +    }
 +
 +    @Override
 +    public Cookie[] getCookies() {
 +        return cookies;
 +    }
 +
 +    public void setCookies(final Cookie[] cookies) {
 +        this.cookies = cookies;
 +    }
 +
 +    @Override
 +    public StringBuffer getRequestURL() {
 +        return new StringBuffer(requestUrl);
 +    }
 +
 +    public void setRequestURL(final String requestUrl) {
 +        this.requestUrl = requestUrl;
 +    }
 +
 +    @Override
 +    public String getServerName() {
 +        return serverName;
 +    }
 +
 +    public void setServerName(final String serverName) {
 +        this.serverName = serverName;
 +    }
 +
 +    @Override
 +    public String getParameter(String name) {
 +        return parameters.get(name);
 +    }
 +
 +    public void addParameter(String key, String value) {
 +        parameters.put(key, value);
 +    }
 +
 +    @Override
 +    public String getHeader(String name) {
 +        return headers.get(name);
 +    }
 +
 +    public void addHeader(String key, String value) {
 +        headers.put(key, value);
 +    }
 +
 +    @Override
++    public void setAttribute(String name, Object value) {
++        attributes.put(name, value);
++    }
++
++    @Override
 +    public Object getAttribute(String name) {
-         return null;
++        return attributes.get(name);
 +    }
 +}


Mime
View raw message