/*
 * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
 * as indicated by the @author tags. All rights reserved.
 *
 * 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 org.keycloak.quickstart.appjee;

import java.io.IOException;
import java.io.InputStream;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.util.JsonSerialization;

/**
 * Client that calls the service.
 *
 * @author Stan Silvert ssilvert@redhat.com (C) 2015 Red Hat Inc.
 */
public class ServiceClient {

    private static final String SERVICE_URI_INIT_PARAM_NAME = "serviceUrl";

    static class MessageBean {
        private String message;

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

    }

    public static class Failure extends Exception {

        private int status;
        private String reason;

        public Failure(int status, String reason) {
            this.status = status;
            this.reason = reason;
        }

        public int getStatus() {
            return status;
        }

        public String getReason() {
            return reason;
        }
    }

    private static String getServiceUrl(HttpServletRequest req, KeycloakSecurityContext session) {
        String uri = req.getServletContext().getInitParameter(SERVICE_URI_INIT_PARAM_NAME);
        if (uri != null && !uri.contains("localhost"))
        	return uri;

    	String ip = req.getLocalAddr();

        if (ip != null){
	        ip = "localhost";
	        try {
	        	ip = java.net.InetAddress.getLocalHost().getHostAddress();
	        } catch (Exception e){
	            e.printStackTrace();
	        }
        }
        
        System.out.println("!!!!! ip " + ip);

        return "http://" + ip + ":8080/service";
    }
    
    public static HttpClient createHttpClient_AcceptsUntrustedCerts() throws Exception {
        HttpClientBuilder b = HttpClientBuilder.create();
     
        // setup a Trust Strategy that allows all certificates.
        //
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                return true;
            }
        }).build();
        b.setSslcontext( sslContext);
     
        // don't check Hostnames, either.
        //      -- use SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weaken
        HostnameVerifier hostnameVerifier = SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
     
        // here's the special part:
        //      -- need to create an SSL Socket Factory, to use our weakened "trust strategy";
        //      -- and create a Registry, to register it.
        //
        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", sslSocketFactory)
                .build();
     
        // now, we create connection-manager using our Registry.
        //      -- allows multi-threaded use
        PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry);
        b.setConnectionManager( connMgr);
     
        // finally, build the HttpClient;
        //      -- done!
        HttpClient client = b.build();
        return client;
    }

    public static String callService(HttpServletRequest req, KeycloakSecurityContext session, String action) throws Failure {
        HttpClient client = null;
        try {
        	client = createHttpClient_AcceptsUntrustedCerts();
            HttpGet get = new HttpGet(getServiceUrl(req, session) + "/" + action);
            if (session != null) {
                get.addHeader("Authorization", "Bearer " + session.getTokenString());
            }

            HttpResponse response = client.execute(get);

            StatusLine status = response.getStatusLine();
            if (status.getStatusCode() != 200) {
                throw new Failure(status.getStatusCode(), status.getReasonPhrase());
            }

            HttpEntity entity = response.getEntity();
            InputStream is = entity.getContent();
            try {
                MessageBean message = (MessageBean)JsonSerialization.readValue(is, MessageBean.class);
                return message.getMessage();
            } finally {
                is.close();
            }
        } catch (Failure f) {
            throw f;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
        	if (client != null)
             client.getConnectionManager().shutdown();
        }
    }
}

@@ -3217,55 +3217,8 @@
    %0A
-        System.out.println(%22!!!!! ip %22 + ip);%0A%0A
     
@@ -3277,1816 +3277,8 @@
    %0A
-    public static HttpClient createHttpClient_AcceptsUntrustedCerts() throws Exception %7B%0A        HttpClientBuilder b = HttpClientBuilder.create();%0A     %0A        // setup a Trust Strategy that allows all certificates.%0A        //%0A        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() %7B%0A            public boolean isTrusted(X509Certificate%5B%5D arg0, String arg1) throws CertificateException %7B%0A                return true;%0A            %7D%0A        %7D).build();%0A        b.setSslcontext( sslContext);%0A     %0A        // don't check Hostnames, either.%0A        //      -- use SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weaken%0A        HostnameVerifier hostnameVerifier = SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;%0A     %0A        // here's the special part:%0A        //      -- need to create an SSL Socket Factory, to use our weakened %22trust strategy%22;%0A        //      -- and create a Registry, to register it.%0A        //%0A        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);%0A        Registry%3CConnectionSocketFactory%3E socketFactoryRegistry = RegistryBuilder.%3CConnectionSocketFactory%3Ecreate()%0A                .register(%22http%22, PlainConnectionSocketFactory.getSocketFactory())%0A                .register(%22https%22, sslSocketFactory)%0A                .build();%0A     %0A        // now, we create connection-manager using our Registry.%0A        //      -- allows multi-threaded use%0A        PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry);%0A        b.setConnectionManager( connMgr);%0A     %0A        // finally, build the HttpClient;%0A        //      -- done!%0A        HttpClient client = b.build();%0A        return client;%0A    %7D%0A%0A
     
@@ -3455,17 +3455,20 @@
         
-%09
+    
 client =
@@ -3472,46 +3472,29 @@
 t = 
-createHttpClient_AcceptsUntrustedCerts
+new DefaultHttpClient
 ();%0A

secure httpclient