/*
 *
 * Copyright 2013 Netflix, Inc.
 *
 * Licensed 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 com.netflix.niws.client.http;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.FileOutputStream;
import java.net.URI;

import org.apache.commons.configuration.AbstractConfiguration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import com.netflix.client.ClientFactory;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
import com.netflix.client.testutil.SimpleSSLTestServer;
import com.netflix.config.ConfigurationManager;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.core.util.Base64;
import com.sun.jersey.core.util.MultivaluedMapImpl;

/**
 *
 * Test TLS configurations work against a very dumbed down test server.
 *
 * @author jzarfoss
 *
 */
public class SecureGetTest {

	// custom minted test keystores/truststores for Ribbon testing

	// PLEASE DO NOT USE FOR ANYTHING OTHER THAN TESTING (the private keys are sitting right here in a String!!)
	// but if you need keystore to test with, help yourself, they're good until 2113!

	// we have a pair of independently valid keystore/truststore combinations
	// thus allowing us to perform both positive and negative testing,
	// the negative testing being that set 1 and set 2 cannot talk to each other

	// base64 encoded

	//	Keystore type: JKS
	//	Keystore provider: SUN
	//
	//	Your keystore contains 1 entry
	//
	//	Alias name: ribbon_root
	//	Creation date: Sep 6, 2013
	//	Entry type: trustedCertEntry
	//
	//	Owner: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestRoot1
	//	Issuer: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestRoot1
	//	Serial number: 1
	//	Valid from: Fri Sep 06 10:25:22 PDT 2013 until: Sun Aug 13 10:25:22 PDT 2113
	//	Certificate fingerprints:
	//		 MD5:  BD:08:2A:F3:3B:26:C0:D4:44:B9:6D:EE:D2:45:31:C0
	//		 SHA1: 64:95:7E:C6:0C:D7:81:56:28:0C:93:60:85:AB:9D:E2:60:33:70:43
	//		 Signature algorithm name: SHA1withRSA
	//		 Version: 3
	//
	//	Extensions:
	//
	//	#1: ObjectId: 2.5.29.19 Criticality=false
	//	BasicConstraints:[
	//	  CA:true
	//	  PathLen:2147483647
	//	]


	public static final String TEST_TS1 =
			"/u3+7QAAAAIAAAABAAAAAgALcmliYm9uX3Jvb3QAAAFA9E6KkQAFWC41MDkAAAIyMIICLjCCAZeg" +
					"AwIBAgIBATANBgkqhkiG9w0BAQUFADBTMRgwFgYDVQQDDA9SaWJib25UZXN0Um9vdDExCzAJBgNV" +
					"BAsMAklUMRAwDgYDVQQKDAdOZXRmbGl4MQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMwIBcNMTMw" +
					"OTA2MTcyNTIyWhgPMjExMzA4MTMxNzI1MjJaMFMxGDAWBgNVBAMMD1JpYmJvblRlc3RSb290MTEL" +
					"MAkGA1UECwwCSVQxEDAOBgNVBAoMB05ldGZsaXgxCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzCB" +
					"nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAg8riOgT2Y39SQlZE+MWnOiKjREZzQ3ecvPf40oF8" +
					"9YPNGpBhJzIKdA0TR1vQ70p3Fl2+Y5txs1H2/iguOdFMBrSdv1H8qJG1UufaeYO++HBm3Mi2L02F" +
					"6fcTEEyXQMebKCWf04mxvLy5M6B5yMqZ9rHEZD+qsF4rXspx70bd0tUCAwEAAaMQMA4wDAYDVR0T" +
					"BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBzTEn9AZniODYSRa+N7IvZu127rh+Sc6XWth68TBRj" +
					"hThDFARnGxxe2d3EFXB4xH7qcvLl3HQ3U6lIycyLabdm06D3/jzu68mkMToE5sHJmrYNHHTVl0aj" +
					"0gKFBQjLRJRlgJ3myUbbfrM+/a5g6S90TsVGTxXwFn5bDvdErsn8F8Hd41plMkW5ywsn6yFZMaFr" +
					"MxnX";


	//	Keystore type: JKS
	//	Keystore provider: SUN
	//
	//	Your keystore contains 1 entry
	//
	//	Alias name: ribbon_root
	//	Creation date: Sep 6, 2013
	//	Entry type: trustedCertEntry
	//
	//	Owner: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestRoot2
	//	Issuer: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestRoot2
	//	Serial number: 1
	//	Valid from: Fri Sep 06 10:26:22 PDT 2013 until: Sun Aug 13 10:26:22 PDT 2113
	//	Certificate fingerprints:
	//		 MD5:  44:64:E3:25:4F:D2:2C:8D:4D:B0:53:19:59:BD:B3:20
	//		 SHA1: 26:2F:41:6D:03:C7:D0:8E:4F:AF:0E:4F:29:E3:08:53:B7:3C:DB:EE
	//		 Signature algorithm name: SHA1withRSA
	//		 Version: 3
	//
	//	Extensions:
	//
	//	#1: ObjectId: 2.5.29.19 Criticality=false
	//	BasicConstraints:[
	//	  CA:true
	//	  PathLen:2147483647
	//	]

	public static final String TEST_TS2 =
			"/u3+7QAAAAIAAAABAAAAAgALcmliYm9uX3Jvb3QAAAFA9E92vgAFWC41MDkAAAIyMIICLjCCAZeg" +
					"AwIBAgIBATANBgkqhkiG9w0BAQUFADBTMRgwFgYDVQQDDA9SaWJib25UZXN0Um9vdDIxCzAJBgNV" +
					"BAsMAklUMRAwDgYDVQQKDAdOZXRmbGl4MQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMwIBcNMTMw" +
					"OTA2MTcyNjIyWhgPMjExMzA4MTMxNzI2MjJaMFMxGDAWBgNVBAMMD1JpYmJvblRlc3RSb290MjEL" +
					"MAkGA1UECwwCSVQxEDAOBgNVBAoMB05ldGZsaXgxCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzCB" +
					"nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAnEwAfuHYKRJviVB3RyV3+/mp4qjWZZd/q+fE2Z0k" +
					"o2N2rrC8fAw53KXwGOE5fED6wXd3B2zyoSFHVsWOeL+TUoohn+eHSfwH7xK+0oWC8IvUoXWehOft" +
					"grYtv9Jt5qNY5SmspBmyxFiaiAWQJYuf12Ycu4Gqg+P7mieMHgu6Do0CAwEAAaMQMA4wDAYDVR0T" +
					"BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBNA0ask9eTYYhYA3bbmQZInxkBV74Gq/xorLlVygjn" +
					"OgyGYp4/L274qwlPMqnQRmVbezkug2YlUK8xbrjwCUvHq2XW38e2RjK5q3EXVkGJxgCBuHug/eIf" +
					"wD+/IEIE8aVkTW2j1QrrdkXDhRO5OsjvIVdy5/V4U0hVDnSo865ud9VQ/hZmOQuZItHViSoGSe2j" +
					"bbZk";

	//	Keystore type: JKS
	//	Keystore provider: SUN
	//
	//	Your keystore contains 1 entry
	//
	//	Alias name: ribbon_key
	//	Creation date: Sep 6, 2013
	//	Entry type: PrivateKeyEntry
	//	Certificate chain length: 1
	//	Certificate[1]:
	//	Owner: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestEndEntity1
	//	Issuer: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestRoot1
	//	Serial number: 64
	//	Valid from: Fri Sep 06 10:25:22 PDT 2013 until: Sun Aug 13 10:25:22 PDT 2113
	//	Certificate fingerprints:
	//		 MD5:  79:C5:F3:B2:B8:4C:F2:3F:2E:C7:67:FC:E7:04:BF:90
	//		 SHA1: B1:D0:4E:A6:D8:84:BF:8B:01:46:B6:EA:97:5B:A0:4E:13:8B:A9:DE
	//		 Signature algorithm name: SHA1withRSA
	//		 Version: 3

	public static final String TEST_KS1 =
			"/u3+7QAAAAIAAAABAAAAAQAKcmliYm9uX2tleQAAAUD0Toq4AAACuzCCArcwDgYKKwYBBAEqAhEB" +
					"AQUABIICo9fLN8zeXLcyx50+6B6gdXiUslZKY0SgLwL8kKNlQFiccD3Oc1yWjMnVC2QOdLsFzcVk" +
					"ROhgMH/nHfFeXFlvY5IYMXqhbEC37LjE52RtX5KHv4FLYxxZCHduAwO8UTPa603XzrJ0VTMJ6Hso" +
					"9+Ql76cGxPtIPcYm8IfqIY22as3NlKO4eMbiur9GLvuC57eql8vROaxGy8y657gc6kZMUyQOC+HG" +
					"a5M3DTFpjl4V6HHbXHhMNEk9eXHnrZwYVOJmOgdgIrNNHOyD4kE+k21C7rUHhLAwK84wKL/tW4k9" +
					"xnhOJK/L1RmycRIFWwXVi3u/3vi49bzdZsRLn73MdQkTe5p8oNZzG9sxg76u67ua6+99TMZYE1ay" +
					"5JCYgbr85KbRsoX9Hd5XBcSNzROKJl0To2tAF8eTTMRlhEy7JZyTF2M9877juNaregVwE3Tp+a/J" +
					"ACeNMyrxOQItNDam7a5dgBohpM8oJdEFqqj/S9BU7H5sR0XYo8TyIe1BV9zR5ZC/23fj5l5zkrri" +
					"TCMgMbvt95JUGOT0gSzxBMmhV+ZLxpmVz3M5P2pXX0DXGTKfuHSiBWrh1GAQL4BOVpuKtyXlH1/9" +
					"55/xY25W0fpLzMiQJV7jf6W69LU0FAFWFH9uuwf/sFph0S1QQXcQSfpYmWPMi1gx/IgIbvT1xSuI" +
					"6vajgFqv6ctiVbFAJ6zmcnGd6e33+Ao9pmjs5JPZP3rtAYd6+PxtlwUbGLZuqIVK4o68LEISDfvm" +
					"nGlk4/1+S5CILKVqTC6Ja8ojwUjjsNSJbZwHue3pOkmJQUNtuK6kDOYXgiMRLURbrYLyen0azWw8" +
					"C5/nPs5J4pN+irD/hhD6cupCnUJmzMw30u8+LOCN6GaM5fdCTQ2uQKF7quYuD+gR3lLNOqq7KAAA" +
					"AAEABVguNTA5AAACJTCCAiEwggGKoAMCAQICAWQwDQYJKoZIhvcNAQEFBQAwUzEYMBYGA1UEAwwP" +
					"UmliYm9uVGVzdFJvb3QxMQswCQYDVQQLDAJJVDEQMA4GA1UECgwHTmV0ZmxpeDELMAkGA1UECAwC" +
					"Q0ExCzAJBgNVBAYTAlVTMCAXDTEzMDkwNjE3MjUyMloYDzIxMTMwODEzMTcyNTIyWjBYMR0wGwYD" +
					"VQQDDBRSaWJib25UZXN0RW5kRW50aXR5MTELMAkGA1UECwwCSVQxEDAOBgNVBAoMB05ldGZsaXgx" +
					"CzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAydqk" +
					"AJuUcSF8dpUbNJWl+G1usgHtEFEbOMm54N/ZqGC7iSYs6EXfeoEyiHrMw/hdCKACERq2vuiuqan8" +
					"h6z65/DXIiHUyykGb/Z4NK1I0aCQLZG4Ek3sERilILWyy2NRpjUrvqDPr/mQgymXqpuYhSD81jHx" +
					"F84AOpTrnGsY7/sCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAjvtRKNhb1R6XIuWaOxJ0XDLine464" +
					"Ie7LDfkE/KB43oE4MswjRh7nR9q6C73oa6TlIXmW6ysyKPp0vAyWHlq/zZhL3gNQ6faHuYHqas5s" +
					"nJQgvQpHAQh4VXRyZt1K8ZdsHg3Qbd4APTL0aRVQkxDt+Dxd6AsoRMKmO/c5CRwUFIV/CK7k5VSh" +
					"Sl5PRtH3PVj2vp84";

	//	Keystore type: JKS
	//	Keystore provider: SUN
	//
	//	Your keystore contains 1 entry
	//
	//	Alias name: ribbon_key
	//	Creation date: Sep 6, 2013
	//	Entry type: PrivateKeyEntry
	//	Certificate chain length: 1
	//	Certificate[1]:
	//	Owner: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestEndEntity2
	//	Issuer: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestRoot2
	//	Serial number: 64
	//	Valid from: Fri Sep 06 10:26:22 PDT 2013 until: Sun Aug 13 10:26:22 PDT 2113
	//	Certificate fingerprints:
	//		 MD5:  C3:AF:6A:DB:18:ED:70:22:83:73:9A:A5:DB:58:6D:04
	//		 SHA1: B7:D4:F0:87:A8:4E:49:0A:91:B1:7B:62:28:CA:A2:4A:0E:AE:40:CC
	//		 Signature algorithm name: SHA1withRSA
	//		 Version: 3
	//
	//
	//

	public static final String TEST_KS2 =
			"/u3+7QAAAAIAAAABAAAAAQAKcmliYm9uX2tleQAAAUD0T3bNAAACuzCCArcwDgYKKwYBBAEqAhEB" +
					"AQUABIICoysDP4inwmxxKZkS8EYMW3DCJCD1AmpwFHxJIzo2v9fMysg+vjKxsrvVyKG23ZcHcznI" +
					"ftmrEpriCCUZp+NNAf0EJWVAIzGenwrsd0+rI5I96gBOh9slJUzgucn7164R3XKNKk+VWcwGJRh+" +
					"IuHxVrwFN025pfhlBJXNGJg4ZlzB7ZwcQPYblBzhLbhS3vJ1Vc46pEYWpnjxmHaDSetaQIcueAp8" +
					"HnTUkFMXJ6t51N0u9QMPhBH7p7N8tNjaa5noSdxhSl/2Znj6r04NwQU1qX2n4rSWEnYaW1qOVkgx" +
					"YrQzxI2kSHZfQDM2T918UikboQvAS1aX4h5P3gVCDKLr3EOO6UYO0ZgLHUr/DZrhVKd1KAhnzaJ8" +
					"BABxot2ES7Zu5EzY9goiaYDA2/bkURmt0zDdKpeORb7r59XBZUm/8D80naaNnE45W/gBA9bCiDu3" +
					"R99xie447c7ZX9Jio25yil3ncv+npBO1ozc5QIgQnbEfxbbwii3//shvPT6oxYPrcwWBXnaJNC5w" +
					"2HDpCTXJZNucyjnNVVxC7p1ANNnvvZhgC0+GpEqmf/BW+fb9Qu+AXe0/h4Vnoe/Zs92vPDehpaKy" +
					"oe+jBlUNiW2bpR88DSqxVcIu1DemlgzPa1Unzod0FdrOr/272bJnB2zAo4OBaBSv3KNf/rsMKjsU" +
					"X2Po77+S+PKoQkqd8KJFpmLEb0vxig9JsrTDJXLf4ebeSA1W7+mBotimMrp646PA3NciMSbS4csh" +
					"A7o/dBYhHlEosVgThm1JknIKhemf+FZsOzR3bJDT1oXJ/GhYpfzlCLyVFBeVP0KRnhih4xO0MEO7" +
					"Q21DBaTTqAvUo7Iv3/F3mGMOanLcLgoRoq3moQ7FhfCDRtRAPA1qT2+pxPG5wqlGeYc6McOvogAA" +
					"AAEABVguNTA5AAACJTCCAiEwggGKoAMCAQICAWQwDQYJKoZIhvcNAQEFBQAwUzEYMBYGA1UEAwwP" +
					"UmliYm9uVGVzdFJvb3QyMQswCQYDVQQLDAJJVDEQMA4GA1UECgwHTmV0ZmxpeDELMAkGA1UECAwC" +
					"Q0ExCzAJBgNVBAYTAlVTMCAXDTEzMDkwNjE3MjYyMloYDzIxMTMwODEzMTcyNjIyWjBYMR0wGwYD" +
					"VQQDDBRSaWJib25UZXN0RW5kRW50aXR5MjELMAkGA1UECwwCSVQxEDAOBgNVBAoMB05ldGZsaXgx" +
					"CzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtOvK" +
					"fBMC/oMo4xf4eYGN7hTNn+IywaSaVYndqECIfuznoIqRKSbeCKPSGs4CN1D+u3E2UoXcsDmTguHU" +
					"fokDA7sLUu8wD5ndAXfCkP3gXlFtUpNz/jPaXDsMFntTn2BdLKccxRxNwtwC0zzwIdtx9pw/Ru0g" +
					"NXIQnPi50aql5WcCAwEAATANBgkqhkiG9w0BAQUFAAOBgQCYWM2ZdBjG3jCvMw/RkebMLkEDRxVM" +
					"XU63Ygo+iCZUk8V8d0/S48j8Nk/hhVGHljsHqE/dByEF77X6uHaDGtt3Xwe+AYPofoJukh89jKnT" +
					"jEDtLF+y5AVfz6b2z3TnJcuigMr4ZtBFv18R00KLnVAznl/waXG8ix44IL5ss6nRZBJE4jr+ZMG9" +
					"9I4P1YhySxo3Qd3g";



	private static String SERVICE_URI1;
	private static String SERVICE_URI2;

	private static SimpleSSLTestServer testServer1;
	private static SimpleSSLTestServer testServer2;

	private static File FILE_TS1;
	private static File FILE_KS1;

	private static File FILE_TS2;
	private static File FILE_KS2;

	public static final String PASSWORD = "changeit";


	@BeforeClass
	public static void init() throws Exception {

		// setup server 1, will use first keystore/truststore with client auth

		// jks format
		byte[] sampleTruststore1 = Base64.decode(TEST_TS1);
		byte[] sampleKeystore1 = Base64.decode(TEST_KS1);

		FILE_KS1 = File.createTempFile("SecureGetTest1", ".keystore");
		FILE_TS1 = File.createTempFile("SecureGetTest1", ".truststore");

		FileOutputStream keystoreFileOut = new FileOutputStream(FILE_KS1);
        try {
            keystoreFileOut.write(sampleKeystore1);
        } finally {
            keystoreFileOut.close();
        }

		FileOutputStream truststoreFileOut = new FileOutputStream(FILE_TS1);
        try {
            truststoreFileOut.write(sampleTruststore1);
        } finally {
            truststoreFileOut.close();
        }

		try{
			testServer1 = new SimpleSSLTestServer(FILE_TS1, PASSWORD, FILE_KS1, PASSWORD, true);
		} catch (Exception e) {
			e.printStackTrace();
			fail(e.getMessage());
		}

		SERVICE_URI1 = "https://127.0.0.1:" + testServer1.getPort() + "/";

		// setup server 2, will use second keystore truststore without client auth

		// jks format
		byte[] sampleTruststore2 = Base64.decode(TEST_TS2);
		byte[] sampleKeystore2 = Base64.decode(TEST_KS2);

		FILE_KS2 = File.createTempFile("SecureGetTest2", ".keystore");
		FILE_TS2 = File.createTempFile("SecureGetTest2", ".truststore");

		keystoreFileOut = new FileOutputStream(FILE_KS2);
        try {
            keystoreFileOut.write(sampleKeystore2);
        } finally {
            keystoreFileOut.close();
        }

		truststoreFileOut = new FileOutputStream(FILE_TS2);
        try {
            truststoreFileOut.write(sampleTruststore2);
        } finally {
            truststoreFileOut.close();
        }

		try{
			testServer2 = new SimpleSSLTestServer(FILE_TS2, PASSWORD, FILE_KS2, PASSWORD, false);
		} catch (Exception e) {
			e.printStackTrace();
			fail(e.getMessage());
		}

		SERVICE_URI2 = "https://127.0.0.1:" + testServer2.getPort() + "/";
	}

	@AfterClass
	public static void shutDown(){

		try{
			testServer1.close();
		}catch(Exception e){
			e.printStackTrace();
		}

		try{
			testServer2.close();
		}catch(Exception e){
			e.printStackTrace();
		}

	}

	@Test
	public void testSunnyDay() throws Exception {

		AbstractConfiguration cm = ConfigurationManager.getConfigInstance();

		String name = "GetPostSecureTest" + ".testSunnyDay";

		String configPrefix = name + "." + "ribbon";

		cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsSecure, "true");
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.SecurePort, Integer.toString(testServer1.getPort()));
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsHostnameValidationRequired, "false");
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsClientAuthRequired, "true");
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.KeyStore, FILE_KS1.getAbsolutePath());
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.KeyStorePassword, PASSWORD);
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStore, FILE_TS1.getAbsolutePath());
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStorePassword, PASSWORD);

		RestClient rc = (RestClient) ClientFactory.getNamedClient(name);

		testServer1.accept();

		URI getUri = new URI(SERVICE_URI1 + "test/");
        HttpRequest request = HttpRequest.newBuilder().uri(getUri).queryParams("name", "test").build();
		HttpResponse response = rc.execute(request);
		assertEquals(200, response.getStatus());
	}


	@Test
	public void testSunnyDayNoClientAuth() throws Exception{

		AbstractConfiguration cm = ConfigurationManager.getConfigInstance();

		String name = "GetPostSecureTest" + ".testSunnyDayNoClientAuth";

		String configPrefix = name + "." + "ribbon";

		cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsSecure, "true");
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.SecurePort, Integer.toString(testServer2.getPort()));
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsHostnameValidationRequired, "false");
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStore, FILE_TS2.getAbsolutePath());
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStorePassword, PASSWORD);

		RestClient rc = (RestClient) ClientFactory.getNamedClient(name);

		testServer2.accept();

		URI getUri = new URI(SERVICE_URI2 + "test/");
        HttpRequest request = HttpRequest.newBuilder().uri(getUri).queryParams("name", "test").build();
		HttpResponse response = rc.execute(request);
		assertEquals(200, response.getStatus());
	}


	@Test
	public void testFailsWithHostNameValidationOn() throws Exception {

		AbstractConfiguration cm = ConfigurationManager.getConfigInstance();

		String name = "GetPostSecureTest" + ".testFailsWithHostNameValidationOn";

		String configPrefix = name + "." + "ribbon";

		cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsSecure, "true");
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.SecurePort, Integer.toString(testServer2.getPort()));
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsHostnameValidationRequired, "true"); // <--
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsClientAuthRequired, "true");
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.KeyStore, FILE_KS1.getAbsolutePath());
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.KeyStorePassword, PASSWORD);
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStore, FILE_TS1.getAbsolutePath());
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStorePassword, PASSWORD);

		RestClient rc = (RestClient) ClientFactory.getNamedClient(name);

		testServer1.accept();

		URI getUri = new URI(SERVICE_URI1 + "test/");
		MultivaluedMapImpl params = new MultivaluedMapImpl();
		params.add("name", "test");
        HttpRequest request = HttpRequest.newBuilder().uri(getUri).queryParams("name", "test").build();

		try{
			rc.execute(request);

			fail("expecting ssl hostname validation error");
		}catch(ClientHandlerException che){
			assertTrue(che.getMessage().indexOf("hostname in certificate didn't match") > -1);
		}
	}

	@Test
	public void testClientRejectsWrongServer() throws Exception{

		AbstractConfiguration cm = ConfigurationManager.getConfigInstance();

		String name = "GetPostSecureTest" + ".testClientRejectsWrongServer";

		String configPrefix = name + "." + "ribbon";

		cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsSecure, "true");
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.SecurePort, Integer.toString(testServer2.getPort()));
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsHostnameValidationRequired, "false");
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStore, FILE_TS1.getAbsolutePath()); // <--
		cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStorePassword, PASSWORD);

		RestClient rc = (RestClient) ClientFactory.getNamedClient(name);

		testServer2.accept();

		URI getUri = new URI(SERVICE_URI2 + "test/");
		HttpRequest request = HttpRequest.newBuilder().uri(getUri).queryParams("name", "test").build();
		try{
			rc.execute(request);

			fail("expecting ssl hostname validation error");

		}catch(ClientHandlerException che){
			assertTrue(che.getMessage().indexOf("peer not authenticated") > -1);
		}
	}



}