Package org.eclipse.persistence.internal.sessions.coordination.jgroups

Source Code of org.eclipse.persistence.internal.sessions.coordination.jgroups.JGroupsRemoteConnection

/*******************************************************************************
* Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*     Oracle - initial API and implementation
******************************************************************************/ 
package org.eclipse.persistence.internal.sessions.coordination.jgroups;

import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.coordination.broadcast.BroadcastRemoteConnection;
import org.eclipse.persistence.sessions.coordination.RemoteCommandManager;
import org.eclipse.persistence.sessions.serializers.Serializer;

import org.jgroups.JChannel;
import org.jgroups.Message;
import org.jgroups.ReceiverAdapter;

/**
* <p>
* <b>Purpose</b>: Define the implementation of the abstract RemoteConnection for JGroups.
* <p>
* <b>Description</b>:  Executing commands implementation of RemoteConnection is done via JGroups JChannel.
*
* @author James Sutherland
* @since EclipseLink 2.5
*/
public class JGroupsRemoteConnection extends BroadcastRemoteConnection {
    protected JChannel channel;
    // indicates whether it's a local connection.
    protected boolean isLocal;
   
    /**
     * INTERNAL:
     * Constructor creating either a local or external connection.
     */
    public JGroupsRemoteConnection(RemoteCommandManager rcm, JChannel channel, boolean isLocalConnectionBeingCreated) {
        super(rcm);
        this.channel = channel;
        this.isLocal = isLocalConnectionBeingCreated;
        rcm.logDebug("creating_broadcast_connection", getInfo());
        try {
            if (isLocalConnectionBeingCreated) {
                // it's a local connection
                this.channel.setReceiver(new ReceiverAdapter() {
                    public void receive(Message message) {
                        onMessage(message);
                    }
                });
                rcm.logDebug("broadcast_connection_created", getInfo());
            }
        } catch (RuntimeException ex) {
            rcm.logDebug("failed_to_create_broadcast_connection", getInfo());
            close();
            throw ex;
        }
    }
   
    /**
     * Creates local connections.
     */
    public JGroupsRemoteConnection(RemoteCommandManager rcm){
        super(rcm);
        this.isLocal = true;
    }

    /**
     * INTERNAL:
     * Indicates whether connection is local (subscriber)
     * or external (publisher).
     */
    public boolean isLocal() {
        return isLocal;
    }
   
    /**
     * INTERNAL:
     * Execute the remote command. The result of execution is returned.
     * This method is used only by external (publishing) connection.
     */
    @Override
    protected Object executeCommandInternal(Object command) throws Exception {
        Message message = null;
        if (command instanceof byte[]) {
            message = new Message(null, null, (byte[])command);
        } else {
            message = new Message(null, null, command);
        }
           
        Object[] debugInfo = null;
        if(this.rcm.shouldLogDebugMessage()) {
            debugInfo = logDebugBeforePublish(null);
        }
           
        this.channel.send(message);
           
        // debug logging is on
        if (debugInfo != null) {
            logDebugAfterPublish(debugInfo, null);
        }
       
        return null;
    }

    /**
     * INTERNAL:
     * Process received JGroups message.
     * This method is used only by local (listening) connection.
     */
    public void onMessage(Message message) {
        String messageId = "";
        if (rcm.shouldLogDebugMessage()) {
            logDebugOnReceiveMessage(null);
            logDebugMessage(message);
        }

        Object object = null;
        try {
            Serializer serializer = this.rcm.getSerializer();
            if (serializer != null) {
                object = serializer.deserialize(message.getBuffer(), (AbstractSession)this.rcm.getCommandProcessor());
            } else {
                object = message.getObject();           
            }
        } catch (Exception exception) {
            failDeserializeMessage(null, exception);
            return;
        }
       
        processReceivedObject(object, messageId);
    }

    /**
     * INTERNAL:
     * Indicates whether all the resources used by connection are freed after close method returns.
     */
    protected boolean areAllResourcesFreedOnClose() {
        return !isLocal();
    }

    /**
     * INTERNAL:
     * This method is called by close method.
     */
    protected void closeInternal() {
        if (areAllResourcesFreedOnClose() && this.channel != null) {
            this.channel.close();
        }
    }

    /**
     * INTERNAL:
     */
    protected String logDebugMessage(Message message) {
        Object[] args = { this.channel.getName() };
        // call logDebugWithoutLevelCheck to avoid the second rcm.shouldLogDebugMessage() check
        rcm.logDebugWithoutLevelCheck("retreived_remote_message_from_jgroup_channel", args);
        return this.channel.getName();
    }

    /**
     * INTERNAL:
     * Used for debug logging
     */
    protected void createDisplayString() {
        this.displayString = Helper.getShortClassName(this) + "[" + serviceId.toString() + "]";
    }

    /**
     * INTERNAL:
     * Return whether a BroadcastConnection should check a ServiceId against its
     * own ServiceId to avoid the processing of Commands with the same ServiceId.
     * Not required for JGroups.
     */
    protected boolean shouldCheckServiceId() {
        return false;
    }
}
TOP

Related Classes of org.eclipse.persistence.internal.sessions.coordination.jgroups.JGroupsRemoteConnection

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.