Package org.apache.geronimo.interop.rmi.iiop.client

Source Code of org.apache.geronimo.interop.rmi.iiop.client.Connection

/**
*
*  Copyright 2004-2005 The Apache Software Foundation
*
*  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.apache.geronimo.interop.rmi.iiop.client;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.Socket;

import org.apache.geronimo.interop.SystemException;
import org.apache.geronimo.interop.properties.BooleanProperty;
import org.apache.geronimo.interop.properties.IntProperty;
import org.apache.geronimo.interop.properties.PropertyMap;
import org.apache.geronimo.interop.properties.SystemProperties;
import org.apache.geronimo.interop.rmi.iiop.BadMagicException;
import org.apache.geronimo.interop.rmi.iiop.CdrInputStream;
import org.apache.geronimo.interop.rmi.iiop.CdrOutputStream;
import org.apache.geronimo.interop.rmi.iiop.GiopMessage;
import org.apache.geronimo.interop.rmi.iiop.ObjectRef;
import org.apache.geronimo.interop.rmi.iiop.SecurityInfo;
import org.apache.geronimo.interop.rmi.iiop.SimpleObjectInputStream;
import org.apache.geronimo.interop.rmi.iiop.UnsupportedProtocolVersionException;
import org.apache.geronimo.interop.util.ExceptionUtil;
import org.apache.geronimo.interop.util.InstancePool;
import org.apache.geronimo.interop.util.StringUtil;
import org.apache.geronimo.interop.util.ThreadContext;
import org.omg.GIOP.MsgType_1_1;
import org.omg.GIOP.ReplyHeader_1_2;
import org.omg.GIOP.ReplyStatusType_1_2;
import org.omg.GIOP.RequestHeader_1_2;
import org.omg.GIOP.SystemExceptionReplyBody;
import org.omg.GIOP.SystemExceptionReplyBodyHelper;
import org.omg.GIOP.TargetAddress;
import org.omg.IOP.ServiceContext;

public class Connection
{

    private static final byte reservedBA[] = new byte[] { 0, 0, 0};
    private int requestid_ = 0;

    // http tunnelling related
    private boolean httpTunnelled;
    private String  httpHeaders;
    private String  webProxyHost;
    private int     webProxyPort;

    public Connection()
    {
    }

    public static Connection getInstance(String endpoint, ObjectRef objectRef, PropertyMap connProps)
    {
        Connection conn = new Connection();
        conn.init(endpoint, objectRef, connProps);
        return conn;
    }

    public static final BooleanProperty simpleIDLProperty =
            new BooleanProperty(SystemProperties.class, "org.apache.geronimo.interop.simpleIDL");

    public static final IntProperty socketTimeoutProperty =
            new IntProperty(Connection.class, "socketTimeout")
            .defaultValue(600); // 10 minutes

    private static final boolean SIMPLE_IDL = simpleIDLProperty.getBoolean();

    private static final ServiceContext[] EMPTY_SERVICE_CONTEXT = {};

    private static final byte[] CODE_SET_ENCAPSULATION =
    {
        (byte)0, // big endian
        (byte)0, (byte)0, (byte)0, // padding
        (byte)0x05, (byte)0x01, (byte)0x00, (byte)0x01, // 0x05010001 = CodeSet ID for UTF-8
        (byte)0x00, (byte)0x01, (byte)0x01, (byte)0x09, // 0x00010109 = CodeSet ID for UTF-16
    };

    private static final ServiceContext CODE_SET_SERVICE_CONTEXT = new ServiceContext(1, CODE_SET_ENCAPSULATION);

    private String              url;

    private boolean             ok;

    private InstancePool        pool;

    private Socket              socket;

    protected org.apache.geronimo.interop.rmi.iiop.ObjectInputStream input;

    protected org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream output;

    private CdrOutputStream     parameters;

    private CdrOutputStream     requestOut;

    private CdrInputStream      results;

    private String              exceptionType;

    private Exception           exception;

    private RequestHeader_1_2   requestHeader;

    private int                 callForget;


    protected java.io.InputStream   socketIn;

    protected java.io.OutputStream  socketOut;

    public String getInstanceName()
    {
        return url;
    }

    public void close()
    {
        parameters = null;
        input = null;
        output = null;
        if (ok)
        {
            pool.put(this);
        }
        else
        {
            shutdown();
        }
    }

    public void beforeInvoke() {
        ok = false;
        parameters = CdrOutputStream.getInstance();
    }

    public void forget(Object requestKey) {
    }

    public void invoke(ObjectRef object, String method, Object requestKey, int retryCount)
    {
        if(object.$getForwardingAddress() != null)
        {
            object = object.$getForwardingAddress();
        }

        RequestHeader_1_2 request = requestHeader;

        request.request_id = requestid_++;
        request.response_flags = 3;
        request.target = new TargetAddress();
        request.target.object_key(object.$getObjectKey());
        request.operation = method;
        request.service_context = getServiceContext(object, requestKey, retryCount);
        request.reserved = reservedBA;  // Sun's generated org.omg.GIOP.RequestHeader_1_2Helper wants this....

        if (requestOut == null)
        {
            requestOut = CdrOutputStream.getInstance();
        }
        requestOut.write_request(request, parameters);


        try
        {
            if(httpTunnelled)
            {
                requestOut.send_http_request(socketOut, url, httpHeaders);
            }
            else
            {
                requestOut.send_message(socketOut, url);
            }
        } catch (RuntimeException ex) {
            throw ex;
        }

        requestOut.reset();

        if (results == null)
        {
            results = CdrInputStream.getInstance();
        }
        else
        {
            results.reset();
        }

        results.setNamingContext(object.$getNamingContext());
        GiopMessage message;
        try
        {
            if(httpTunnelled)
            {
                message = results.receive_http_response(socketIn, url);
            }
            else
            {
                message = results.receive_message(socketIn, url);//_serverHost);
            }
        }
        catch (BadMagicException ex)
        {
            throw new SystemException(ex);
        }
        catch (UnsupportedProtocolVersionException ex)
        {
            throw new SystemException(ex);
        }
        catch (RuntimeException ex)
        {
            throw new RetryInvokeException(ex);
        }

        switch (message.type)
        {
          case MsgType_1_1._Reply:
                processReply(message.reply, object);
                break;

            default:
                throw new SystemException("TODO: message type = " + message.type);
        }

        ok = true;
    }

    public InstancePool getInstancePool() {
        return pool;
    }

    public void setInstancePool(InstancePool pool) {
        this.pool = pool;
    }

    public org.apache.geronimo.interop.rmi.iiop.ObjectInputStream getInputStream() {
        if (SIMPLE_IDL) {
            return getSimpleInputStream();
        }
        if (input == null) {
            input = org.apache.geronimo.interop.rmi.iiop.ObjectInputStream.getInstance(results);
        }
        return input;
    }

    public org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream getOutputStream() {
        if (SIMPLE_IDL) {
            return getSimpleOutputStream();
        }
        if (output == null) {
            output = org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream.getInstance(parameters);
        }
        return output;
    }

    public org.apache.geronimo.interop.rmi.iiop.ObjectInputStream getSimpleInputStream() {
        if (input == null) {
            input = org.apache.geronimo.interop.rmi.iiop.SimpleObjectInputStream.getInstance(results);
        }
        return input;
    }

    public org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream getSimpleOutputStream() {
        if (output == null) {
            output = org.apache.geronimo.interop.rmi.iiop.SimpleObjectOutputStream.getInstance(parameters);
        }
        return output;
    }

    public String getExceptionType() {
        return exceptionType;
    }

    public Exception getException() {
        if (exception == null) {
            if (exceptionType != null) {
                return new SystemException(exceptionType, new org.omg.CORBA.UNKNOWN());
            } else {
                throw new IllegalStateException("no exception");
            }
        } else {
            return exception;
        }
    }

    public void clearException()
    {
        exceptionType = null;
        exception = null;
    }

    // TODO: check why we have 'objectRef' parameter???
    protected void init(String endpoint, ObjectRef objectRef, PropertyMap connProps)
    {
        setHttpTunnelledPropsIfTrue(connProps);

        if(httpTunnelled)
        {
            httpInit(endpoint, connProps);
            return;
        }

        url = "iiop://" + endpoint;
        UrlInfo urlInfo = UrlInfo.getInstance(url);
        String host = urlInfo.getHost();
        int port = urlInfo.getPort();
        int socketTimeout = socketTimeoutProperty.getInt(endpoint, connProps);
        try
        {
            socket = new Socket(host, port);
            socketIn = socket.getInputStream();
            socketOut = socket.getOutputStream();
            socket.setSoTimeout(1000 * socketTimeout);
        }
        catch (Exception ex)
        {
            throw new SystemException(ex);
        }
        requestHeader = new RequestHeader_1_2();
        requestHeader.reserved = reservedBA;
    }

    private void httpInit(String endpoint, PropertyMap connProps)
    {
        String host = null;
        int port;
        url = "iiop://" + endpoint;
        int socketTimeout = socketTimeoutProperty.getInt(endpoint, connProps);

        if(webProxyHost != null)
        {
            host = webProxyHost;
            port = webProxyPort;
        }
        else
        {
            UrlInfo urlInfo = UrlInfo.getInstance(url);
            host = urlInfo.getHost();
            port = urlInfo.getPort();
        }

        try
        {
            socket = new Socket(host, port);
            socketIn = socket.getInputStream();
            socketOut = socket.getOutputStream();
            socket.setSoTimeout(1000 * socketTimeout);
        }
        catch (IOException ex)
        {
            throw new SystemException(ex);
        }
        requestHeader = new RequestHeader_1_2();
        requestHeader.reserved = reservedBA;
    }

    public ServiceContext[] getServiceContext(ObjectRef object, Object requestKey, int retryCount) {
        String username;
        String password;
        SecurityInfo securityInfo = SecurityInfo.getCurrent();
        if (securityInfo == null) {
            ClientNamingContext namingContext = object.$getNamingContext();
            if (namingContext != null) {
                username = namingContext.getUsername();
                password = namingContext.getPassword();
            } else {
                username = null;
                password = null;
            }
        } else {
            username = securityInfo.username;
            password = securityInfo.password;
        }
        if (username != null && username.length() == 0) {
            username = null; // Save network bandwidth in service context.
        }
        if (password != null && password.length() == 0) {
            password = null; // Save network bandwidth in service context.
        }
        int count = 0;
        if (username != null) {
            count++;
        }
        if (password != null) {
            count++;
        }
        if (requestKey != null) {
            count++;
        }
        ServiceContext[] context = new ServiceContext[count];
        int index = 0;
        context[index++] = CODE_SET_SERVICE_CONTEXT;
        if (username != null) {
            context[index++] = new ServiceContext(SecurityInfo.TAG_USERNAME, SecurityInfo.encode(username));
        }
        if (password != null) {
            context[index++] = new ServiceContext(SecurityInfo.TAG_PASSWORD, SecurityInfo.encode(password));
        }
        return context;
    }

    protected void processReply(ReplyHeader_1_2 reply, ObjectRef object)
    {
        processReplyServiceContext(reply);
        int status = reply.reply_status.value();
        switch (status)
        {
          case ReplyStatusType_1_2._NO_EXCEPTION:
            processNormalReply(reply);
            break;
          case ReplyStatusType_1_2._USER_EXCEPTION:
            processUserException(reply);
            break;
          case ReplyStatusType_1_2._SYSTEM_EXCEPTION:
            processSystemException(reply);
            break;
          case ReplyStatusType_1_2._LOCATION_FORWARD:
            processLocationForward(reply, object);
            break;
          case ReplyStatusType_1_2._LOCATION_FORWARD_PERM:
            processLocationForward(reply, object);
            break;
          case ReplyStatusType_1_2._NEEDS_ADDRESSING_MODE:
            throw new SystemException("TODO");
          default:
            throw new SystemException("reply status = " + status);
        }
    }

    protected void processLocationForward(ReplyHeader_1_2 reply, ObjectRef object)
    {
        ObjectRef ref = (ObjectRef)results.read_Object();
        object.$setForwardingAddress(ref);
        throw new RetryInvokeException(new RuntimeException("LOCATION_FORWARD"));
    }

    protected void processReplyServiceContext(ReplyHeader_1_2 reply) {
        ServiceContext[] list = reply.service_context;
        int n = list.length;
        for (int i = 0; i < n; i++) {
            ServiceContext sc = list[i];
            if (sc.context_id == 0xCFCFCFCF
                || sc.context_id == 0xDFDFDFDF) {
                // "CF..." indicates "Call Forget Request"
                // "DF..." indicates "Call Forget Response"
                callForget = sc.context_id;
            }
        }
    }

    protected void processNormalReply(ReplyHeader_1_2 reply) {
        // Intentionally empty.
    }

    protected void processUserException(ReplyHeader_1_2 reply)
    {
        exception = null;
        String type = results.read_string();
        type = StringUtil.removePrefix(type, "IDL:");
        type = StringUtil.removeSuffix(type, ":1.0");
        if (! (input instanceof SimpleObjectInputStream))
        {
            if (type.endsWith("Ex"))
            {
                type = StringUtil.removeSuffix(type, "Ex") + "Exception";
            }
        }
        type = type.replace('/', '.');
        exceptionType = type;
        ok = true;
    }

    protected void processSystemException(ReplyHeader_1_2 reply)
    {
        exceptionType = "???";
        SystemExceptionReplyBody replyBody = SystemExceptionReplyBodyHelper.read(results);
        String id = replyBody.exception_id;
        id = StringUtil.removePrefix(id, "IDL:CORBA/"); // ancient servers might send this!
        id = StringUtil.removePrefix(id, "IDL:omg.org/CORBA/");
        id = StringUtil.removeSuffix(id, ":1.0");
        String causedBy = null;
        if (results.hasMoreData())
        {
            // This is non-standard for IIOP, but if the data isn't present,
            // we wont try to read it!
            causedBy = ExceptionUtil.causedBy(results.read_string());
        }
        ok = true;
        String exceptionClassName = "org.omg.CORBA." + id;
        try
        {
            Class exceptionClass = ThreadContext.loadClass(exceptionClassName);
            Constructor constructor = exceptionClass.getConstructor
            (
                new Class[] { String.class }
            );
            org.omg.CORBA.SystemException corbaException;
            corbaException = (org.omg.CORBA.SystemException)constructor.newInstance
            (
                new Object[] { causedBy == null ? "" : causedBy }
            );
            corbaException.minor = replyBody.minor_code_value;
            corbaException.completed = org.omg.CORBA.CompletionStatus.from_int(replyBody.completion_status);
            exception = corbaException;
        }
        catch (Exception ex)
        {
            // Shouldn't happen, but just in case
            ex.printStackTrace();
            if (causedBy == null)
            {
                causedBy = replyBody.exception_id;
            }
            else
            {
                causedBy = replyBody.exception_id + "\nCaused by: " + causedBy;
            }
            exception = new org.omg.CORBA.UNKNOWN(causedBy,
                replyBody.minor_code_value,
                org.omg.CORBA.CompletionStatus.from_int(replyBody.completion_status));
        }
    }

    private void setHttpTunnelledPropsIfTrue(PropertyMap connprops)
    {
        if(connprops.get("http") != null)
        {
            httpTunnelled = true;
        }
        else
        {
            httpTunnelled = false;
        }

        if(httpTunnelled)
        {
            // get http extra headers if present
            httpHeaders = connprops.getProperty("HttpExtraHeader");

            if(httpHeaders != null && httpHeaders.toLowerCase().indexOf("user-agent") == -1)
            {
                httpHeaders += "User-Agent: Geronimo/1.0\r\n";
            }

            if(httpHeaders == null)
            {
                httpHeaders = "User-Agent: Geronimo/1.0\r\n";
            }

            //get webproxy host/port if present:
            webProxyHost = connprops.getProperty("WebProxyHost");
            String port = connprops.getProperty("WebProxyPort");

            if(port != null)
            {
                try
                {
                    webProxyPort = java.lang.Integer.parseInt(port);
                }
                catch(java.lang.NumberFormatException e)
                {
                    throw new SystemException(org.apache.geronimo.interop.util.ExceptionUtil.causedBy(e));
                }
            }

            if(port == null && webProxyHost != null)
            {
                webProxyPort = 80//default
            }
        }
        else
        {
            webProxyHost = null;
            httpHeaders = null;
        }
    }

    public void shutdown() {
        if (socketOut != null) {
            try {
                socketOut.close();
            } catch (Exception ignore) {
            }
            socketOut = null;
        }
        if (socketIn != null) {
            try {
                socketIn.close();
            } catch (Exception ignore) {
            }
            socketIn = null;
        }
        if (socket != null) {
            try {
                socket.close();
            } catch (Exception ignore) {
            }
            socket = null;
        }
    }
}
TOP

Related Classes of org.apache.geronimo.interop.rmi.iiop.client.Connection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.