/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/*
* ReplicationState.java
*
* Created on November 22, 2005, 11:45 AM
*
*/
package com.sun.enterprise.ee.web.sessmgmt;
import com.sun.appserv.ha.util.Metadata;
import com.sun.appserv.ha.util.CompositeMetadata;
import com.sun.appserv.ha.util.SimpleMetadata;
import com.sun.appserv.ha.util.SimpleMetadataFactory;
import com.sun.appserv.ha.spi.BackingStoreException;
import com.sun.appserv.ha.uow.ReplicableEntity;
import com.sun.enterprise.ee.web.authenticator.SSOExtraParams;
import com.sun.enterprise.web.ServerConfigLookup;
import com.sun.logging.LogDomains;
import net.jxta.endpoint.ByteArrayMessageElement;
import net.jxta.endpoint.Message;
import net.jxta.endpoint.MessageElement;
import net.jxta.endpoint.StringMessageElement;
import net.jxta.protocol.RouteAdvertisement;
import org.apache.catalina.Session;
import org.apache.catalina.session.*;
import java.io.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;
/**
*
* @author Larry White
*/
public class ReplicationState implements Serializable {
/**
* The logger to use for logging ALL web container related messages.
*/
private final static Logger _logger
= LogDomains.getLogger(LogDomains.WEB_LOGGER);
public final static String LOGGER_MEM_REP
= "com.sun.enterprise.ee.web.sessmgmt";
public final static String MODE_WEB = "web";
public final static String MODE_SSO = "sso";
public final static String MODE_EJB = "ejb";
public final static String MODE_SIP = "sip";
public final static String MODE_STARTUP = "startup";
public final static String MESSAGE_MODE = "message_mode";
public final static String BULK_MESSAGE_MODE = "bulk_message_mode";
public final static String BULK_MESSAGE_ID = "bulk_message_id";
public final static String MESSAGE_ID = "message_id";
public final static String SAS_PARENT_ID = "sas_parent_id";
public final static String BEKEY = "bekey";
public final static String IMMEDIATE_REPLICA_PARTNER = "immediate_replica_partner";
final static String MESSAGE_APPID = "message_appid";
final static String MESSAGE_VERSION = "message_version";
final static String MESSAGE_COMMAND = "message_command";
final static String MESSAGE_LAST_ACCESS = "message_last_access";
final static String MESSAGE_MAX_INACTIVE = "message_max_inactive";
//final static String MESSAGE_SSO_ID = "message_sso_id";
//final static String MESSAGE_USER_NAME = "message_user_name";
final static String MESSAGE_EXTRA_PARAM = "message_extra_param";
public final static String MESSAGE_ACK_REQUIRED = "message_ack_required";
public final static String MESSAGE_IS_NACK = "message_is_nack";
public final static String MESSAGE_ACK_LIST_PROPERTY = "message_ack_list_property";
public final static String MESSAGE_SEND_START_TIME = "message_send_start_time";
final static String MESSAGE_QUERY_RESULT = "message_query_result";
final static String MESSAGE_INSTANCE_NAME = "message_instance_name";
final static String MESSAGE_DATA = "message_data";
final static String MESSAGE_TOTAL_STATES = "message_total_states";
final static String MESSAGE_ACK_IDS_LIST = "message_ack_ids_list";
final static String MESSAGE_TRUNK_DATA = "message_trunk_data";
final static String MESSAGE_PROPERTIES_DATA = "message_properties_data";
final static String MESSAGE_CONTAINER_EXTRA_PARAMS_DATA = "message_container_extra_params_data";
final static String MESSAGE_READY = "ready";
final static String MESSAGE_BIDI_STYLE = "message_bidi_style";
final static String ReadyMessage = "ready";
//used for unicast route advertisement
public static final String NAMESPACE = "INSTANCE";
public static final String ROUTEADV = "ROUTE";
final static String RETURN_MSG_COMMAND = "response";
public final static String MESSAGE_BROADCAST_QUERY = "broadcastFindSession";
public final static String RETURN_BROADCAST_MSG_COMMAND = "broadcastResponse";
public final static String RETURN_UNICAST_MSG_COMMAND = "unicastResponse";
public final static String MESSAGE_BROADCAST_LOAD_RECEIVED = "broadcastLoadReceived";
public final static String MESSAGE_BROADCAST_LOAD_ADVISORY = "broadcastLoadAdvisory";
public final static String MESSAGE_BROADCAST_PURGE_ADVISORY = "broadcastPurgeAdvisory";
public final static String MESSAGE_BROADCAST_FIND_EXPAT_IDS = "broadcastFindExpatIds";
public final static String MESSAGE_APPLICATION_STATUS_QUERY = "broadcastapplicationstatus";
public final static String MESSAGE_BROADCAST_NETWORK_PARTITION_ADVISORY
= "broadcastNetworkPartitionAdvisory";
final static String InstanceNameMessage = "instance_name";
final static boolean METHOD_RETURN_VOID = true;
//commands
public final static String SAVE_COMMAND = "save";
public final static String VALVE_SAVE_COMMAND = "valveSave";
public final static String REMOVE_COMMAND = "remove";
public final static String UNDEPLOY_COMMAND = "undeploy";
public final static String REMOVE_EXPIRED_COMMAND = "removeExpired";
public final static String REMOVE_SYNCHRONIZED_COMMAND = "removeSynchronized";
public final static String UPDATE_LAST_ACCESS_TIME_COMMAND = "updateLastAccessTime";
public final static String SIZE_COMMAND = "size";
public final static String COMPOSITE_SAVE_COMMAND = "compositeSave";
public final static String REMOVE_IDS_COMMAND = "removeIds";
final static String BULK_MESSAGE_COMMAND = "bulk_message_command";
public final static String HC_COMMAND = "healthCheck";
final static String RETURN_HC_MSG_COMMAND = "healthCheckResponse";
public final static String DUPLICATE_IDS_SEMANTICS_PROPERTY
= "duplicate_ids_semantics_property";
public final static String WAIT_FOR_ACK_PROPERTY
= "wait_for_ack_property";
public final static String SUPPRESS_LOAD_ACK_PROPERTY
= "suppress_load_ack_property";
public final static String REPLICATION_COMPRESSION_PROPERTY
= "replication_compression_property";
public final static String SESSION_MANAGER_PROPERTY
= "session_manager_property";
public static final String ID = "id";
public static final String ORIGINATING_INSTANCE_NAME = "originating_instance_name";
public static final String IGNORE_REMOVE_INSTANCE_NAME = "ignore_remove_instance_name";
public static final String WAIT_TIME = "wait_time";
/**
* Creates a new instance of ReplicationState
*/
public ReplicationState() {
}
/**
* Creates a new instance of ReplicationState
* want this package protected
*/
ReplicationState(Object id) {
this();
_id = id;
}
/**
* Creates a new instance of ReplicationState
*/
public ReplicationState(String mode, Object id, String appId, long version, long lastAccess, long maxInactiveInterval, String extraParam, Object queryResult, String instanceName, String command, byte[] state, byte[] trunkState, byte[] containerExtraParamsState) {
_mode = mode;
_id = id;
_appId = appId;
_version = version;
_maxInactiveInterval = maxInactiveInterval;
_lastAccess = lastAccess;
_extraParam = extraParam;
_queryResult = queryResult;
_instanceName = instanceName;
_command = command;
_state = state;
_trunkState = trunkState;
_containerExtraParamsState = containerExtraParamsState;
_hc = _id.hashCode();
}
/**
* Creates a new instance of ReplicationState cloned (shallow-copy)
* from originalState
* @param originalState
*/
public static ReplicationState createReplicationStateFrom(ReplicationState originalState) {
ReplicationState result =
new ReplicationState(originalState.getMode(),
originalState.getId(),
originalState.getAppId(),
originalState.getVersion(),
originalState.getLastAccess(),
originalState.getMaxInactiveInterval(),
originalState.getExtraParam(),
originalState.getQueryResult(),
originalState.getInstanceName(),
originalState.getCommand(),
originalState.getState(),
originalState.getTrunkState(),
originalState.getContainerExtraParamsState());
return result;
}
/**
* the list of method names that are removes
*/
private static List removeMethods
= Arrays.asList(REMOVE_COMMAND, REMOVE_SYNCHRONIZED_COMMAND);
/**
* the list of method names with void return
*/
private static List voidReturnsMethods
= Arrays.asList(SAVE_COMMAND,
VALVE_SAVE_COMMAND, REMOVE_SYNCHRONIZED_COMMAND,
REMOVE_COMMAND, UPDATE_LAST_ACCESS_TIME_COMMAND,
COMPOSITE_SAVE_COMMAND, HC_COMMAND);
/**
* the list of method names that are hc (health check)
*/
private static List hcMethods
= Arrays.asList(HC_COMMAND);
/**
* the list of method names that are responses
*/
private static List responseMethods
= Arrays.asList(RETURN_MSG_COMMAND,
RETURN_BROADCAST_MSG_COMMAND,
RETURN_UNICAST_MSG_COMMAND);
public static ReplicationState getBestResult(ReplicationState localState,
ReplicationState broadcastResultState) {
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationStore>>getBestResult:localState=" + localState + "other=" + broadcastResultState);
}
if(localState == null) {
return broadcastResultState;
}
//localState is not null
if(broadcastResultState == null) {
return localState;
}
//both are non-null
if(broadcastResultState.getVersion() >= localState.getVersion()) {
return broadcastResultState;
} else {
return localState;
}
}
public static SimpleMetadata createSimpleMetadataFrom(
ReplicationState replicationState, boolean compressionEnabled)
throws BackingStoreException {
if(replicationState == null) {
return null;
}
try {
Object containerExtraParams = getContainerExtraParamFrom(
replicationState, compressionEnabled);
SimpleMetadata result = SimpleMetadataFactory.createSimpleMetadata(replicationState.getVersion(),
replicationState.getLastAccess(), replicationState.getMaxInactiveInterval(),
replicationState.getState(),
containerExtraParams);
return result;
} catch (Exception ex) {
throw new BackingStoreException("error during deserialization of extra parameters", ex);
}
}
public static Object getContainerExtraParamFrom(ReplicationState queryResult,
boolean compressionEnabled)
throws BackingStoreException {
/* this logic may apply for EJB do not remove yet
if(this.getMode() == MODE_SSO) {
return queryResult.getExtraParam();
}
*/
//deserialize containerExtraParams if present
//note: we assume extra param state is deserializable
//using the system class loader
Object containerExtraParams = null;
byte[] containerExtraParamState = queryResult.getContainerExtraParamsState();
if(containerExtraParamState != null) {
try {
containerExtraParams = getObjectValue(containerExtraParamState,
compressionEnabled);
} catch (Exception ex) {
throw new BackingStoreException("error during deserialization of extra parameters", ex);
}
}
return containerExtraParams;
}
/**
* create a response ReplicationState from the input ReplicationState
* @param input
*/
public static ReplicationState createResponseFrom(ReplicationState input) {
return new ReplicationState(
input.getMode(),
input.getId(),
input.getAppId(),
input.getVersion(),
input.getLastAccess(),
input.getMaxInactiveInterval(),
input.getExtraParam(),
input.getQueryResult(),
input.getInstanceName(),
RETURN_MSG_COMMAND,
input.getState(),
input.getTrunkState(),
input.getContainerExtraParamsState());
}
public static ReplicationState createQueryResponseFrom(ReplicableEntity session,
String appId,
String mode,
String command,
String origin,
boolean isCompressionEnabled,
boolean useUnicast) {
byte[] containerExtraParamState = null;
byte[] state = null;
Serializable containerExtraParams
= session.getExtraParameters();
if(containerExtraParams != null) {
try {
containerExtraParamState
= ReplicationUtil.getByteArray(containerExtraParams, isCompressionEnabled);
state = ReplicationUtil.getByteArray(session, isCompressionEnabled);
} catch (IOException ex) {
_logger.warning("Unable to serialize " + session +
", error message = " + ex.getMessage());
; //deliberate no-op
}
}
ReplicationState result = null;
if(!useUnicast) {
result = new ReplicationState(
mode,
session.getId(),
appId,
session.getVersion(),
0L,
0L,
null,
null,
null,
ReplicationState.RETURN_BROADCAST_MSG_COMMAND,
state,
null,
containerExtraParamState);
} else {
result = new ReplicationState(
mode,
session.getId(),
appId,
session.getVersion(),
0L,
0L,
command, //put original command in extraParam slot
null,
null,
ReplicationState.RETURN_UNICAST_MSG_COMMAND,
state,
null,
containerExtraParamState);
}
result.setProperties(session.getBeKey(), origin);
return result;
}
/**
* create a query response ReplicationState from the input ReplicationState
* @param input
*/
public static ReplicationState createUnicastQueryResponseFrom(ReplicationState input, String queryCommand) {
String extraParam = input.getExtraParam();
//store original commend in extraParam if it exists
if(queryCommand != null) {
extraParam = queryCommand;
}
ReplicationState result = new ReplicationState(
input.getMode(),
input.getId(),
input.getAppId(),
input.getVersion(),
input.getLastAccess(),
input.getMaxInactiveInterval(),
extraParam,
input.getQueryResult(),
input.getInstanceName(),
RETURN_UNICAST_MSG_COMMAND,
input.getState(),
input.getTrunkState(),
input.getContainerExtraParamsState());
return result;
}
/**
* create a query response ReplicationState from the input ReplicationState
* @param input
*/
public static ReplicationState createQueryResponseFrom(ReplicationState input) {
ReplicationState result = new ReplicationState(
input.getMode(),
input.getId(),
input.getAppId(),
input.getVersion(),
input.getLastAccess(),
input.getMaxInactiveInterval(),
input.getExtraParam(),
input.getQueryResult(),
input.getInstanceName(),
RETURN_BROADCAST_MSG_COMMAND,
input.getState(),
input.getTrunkState(),
input.getContainerExtraParamsState());
return result;
}
/**
* create a query response ReplicationState from the input ReplicationState
* @param input
* @param isNack is this a nack response
*/
public static ReplicationState createQueryResponseFrom(ReplicationState input, boolean isNack) {
if(!isNack) {
return createQueryResponseFrom(input);
} else {
ReplicationState result = new ReplicationState(
input.getMode(),
input.getId(),
input.getAppId(),
input.getVersion(),
input.getLastAccess(),
input.getMaxInactiveInterval(),
input.getExtraParam(),
input.getQueryResult(),
input.getInstanceName(),
RETURN_BROADCAST_MSG_COMMAND,
null, //state do not pass state in a nack
null, //trunkState do not pass in a nack
null); //containerExtraParamsState do not pass in a nack
result._isNack=true; //this is a nack
//in the nack case the input is the queryState
//and contains the route advertisement
result.setRouteAdvertisement(input.getRouteAdvertisement());
return result;
}
}
/**
* create a query response ReplicationState from the input ReplicationState
* @param input
* @param isNack is this a nack response
*/
public static ReplicationState createUnicastQueryResponseFrom(ReplicationState input, boolean isNack) {
if(!isNack) {
return createUnicastQueryResponseFrom(input, input.getCommand());
} else {
ReplicationState result = new ReplicationState(
input.getMode(),
input.getId(),
input.getAppId(),
input.getVersion(),
input.getLastAccess(),
input.getMaxInactiveInterval(),
input.getCommand(), //store original commend in extraParam
input.getQueryResult(),
input.getInstanceName(),
RETURN_UNICAST_MSG_COMMAND,
null, //state do not pass state in a nack
null, //trunkState do not pass in a nack
null); //containerExtraParamsState do not pass in a nack
result._isNack=true; //this is a nack
//in the nack case the input is the queryState
//and contains the route advertisement
result.setRouteAdvertisement(input.getRouteAdvertisement());
return result;
}
}
/**
* create a query response ReplicationState from the input ReplicationState
* @param input
* @param extraParam extraParam for the response
* @param queryResult queryResult for the response
*/
public static ReplicationState createQueryResponseFrom(ReplicationState input, String extraParam, String queryResult) {
ReplicationState result = createQueryResponseFrom(input);
result._extraParam=extraParam;
result._queryResult = queryResult;
result.setRouteAdvertisement(input.getRouteAdvertisement());
return result;
}
/**
* create a query response ReplicationState from the input ReplicationState
* @param input
*/
public static ReplicationState createQueryResponseFrom(ReplicationState input, byte[] returnState) {
ReplicationState result = new ReplicationState(
input.getMode(),
input.getId(),
input.getAppId(),
input.getVersion(),
input.getLastAccess(),
input.getMaxInactiveInterval(),
input.getExtraParam(),
input.getQueryResult(),
input.getInstanceName(),
RETURN_BROADCAST_MSG_COMMAND,
returnState,
input.getTrunkState(),
input.getContainerExtraParamsState());
return result;
}
/**
* create a query response ReplicationState from the input ReplicationState
* @param input
* @param isNack is this a nack response
*/
public static ReplicationState createQueryResponseFrom(ReplicationState input, byte[] returnState, boolean isNack) {
if(!isNack) {
return createQueryResponseFrom(input, returnState);
} else {
ReplicationState result = new ReplicationState(
input.getMode(),
input.getId(),
input.getAppId(),
input.getVersion(),
input.getLastAccess(),
input.getMaxInactiveInterval(),
input.getExtraParam(),
input.getQueryResult(),
input.getInstanceName(),
RETURN_BROADCAST_MSG_COMMAND,
null, //state do not pass state in a nack
null, //trunkState do not pass in a nack
null); //containerExtraParamsState do not pass in a nack
result._isNack=true; //this is a nack
//in the nack case the input is the queryState
//and contains the route advertisement
result.setRouteAdvertisement(input.getRouteAdvertisement());
return result;
}
}
/**
* create a response ReplicationState from the input ReplicationState
* @param input
*
* @param newState - updated state
*/
public static ReplicationState createUpdatedStateFrom(ReplicationState input, byte[] newState) {
return new ReplicationState(
input.getMode(),
input.getId(),
input.getAppId(),
input.getVersion(),
input.getLastAccess(),
input.getMaxInactiveInterval(),
input.getExtraParam(),
input.getQueryResult(),
input.getInstanceName(),
RETURN_MSG_COMMAND,
newState,
input.getTrunkState(),
input.getContainerExtraParamsState());
}
/**
* create a response ReplicationState from the input ReplicationState
* @param input
* @param theCommand
* @param newState - updated state
*/
public static ReplicationState createUpdatedStateFrom(ReplicationState input, String theCommand, byte[] newState) {
return new ReplicationState(
input.getMode(),
input.getId(),
input.getAppId(),
input.getVersion(),
input.getLastAccess(),
input.getMaxInactiveInterval(),
input.getExtraParam(),
input.getQueryResult(),
input.getInstanceName(),
theCommand,
newState,
input.getTrunkState(),
input.getContainerExtraParamsState());
}
static List<ReplicationState> extractBulkReplicationStatesFromMessage(Message msg) {
List<ReplicationState> states = null;
byte[] data = null;
MessageElement dataMsgElement =
msg.getMessageElement(MESSAGE_DATA, MESSAGE_DATA);
MessageElement totalStatesElement =
msg.getMessageElement(MESSAGE_TOTAL_STATES, MESSAGE_TOTAL_STATES);
if(dataMsgElement != null) {
data = dataMsgElement.getBytes(false);
ObjectInputStream ois = null;
ByteArrayInputStream bis = null;
try {
bis = new ByteArrayInputStream(data);
ois = new ObjectInputStream(bis);
states = (List<ReplicationState>) ois.readObject();
} catch (IOException ioEx) {
_logger.log(Level.INFO, "ReplicationState: IOEx ", ioEx);
} catch (ClassNotFoundException cnfEx) {
_logger.log(Level.INFO, "ReplicationState: CNF ", cnfEx);
} finally {
try {
bis.close();
} catch (Exception ex) {
if (_logger.isLoggable(Level.FINEST)) {
_logger.finest("error closing stream");
}
}
try {
ois.close();
} catch (Exception ex) {
if (_logger.isLoggable(Level.FINEST)) {
_logger.finest("error closing stream");
}
}
}
}
return states;
}
/**
* create a ReplicationState from the input msg
* @param msg
*/
public static ReplicationState createReplicationState(Message msg) {
//FIXME all messages should have a non-null mode check all
// message creating code later
String mode = MODE_WEB;
String id = "";
String appid = "";
String bulkMode = null;
String bulkId = "";
long version = 0L;
long lastAccess = 0L;
long maxInactive = 0L;
String extraParam = null;
Object queryResult = null;
String instanceName = null;
byte[] data = null;
byte[] trunkData = null;
byte[] containerExtraParamsData = null;
byte[] propertiesState = null;
HashMap properties = null;
MessageElement modeMsgElement =
msg.getMessageElement(MESSAGE_MODE, MESSAGE_MODE);
if(modeMsgElement != null) {
mode = modeMsgElement.toString();
}
MessageElement idMsgElement =
msg.getMessageElement(MESSAGE_ID, MESSAGE_ID);
if(idMsgElement != null) {
id = idMsgElement.toString();
}
//added for bulk messages
MessageElement bulkModeMsgElement =
msg.getMessageElement(BULK_MESSAGE_MODE, BULK_MESSAGE_MODE);
if(bulkModeMsgElement != null) {
bulkMode = bulkModeMsgElement.toString();
}
MessageElement bulkIdMsgElement =
msg.getMessageElement(BULK_MESSAGE_ID, BULK_MESSAGE_ID);
if(bulkIdMsgElement != null) {
bulkId = bulkIdMsgElement.toString();
}
//end added for bulk messages
MessageElement appidMsgElement =
msg.getMessageElement(MESSAGE_APPID, MESSAGE_APPID);
if(appidMsgElement != null) {
appid = appidMsgElement.toString();
}
MessageElement versionMsgElement =
msg.getMessageElement(MESSAGE_VERSION, MESSAGE_VERSION);
if(versionMsgElement != null) {
version =
(Long.decode(versionMsgElement.toString())).longValue();
}
MessageElement commandMsgElement =
msg.getMessageElement(MESSAGE_COMMAND, MESSAGE_COMMAND);
String command = commandMsgElement.toString();
MessageElement lastAccessMsgElement =
msg.getMessageElement(MESSAGE_LAST_ACCESS, MESSAGE_LAST_ACCESS);
if(lastAccessMsgElement != null) {
lastAccess =
(Long.decode(lastAccessMsgElement.toString())).longValue();
}
MessageElement maxInactiveMsgElement =
msg.getMessageElement(MESSAGE_MAX_INACTIVE, MESSAGE_MAX_INACTIVE);
if(maxInactiveMsgElement != null) {
maxInactive =
(Long.decode(maxInactiveMsgElement.toString())).longValue();
}
MessageElement instanceNameMsgElement =
msg.getMessageElement(MESSAGE_INSTANCE_NAME, MESSAGE_INSTANCE_NAME);
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState>>createReplicationState:instanceNameMsgElement: " + instanceNameMsgElement);
}
if(instanceNameMsgElement != null) {
instanceName = instanceNameMsgElement.toString();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState>>createReplicationState:instanceNameString: " + instanceName);
}
}
MessageElement extraParamMsgElement =
msg.getMessageElement(MESSAGE_EXTRA_PARAM, MESSAGE_EXTRA_PARAM);
if(extraParamMsgElement != null) {
extraParam = extraParamMsgElement.toString();
}
//FIXME assuming queryResult is a string encoding an Integer
MessageElement queryResultMsgElement =
msg.getMessageElement(MESSAGE_QUERY_RESULT, MESSAGE_QUERY_RESULT);
if(queryResultMsgElement != null) {
queryResult =
Integer.decode(maxInactiveMsgElement.toString());
}
MessageElement dataMsgElement =
msg.getMessageElement(MESSAGE_DATA, MESSAGE_DATA);
if(dataMsgElement != null) {
data = dataMsgElement.getBytes(false);
}
MessageElement trunkDataMsgElement =
msg.getMessageElement(MESSAGE_TRUNK_DATA, MESSAGE_TRUNK_DATA);
if(trunkDataMsgElement != null) {
trunkData = trunkDataMsgElement.getBytes(false);
}
MessageElement containerExtraParamsDataMsgElement =
msg.getMessageElement(MESSAGE_CONTAINER_EXTRA_PARAMS_DATA, MESSAGE_CONTAINER_EXTRA_PARAMS_DATA);
if(containerExtraParamsDataMsgElement != null) {
containerExtraParamsData = containerExtraParamsDataMsgElement.getBytes(false);
}
MessageElement propertiesMsgElement =
msg.getMessageElement(MESSAGE_PROPERTIES_DATA, MESSAGE_PROPERTIES_DATA);
if(propertiesMsgElement != null) {
propertiesState = propertiesMsgElement.getBytes(false);
if(propertiesState != null) {
try {
properties = (HashMap)getObjectValue(propertiesState);
} catch (Exception ex) {
;
}
}
}
//added for bulk message support
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState>>createReplicationState:bulkId = " + bulkId + " id = " + id +
" bulkMode = " + bulkMode + " mode = " + mode);
}
if(bulkId != null && bulkMode != null) {
id = bulkId;
mode = bulkMode;
}
//end added for bulk message support
ReplicationState state =
new ReplicationState(mode, id, appid, version, lastAccess, maxInactive, extraParam, queryResult, instanceName, command, data, trunkData, containerExtraParamsData);
if(properties != null) {
state.setProperties(properties);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState>>createReplicationState:creating ReplicationState: " + state);
}
return state;
}
/**
* create a broadcast query ReplicationState from the input
* @param mode
* @param id
* @param appid
* @param instanceName
*/
public static ReplicationState createBroadcastQueryState(String mode, String id, String appid, String instanceName) {
//if version is not specified it will be created as -1L
//and MESSAGE_BROADCAST_QUERY for backward compatibility
return createBroadcastQueryState(mode, id, appid, -1L, instanceName, MESSAGE_BROADCAST_QUERY);
}
/**
* create a broadcast query ReplicationState from the input
* @param mode
* @param id
* @param appid
* @param version
* @param instanceName
*/
public static ReplicationState createBroadcastQueryState(String mode, String id, String appid, long version, String instanceName, String command) {
return new ReplicationState(mode, id, appid, version, 0L, 0L, null, null, instanceName, command, null, null, null);
}
/**
* create a broadcast query ReplicationState from the input
* @param mode
* @param id
* @param appid
* @param version
* @param instanceName
*/
public static ReplicationState createBroadcastLoadReceivedState(String mode, String id, String appid, long version, String instanceName) {
return new ReplicationState(mode, id, appid, version, 0L, 0L, null, null, instanceName, MESSAGE_BROADCAST_LOAD_RECEIVED, null, null, null);
}
/**
* create a broadcast query ReplicationState from the input
* @param mode
* @param id
* @param appid
* @param version
* @param instanceName
* @param command
*/
public static ReplicationState createBroadcastLoadReceivedState(String mode, String id, String appid, long version, String instanceName, String command) {
String replicateToInstanceName = getImmediateReplicateToInstanceName();
ReplicationState result = new ReplicationState(mode, id, appid, version, 0L, 0L, null, null, instanceName, command, null, null, null);
result.setProperty(IMMEDIATE_REPLICA_PARTNER, replicateToInstanceName);
return result;
}
private static String getImmediateReplicateToInstanceName() {
ReplicationUtil util = ReplicationUtil.createReplicationUtil();
if(util.isInstanceLoadBalancedByCLB()) {
return null; //FIXME
} else {
ReplicationHealthChecker healthChecker
= ReplicationHealthChecker.getInstance();
return healthChecker.getReshapeReplicateToInstanceName(null, 0L);
}
}
/**
* create a broadcast aquery ReplicationState from the input
* @param mode
* @param id
* @param appid
* @param version
* @param instanceName
*/
public static ReplicationState createBroadcastPurgeState(String mode, String id, String appid, long version, String owningInstanceName, String instanceName) {
//using extraParam slot for owningInstanceName for only this method
return new ReplicationState(mode, id, appid, version, 0L, 0L, owningInstanceName, null, instanceName, MESSAGE_BROADCAST_PURGE_ADVISORY, null, null, null);
}
/**
* create a broadcast aquery ReplicationState from the input
* @param mode
* @param id
* @param appid
* @param version
* @param instanceName
*/
public static ReplicationState createBroadcastNetworkPartitionAdvisoryState(String mode, String id, String appid, long version, String owningInstanceName, String instanceName) {
//using extraParam slot for owningInstanceName for only this method
return new ReplicationState(mode, id, appid, version, 0L, 0L, owningInstanceName, null, instanceName, MESSAGE_BROADCAST_NETWORK_PARTITION_ADVISORY, null, null, null);
}
/**
* create a broadcast query ReplicationState from the input
* @param mode
* @param id
* @param appid
* @param version
* @param instanceName
* @param command
*/
public static ReplicationState createUnicastLoadAdvisoryState(String mode, String id, String appid, long version, String instanceName, String command) {
return new ReplicationState(mode, id, appid, version, 0L, 0L, null, null, instanceName, command, null, null, null);
}
/**
* create a unicast query ReplicationState from the input
* @param mode
* @param id
* @param appid
* @param version
* @param instanceName
* @param command
*/
public static ReplicationState createUnicastLoadState(String mode, String id, String appid, long version, String instanceName, String command) {
return new ReplicationState(mode, id, appid, version, 0L, 0L, null, null, instanceName, command, null, null, null);
}
/**
* create a query ReplicationState from the input
* @param mode
* @param id
* @param appid
* @param command
*/
public static ReplicationState createQueryState(String mode, String id, String appid, String command) {
return new ReplicationState(mode, id, appid, 0L, 0L, 0L, null, null, lookupInstanceName(), command, null, null, null);
}
/**
* create a query ReplicationState from the input
* @param mode
* @param id
* @param appid
* @param queryResult
*/
public static ReplicationState createQueryStateResponse(String mode, String id, String appid, String sourceInstanceName, Object queryResult) {
return new ReplicationState(mode, id, appid, 0L, 0L, 0L, null, queryResult, sourceInstanceName, RETURN_MSG_COMMAND, null, null, null);
}
/**
* create a broadcast ReplicationState from the input Message
* @param msg
*/
public static ReplicationState createBroadcastReplicationState(Message msg) {
//FIXME all messages should have a non-null mode check all
// message creating code later
String mode = MODE_WEB;
long version = 0L;
String extraParam = null;
String queryResult = null;
String instanceName = null;
byte[] propertiesState = null;
HashMap properties = null;
boolean isNack = false;
MessageElement modeMsgElement =
msg.getMessageElement(MESSAGE_MODE, MESSAGE_MODE);
if(modeMsgElement != null) {
mode = modeMsgElement.toString();
}
MessageElement idMsgElement =
msg.getMessageElement(MESSAGE_ID, MESSAGE_ID);
String id = idMsgElement.toString();
MessageElement appidMsgElement =
msg.getMessageElement(MESSAGE_APPID, MESSAGE_APPID);
String appid = appidMsgElement.toString();
MessageElement versionMsgElement =
msg.getMessageElement(MESSAGE_VERSION, MESSAGE_VERSION);
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState:createBroadcastReplicationState:versMsgElem=" + versionMsgElement);
}
if(versionMsgElement != null) {
version =
(Long.decode(versionMsgElement.toString())).longValue();
}
MessageElement extraParamMsgElement =
msg.getMessageElement(MESSAGE_EXTRA_PARAM, MESSAGE_EXTRA_PARAM);
if(extraParamMsgElement != null) {
extraParam = extraParamMsgElement.toString();
}
MessageElement queryResultMsgElement =
msg.getMessageElement(MESSAGE_QUERY_RESULT, MESSAGE_QUERY_RESULT);
if(queryResultMsgElement != null) {
queryResult = queryResultMsgElement.toString();
}
MessageElement commandMsgElement =
msg.getMessageElement(MESSAGE_COMMAND, MESSAGE_COMMAND);
String command = commandMsgElement.toString();
MessageElement instanceNameMsgElement =
msg.getMessageElement(MESSAGE_INSTANCE_NAME, MESSAGE_INSTANCE_NAME);
if(instanceNameMsgElement != null) {
instanceName = instanceNameMsgElement.toString();
}
MessageElement nackMsgElement =
msg.getMessageElement(MESSAGE_IS_NACK, MESSAGE_IS_NACK);
if(nackMsgElement != null) {
String isNackString = nackMsgElement.toString();
if("Y".equalsIgnoreCase(isNackString)) {
isNack = true;
}
}
/* don't need these message element - remove after testing
//FIXME will need to add more later
MessageElement lastAccessMsgElement =
msg.getMessageElement(MESSAGE_LAST_ACCESS, MESSAGE_LAST_ACCESS);
long lastAccess =
(Long.decode(lastAccessMsgElement.toString())).longValue();
MessageElement maxInactiveMsgElement =
msg.getMessageElement(MESSAGE_MAX_INACTIVE, MESSAGE_MAX_INACTIVE);
long maxInactive =
(Long.decode(maxInactiveMsgElement.toString())).longValue();
MessageElement instanceNameMsgElement =
msg.getMessageElement(MESSAGE_INSTANCE_NAME, MESSAGE_INSTANCE_NAME);
String instanceName = instanceNameMsgElement.toString();
MessageElement extraParamMsgElement =
msg.getMessageElement(MESSAGE_EXTRA_PARAM, MESSAGE_EXTRA_PARAM);
String extraParam = extraParamMsgElement.toString();
*/
byte[] data = null;
MessageElement dataMsgElement =
msg.getMessageElement(MESSAGE_DATA, MESSAGE_DATA);
if(dataMsgElement != null) {
data = dataMsgElement.getBytes(false);
}
byte[] trunkData = null;
MessageElement trunkDataMsgElement =
msg.getMessageElement(MESSAGE_TRUNK_DATA, MESSAGE_TRUNK_DATA);
if(trunkDataMsgElement != null) {
trunkData = trunkDataMsgElement.getBytes(false);
}
byte[] containerExtraParamsData = null;
MessageElement containerExtraParamsMsgElement =
msg.getMessageElement(MESSAGE_CONTAINER_EXTRA_PARAMS_DATA, MESSAGE_CONTAINER_EXTRA_PARAMS_DATA);
if(containerExtraParamsMsgElement != null) {
containerExtraParamsData = containerExtraParamsMsgElement.getBytes(false);
}
MessageElement propertiesMsgElement =
msg.getMessageElement(MESSAGE_PROPERTIES_DATA, MESSAGE_PROPERTIES_DATA);
if(propertiesMsgElement != null) {
propertiesState = propertiesMsgElement.getBytes(false);
if(propertiesState != null) {
try {
properties = (HashMap)getObjectValue(propertiesState);
} catch (Exception ex) {
;
}
}
}
ReplicationState state =
new ReplicationState(mode, id, appid, version, 0L, 0L, extraParam, queryResult, instanceName, command, data, trunkData, containerExtraParamsData);
if(properties != null) {
state.setProperties(properties);
}
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState:createBroadcastReplicationState:creating ReplicationState from broadcast: " + state);
}
//set if response is nack
state.setNack(isNack);
return state;
}
/**
* create a Message from the input state
* @param state
*/
public static Message createMessage(ReplicationState state) {
return createMessage(state, false);
}
/**
* create a Message from the input state
* @param state
* @param isResponse is the created message a response
*/
public static Message createMessage(ReplicationState state, boolean isResponse) {
Message msg = new Message();
String mode = state.getMode();
String id = (String)state.getId();
String appid = state.getAppId();
String command = state.getCommand();
Long version = new Long(state.getVersion());
Long lastAccess = new Long(state.getLastAccess());
Long maxInactive = new Long(state.getMaxInactiveInterval());
String extraParam = state.getExtraParam();
//FIXME for now assuming this is a Long
//for generality will have to serialize and use bytearray
Integer queryResult = (Integer)state.getQueryResult();
String instanceName = state.getInstanceName();
if(instanceName == null) {
//put existing instanceName for source if it is missing here
instanceName = lookupInstanceName();
}
byte[] data = state.getState();
byte[] trunkData = state.getTrunkState();
byte[] containerExtraParamData = state.getContainerExtraParamsState();
boolean ackRequired = state.isAckRequired();
HashMap properties = (HashMap)state.getProperties();
byte[] propertiesState = null;
try {
propertiesState = ReplicationUtil.getByteArray(properties);
} catch (Exception ex) {}
long sendStartTime = state.getSendStartTime();
//String data = "Message #" + i;
msg.addMessageElement(MESSAGE_MODE,
new StringMessageElement(MESSAGE_MODE,
mode,
null));
if(mode != null && mode.equalsIgnoreCase(BULK_MESSAGE_MODE)) {
msg.addMessageElement(BULK_MESSAGE_MODE,
new StringMessageElement(BULK_MESSAGE_MODE,
"BULK",
null));
}
msg.addMessageElement(MESSAGE_ID,
new StringMessageElement(MESSAGE_ID,
id,
null));
msg.addMessageElement(MESSAGE_ID,
new StringMessageElement(MESSAGE_ID,
id,
null));
msg.addMessageElement(MESSAGE_APPID,
new StringMessageElement(MESSAGE_APPID,
appid,
null));
msg.addMessageElement(MESSAGE_VERSION,
new StringMessageElement(MESSAGE_VERSION,
version.toString(),
null));
String theCommand = command;
if(isResponse) {
theCommand = RETURN_MSG_COMMAND;
}
msg.addMessageElement(MESSAGE_COMMAND,
new StringMessageElement(MESSAGE_COMMAND,
theCommand,
null));
msg.addMessageElement(MESSAGE_LAST_ACCESS,
new StringMessageElement(MESSAGE_LAST_ACCESS,
lastAccess.toString(),
null));
msg.addMessageElement(MESSAGE_MAX_INACTIVE,
new StringMessageElement(MESSAGE_MAX_INACTIVE,
maxInactive.toString(),
null));
if(extraParam != null) {
msg.addMessageElement(MESSAGE_EXTRA_PARAM,
new StringMessageElement(MESSAGE_EXTRA_PARAM,
extraParam,
null));
}
if(queryResult != null) {
msg.addMessageElement(MESSAGE_QUERY_RESULT,
new StringMessageElement(MESSAGE_QUERY_RESULT,
queryResult.toString(),
null));
}
if(instanceName != null) {
msg.addMessageElement(MESSAGE_INSTANCE_NAME,
new StringMessageElement(MESSAGE_INSTANCE_NAME,
instanceName,
null));
}
if(data != null) {
msg.addMessageElement(MESSAGE_DATA,
new ByteArrayMessageElement(MESSAGE_DATA,
null,
data,
null));
}
if(trunkData != null) {
msg.addMessageElement(MESSAGE_TRUNK_DATA,
new ByteArrayMessageElement(MESSAGE_TRUNK_DATA,
null,
trunkData,
null));
}
if(containerExtraParamData != null) {
msg.addMessageElement(MESSAGE_CONTAINER_EXTRA_PARAMS_DATA,
new ByteArrayMessageElement(MESSAGE_CONTAINER_EXTRA_PARAMS_DATA,
null,
containerExtraParamData,
null));
}
if(propertiesState != null) {
msg.addMessageElement(MESSAGE_PROPERTIES_DATA,
new ByteArrayMessageElement(MESSAGE_PROPERTIES_DATA,
null,
propertiesState,
null));
}
//is ack required
String ackRequiredString = "N";
if(ackRequired) {
ackRequiredString = "Y";
}
msg.addMessageElement(MESSAGE_ACK_REQUIRED,
new StringMessageElement(MESSAGE_ACK_REQUIRED,
ackRequiredString,
null));
//a property not sent but available for quick-ack case
msg.setMessageProperty(MESSAGE_ACK_REQUIRED, ackRequiredString);
List ackIdsList = state.getAckIdsList();
if(state.getAckIdsList() != null) {
msg.setMessageProperty(MESSAGE_ACK_LIST_PROPERTY, ackIdsList);
}
//send start time for measurements
if(sendStartTime != -1) {
msg.addMessageElement(MESSAGE_SEND_START_TIME,
new StringMessageElement(MESSAGE_SEND_START_TIME,
"" + sendStartTime,
null));
msg.setMessageProperty(MESSAGE_SEND_START_TIME, ""+sendStartTime);
}
msg.addMessageElement(MESSAGE_BIDI_STYLE,
new StringMessageElement(MESSAGE_BIDI_STYLE,
"" + state.isBiDiStyle(),
null));
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState:createMessage:Sending Message id:" + id + " appid:" + appid + " command:" + command);
}
return msg;
}
/**
* create a Message from the input state
* @param msgID
* @param totalStates the number of total states
* @param data the serialized list of ReplicationStates
* this version creates a message with no ack required
*/
public static Message createBulkMessage(long msgID, int totalStates, byte[] data) {
return createBulkMessage(msgID, totalStates, data, false);
}
/**
* create a Message from the input state
* @param msgID
* @param totalStates the number of total states
* @param data the serialized list of ReplicationStates
* @param ackRequired does this message require an ack
*/
public static Message createBulkMessage(long msgID, int totalStates, byte[] data, boolean ackRequired) {
Message msg = new Message();
msg.addMessageElement(BULK_MESSAGE_MODE,
new StringMessageElement(BULK_MESSAGE_MODE,
"BULK",
null));
msg.addMessageElement(BULK_MESSAGE_ID,
new StringMessageElement(BULK_MESSAGE_ID,
""+msgID,
null));
msg.setMessageProperty(BULK_MESSAGE_ID, ""+msgID);
if (data != null) {
msg.addMessageElement(MESSAGE_TOTAL_STATES,
new StringMessageElement(MESSAGE_TOTAL_STATES,
""+totalStates,
null));
msg.addMessageElement(MESSAGE_DATA,
new ByteArrayMessageElement(MESSAGE_DATA,
null,
data,
null));
}
//is ack required
String ackRequiredString = "N";
if(ackRequired) {
ackRequiredString = "Y";
}
msg.addMessageElement(MESSAGE_ACK_REQUIRED,
new StringMessageElement(MESSAGE_ACK_REQUIRED,
ackRequiredString,
null));
//send start time for measurements
long sendStartTime = System.currentTimeMillis();
msg.addMessageElement(MESSAGE_SEND_START_TIME,
new StringMessageElement(MESSAGE_SEND_START_TIME,
"" + sendStartTime,
null));
msg.setMessageProperty(MESSAGE_SEND_START_TIME, ""+sendStartTime);
if(_logger.isLoggable(Level.INFO)) {
_logger.info("ReplicationState:createBulkMessage:Sending BULK_Message id:" + msgID +
" size: " + data.length + " startTime=" + sendStartTime);
}
return msg;
}
/**
* create a Message from the input state
* @param msgID
* @param totalStates the number of total states
* @param data the serialized list of ReplicationStates
* @param ackRequired does this message require an ack
*/
public static ReplicationState createBulkReplicationState(long msgID, List<String> ackIdsList, byte[] data, boolean ackRequired) {
String id = "" + msgID;
ReplicationState resultState =
new ReplicationState(BULK_MESSAGE_MODE, //bulk mode
id, //id
id, //appid (does not matter in this bulk case; must be non null)
-1, //version
0L, //lastaccesstime
0L, //maxInactiveInterval (seconds)
null, // (extraParam)
null, //queryResult not used here
null, //instanceName
VALVE_SAVE_COMMAND, //command (does not matter in this bulk case; must be non-null)
data, //state
null, //trunkState
null); //containerExtraParamState
resultState.setAckRequired(ackRequired);
resultState.setAckIdsList(ackIdsList);
return resultState;
}
/**
* create an ack Message from the input
* @param msg
*/
public static Message createAckMessageFrom(Message msg) {
Message ackMsg = new Message();
//echo the mode
String mode = MODE_WEB;
MessageElement modeMsgElement =
msg.getMessageElement(MESSAGE_MODE, MESSAGE_MODE);
if(modeMsgElement != null) {
mode = modeMsgElement.toString();
}
ackMsg.addMessageElement(MESSAGE_MODE,
new StringMessageElement(MESSAGE_MODE,
mode,
null));
//echo the id
MessageElement idMsgElement =
msg.getMessageElement(MESSAGE_ID, MESSAGE_ID);
String id = idMsgElement.toString();
ackMsg.addMessageElement(MESSAGE_ID,
new StringMessageElement(MESSAGE_ID,
id,
null));
//echo the appid
MessageElement appidMsgElement =
msg.getMessageElement(MESSAGE_APPID, MESSAGE_APPID);
String appid = appidMsgElement.toString();
ackMsg.addMessageElement(MESSAGE_APPID,
new StringMessageElement(MESSAGE_APPID,
appid,
null));
//********** test begin**********************
//get the current command
MessageElement commandMsgElement =
msg.getMessageElement(MESSAGE_COMMAND, MESSAGE_COMMAND);
String previousCommand = commandMsgElement.toString();
String theCommand = RETURN_MSG_COMMAND;
if(previousCommand.equals(ReplicationState.HC_COMMAND)) {
theCommand = RETURN_HC_MSG_COMMAND;
}
//this is a return command
/* FIXME replace next line with above - need to test
String theCommand = RETURN_MSG_COMMAND;
*/
//********** test end **********************
ackMsg.addMessageElement(MESSAGE_COMMAND,
new StringMessageElement(MESSAGE_COMMAND,
theCommand,
null));
return ackMsg;
}
/**
* create an bulk ack Message from the input
* @param msg
*/
public static Message createBulkAckMessageFrom(Message msg, List<ReplicationState> states) {
List<String> ackIdsList = extractAckIdsList(states);
//displayStringList(ackIdsList);
byte[] listAckIds = null;
try {
listAckIds = getByteArray(ackIdsList);
} catch (IOException ex) {
//deliberate no-op
;
}
Message ackMsg = new Message();
//echo the mode
String mode = MODE_WEB;
MessageElement modeMsgElement =
msg.getMessageElement(MESSAGE_MODE, MESSAGE_MODE);
if(modeMsgElement != null) {
mode = modeMsgElement.toString();
}
ackMsg.addMessageElement(MESSAGE_MODE,
new StringMessageElement(MESSAGE_MODE,
mode,
null));
ackMsg.addMessageElement(BULK_MESSAGE_MODE,
new StringMessageElement(BULK_MESSAGE_MODE,
"BULK",
null));
//echo the id
MessageElement idMsgElement =
msg.getMessageElement(MESSAGE_ID, MESSAGE_ID);
String id = idMsgElement.toString();
ackMsg.addMessageElement(MESSAGE_ID,
new StringMessageElement(MESSAGE_ID,
id,
null));
//echo the appid
MessageElement appidMsgElement =
msg.getMessageElement(MESSAGE_APPID, MESSAGE_APPID);
String appid = appidMsgElement.toString();
ackMsg.addMessageElement(MESSAGE_APPID,
new StringMessageElement(MESSAGE_APPID,
appid,
null));
//********** test begin**********************
//get the current command
MessageElement commandMsgElement =
msg.getMessageElement(MESSAGE_COMMAND, MESSAGE_COMMAND);
String previousCommand = commandMsgElement.toString();
String theCommand = RETURN_MSG_COMMAND;
if(previousCommand.equals(ReplicationState.HC_COMMAND)) {
theCommand = RETURN_HC_MSG_COMMAND;
}
//this is a return command
/* FIXME replace next line with above - need to test
String theCommand = RETURN_MSG_COMMAND;
*/
//********** test end **********************
ackMsg.addMessageElement(MESSAGE_COMMAND,
new StringMessageElement(MESSAGE_COMMAND,
theCommand,
null));
//serialized list of ids to ack back to
if(listAckIds != null) {
ackMsg.addMessageElement(MESSAGE_ACK_IDS_LIST,
new ByteArrayMessageElement(MESSAGE_ACK_IDS_LIST,
null,
listAckIds,
null));
}
return ackMsg;
}
public static void displayStringList(List<String> stringList) {
for(int i=0; i<stringList.size(); i++) {
_logger.log(Level.INFO, "displayStringList:elem[" + i + "] = " + stringList.get(i));
}
}
public static List<String> extractAckIdsList(List<ReplicationState> states) {
List<String> ackIdsList = new ArrayList();
for(int i=0; i<states.size(); i++) {
ReplicationState nextState = states.get(i);
//only add ids to ackIdsList that require an ack
if(nextState != null && nextState.isAckRequired()) {
ackIdsList.add((String)nextState.getId());
}
}
return ackIdsList;
}
public static List<String> extractAllIdsList(List<ReplicationState> states) {
List<String> allIdsList = new ArrayList();
for(int i=0; i<states.size(); i++) {
ReplicationState nextState = states.get(i);
//provide the id[vers:xxx] for all states in list
if(nextState != null) {
allIdsList.add("Operation: " + nextState.getCommand() +
" AppId:" + nextState.getAppId() +
" Id:" + nextState.getId() +
"[ver:" + nextState.getVersion() + "]");
}
}
return allIdsList;
}
static List<String> extractAckIdsListFromMessage(Message msg) {
List<String> result = new ArrayList();
byte[] data = null;
MessageElement ackIdsMsgElement =
msg.getMessageElement(MESSAGE_ACK_IDS_LIST, MESSAGE_ACK_IDS_LIST);
if(ackIdsMsgElement != null) {
data = ackIdsMsgElement.getBytes(false);
}
try {
result = (ArrayList)getObjectValue(data);
} catch (Exception ex) {
//deliberate no-op
;
}
return result;
}
/**
* true means this is a broadcast message
*/
public static boolean isBroadcastState(ReplicationState state) {
return (state.getCommand() != null
&& state.getCommand().equals(MESSAGE_BROADCAST_QUERY));
}
/**
* true means void return
*/
public boolean isVoidMethodReturnState() {
String methodName = this.getCommand();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState>>isVoidMethodReturnState:methodName = " + methodName);
}
if(methodName == null) {
return false;
} else {
return isMethodVoidReturn(methodName);
}
}
/**
* true means void return command (i.e. method)
*/
static boolean isMethodVoidReturn(String methodName) {
return voidReturnsMethods.contains(methodName);
}
/**
* true means void return command (i.e. method)
*/
public static boolean isVoidMethodReturnMessage(Message msg) {
MessageElement commandMsgElement =
msg.getMessageElement(MESSAGE_COMMAND, MESSAGE_COMMAND);
String methodName = commandMsgElement.toString();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState>>isVoidMethodReturnMessage:methodName = " + methodName);
}
if(methodName == null) {
return false;
} else {
return isMethodVoidReturn(methodName);
}
}
/**
* true means state command is one of remove methods
*/
public boolean isRemoveMethodState() {
String methodName = this.getCommand();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState>>isRemoveMethodState:methodName = " + methodName);
}
if(methodName == null) {
return false;
} else {
return isMethodRemove(methodName);
}
}
/**
* true means one of remove commands (i.e. method)
*/
static boolean isMethodRemove(String methodName) {
return removeMethods.contains(methodName);
}
///
/**
* true means void return command (i.e. method)
*/
static boolean isMethodHC(String methodName) {
return hcMethods.contains(methodName);
}
/**
* true means void return command (i.e. method)
*/
public static boolean isHCMessage(Message msg) {
MessageElement commandMsgElement =
msg.getMessageElement(MESSAGE_COMMAND, MESSAGE_COMMAND);
String methodName = commandMsgElement.toString();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState>>isHCMessage:methodName = " + methodName);
}
if(methodName == null) {
return false;
} else {
return isMethodHC(methodName);
}
}
/**
* get extra param from message
*/
public static String getExtraParamFromMessage(Message msg) {
String result = "";
MessageElement extraParamMsgElement =
msg.getMessageElement(MESSAGE_EXTRA_PARAM, MESSAGE_EXTRA_PARAM);
if(extraParamMsgElement != null) {
result = extraParamMsgElement.toString();
}
return result;
}
///
/**
* @param msg
* true means a response message
*/
public static boolean isResponseMessage(Message msg) {
MessageElement commandMsgElement =
msg.getMessageElement(MESSAGE_COMMAND, MESSAGE_COMMAND);
String methodName = commandMsgElement.toString();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState>>isResponseMessage:methodName = " + methodName);
}
if(methodName == null) {
return false;
} else {
return isMethodResponse(methodName);
}
}
/**
* true means ack is required
*/
public static boolean isAckRequiredForMessage(Message msg) {
String ackRequiredString = "N";
MessageElement ackRequiredMsgElement =
msg.getMessageElement(MESSAGE_ACK_REQUIRED, MESSAGE_ACK_REQUIRED);
if(ackRequiredMsgElement != null) {
ackRequiredString = ackRequiredMsgElement.toString();
}
return("Y".equalsIgnoreCase(ackRequiredString));
}
/**
* true means a response
*/
public boolean isResponseState() {
String methodName = this.getCommand();
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState>>isResponseState:methodName = " + methodName);
}
if(methodName == null) {
return false;
} else {
return isMethodResponse(methodName);
}
}
/**
* true means void return command (i.e. method)
*/
static boolean isMethodResponse(String methodName) {
return responseMethods.contains(methodName);
}
private static String lookupInstanceName() {
return ReplicationUtil.getInstanceName();
}
/**
* create a new Message based on the input
* this is for a from msg
* @param state
* @param isResponse
*/
public static Message createBroadcastMessage(ReplicationState state, boolean isResponse) {
String instanceName = ReplicationUtil.getInstanceName();
return ReplicationState.createBroadcastMessage(state, isResponse, instanceName);
}
/**
* create a new Message based on the input
* this is for a return msg to the target instance
* @param state
* @param isResponse
* @param instName
*/
public static Message createBroadcastMessage(ReplicationState state, boolean isResponse, String instName) {
String instanceName = ReplicationUtil.getInstanceName();
//String instanceName = instName;
Message msg = new Message();
String mode = state.getMode();
String id = (String)state.getId();
String appid = state.getAppId();
String versionString = Long.toString(state.getVersion());
Long lastAccess = new Long(state.getLastAccess());
Long maxInactive = new Long(state.getMaxInactiveInterval());
String extraParam = state.getExtraParam();
String queryResult = (String)state.getQueryResult();
String theCommand = state.getCommand();
//String theCommand = MESSAGE_BROADCAST_QUERY;
byte[] data = state.getState();
byte[] trunkData = state.getTrunkState();
byte[] containerExtraParamData = state.getContainerExtraParamsState();
HashMap properties = (HashMap)state.getProperties();
byte[] propertiesState = null;
try {
propertiesState = ReplicationUtil.getByteArray(properties);
} catch (Exception ex) {}
/*
if(isResponse) {
theCommand = RETURN_BROADCAST_MSG_COMMAND;
}
*/
//is nack message
boolean isNack = state._isNack;
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState>>createBroadcastMessage:instanceName=" + instanceName + " theCommand=" + theCommand);
}
msg.addMessageElement(MESSAGE_MODE,
new StringMessageElement(MESSAGE_MODE,
mode,
null));
if(mode != null && mode.equalsIgnoreCase(BULK_MESSAGE_MODE)) {
msg.addMessageElement(BULK_MESSAGE_MODE,
new StringMessageElement(BULK_MESSAGE_MODE,
"BULK",
null));
}
msg.addMessageElement(MESSAGE_ID,
new StringMessageElement(MESSAGE_ID,
id,
null));
msg.addMessageElement(MESSAGE_APPID,
new StringMessageElement(MESSAGE_APPID,
appid,
null));
msg.addMessageElement(MESSAGE_VERSION,
new StringMessageElement(MESSAGE_VERSION,
versionString,
null));
if(extraParam != null) {
msg.addMessageElement(MESSAGE_EXTRA_PARAM,
new StringMessageElement(MESSAGE_EXTRA_PARAM,
extraParam,
null));
}
if(queryResult != null) {
msg.addMessageElement(MESSAGE_QUERY_RESULT,
new StringMessageElement(MESSAGE_QUERY_RESULT,
queryResult,
null));
}
msg.addMessageElement(MESSAGE_COMMAND,
new StringMessageElement(MESSAGE_COMMAND,
theCommand,
null));
msg.addMessageElement(MESSAGE_LAST_ACCESS,
new StringMessageElement(MESSAGE_LAST_ACCESS,
lastAccess.toString(),
null));
msg.addMessageElement(MESSAGE_MAX_INACTIVE,
new StringMessageElement(MESSAGE_MAX_INACTIVE,
maxInactive.toString(),
null));
msg.addMessageElement(InstanceNameMessage,
new StringMessageElement(InstanceNameMessage,
instanceName,
null));
msg.addMessageElement(MESSAGE_INSTANCE_NAME,
new StringMessageElement(MESSAGE_INSTANCE_NAME,
instanceName,
null));
//is nack message
String isNackString = "N";
if(isNack) {
isNackString = "Y";
}
msg.addMessageElement(MESSAGE_IS_NACK,
new StringMessageElement(MESSAGE_IS_NACK,
isNackString,
null));
if(data != null) {
msg.addMessageElement(MESSAGE_DATA,
new ByteArrayMessageElement(MESSAGE_DATA,
null,
data,
null));
}
if(trunkData != null) {
msg.addMessageElement(MESSAGE_TRUNK_DATA,
new ByteArrayMessageElement(MESSAGE_TRUNK_DATA,
null,
trunkData,
null));
}
if(containerExtraParamData != null) {
msg.addMessageElement(MESSAGE_CONTAINER_EXTRA_PARAMS_DATA,
new ByteArrayMessageElement(MESSAGE_CONTAINER_EXTRA_PARAMS_DATA,
null,
containerExtraParamData,
null));
}
if(propertiesState != null) {
msg.addMessageElement(MESSAGE_PROPERTIES_DATA,
new ByteArrayMessageElement(MESSAGE_PROPERTIES_DATA,
null,
propertiesState,
null));
}
msg.addMessageElement(ORIGINATING_INSTANCE_NAME,
new StringMessageElement(ORIGINATING_INSTANCE_NAME, ReplicationUtil.getInstanceName(), null));
return msg;
}
// begin Metadata related
/**
* create a new ReplicationState based on the input
* @param mode
* @param id
* @param appid
* @param metaData can be SimpleMetadata
*/
public static ReplicationState createReplicationState(String mode, String id, String appid, Metadata metadata) {
ReplicationState state = null;
state = createReplicationStateFromSimpleMetadata(mode, id, appid, (SimpleMetadata) metadata);
return state;
}
/**
* create a new ReplicationState based on the input
* @param mode
* @param id
* @param appid
* @param simpleMetadata
*/
public static ReplicationState createReplicationStateFromSimpleMetadata(String mode, String id, String appid, SimpleMetadata simpleMetadata)
{
Object extraParams
= simpleMetadata.getExtraParam();
byte[] extraParamState = null;
if(extraParams != null) {
try {
extraParamState
= getByteArray(extraParams);
} catch (IOException ex) {
; //deliberate no-op
}
}
ReplicationState state =
new ReplicationState(mode, //mode
id, //id
appid, //appid
simpleMetadata.getVersion(), //version
simpleMetadata.getLastAccessTime(), //lastAccess
simpleMetadata.getMaxInactiveInterval(), //maxInactive,
null, //extraParam
null, //queryResult
null, //instanceName
null, //command FIXME
simpleMetadata.getState(), //data
null, //trunkState
extraParamState); //extraParamState
if(_logger.isLoggable(Level.FINE)) {
_logger.fine("ReplicationState>>createReplicationStateFromSimpleMetadata:state = " + state);
}
return state;
}
static String extractExtraParamStringFrom(String mode, Object e) {
if(mode.equals(MODE_SSO)) {
//return (String)e; //reminder for possible use with ejb
if(e == null) {
return null;
} else {
return ((SSOExtraParams)e).username;
}
}
if(mode.equals(MODE_WEB)) {
if(e == null) {
return null;
} else {
return ((HttpSessionExtraParams)e).getSsoId();
}
}
return null;
}
/**
* create a CompositeMetadata representing ReplicationState state
*
* @param state
* The ReplicationState
*
* @return
* A newly created CompositeMetadata object for the given state
*/
public static CompositeMetadata createCompositeMetadataFrom(ReplicationState state) {
if (state == null || state.getState() == null) {
return null;
}
Collection entries = deserializeStatesCollection(state.getState());
CompositeMetadata result
= new CompositeMetadata(
state.getVersion(), //version
state.getLastAccess(), //lastAccess
state.getMaxInactiveInterval(), //maxInactive
entries, //entries
state.getTrunkState(), //trunkState
state.getExtraParam(), //extraParam
state.getContainerExtraParams()); //containerExtraParams
return result;
}
private static Collection deserializeStatesCollectionPrevious(byte[] entriesState) {
Collection result = new ArrayList();
try {
result = (Collection)getObjectValue(entriesState);
} catch (ClassNotFoundException ex1) {
} catch (IOException ex2) {}
return result;
}
private static Collection deserializeStatesCollection(byte[] entriesState) {
Collection result = new ArrayList();
try {
result = (Collection)getAttributeValueCollection(entriesState);
} catch (ClassNotFoundException ex1) {
} catch (IOException ex2) {}
return result;
}
/**
* Given a byte[] containing session data, return a session
* object
*
* @param state
* The byte[] with the session attribute data
*
* @return
* A newly created object for the given session attribute data
*/
public static Object getObjectValue(byte[] state)
throws IOException, ClassNotFoundException
{
return getObjectValue(state, false);
}
/**
* Given a byte[] containing session data, return a session
* object
*
* @param state
* The byte[] with the session attribute data
* @param compress
* should compression be used
*
* @return
* A newly created object for the given session attribute data
*/
public static Object getObjectValue(byte[] state, boolean compress)
throws IOException, ClassNotFoundException
{
Object objectValue = null;
InputStream is = null;
BufferedInputStream bis = null;
ByteArrayInputStream bais = null;
ObjectInputStream ois = null;
try
{
bais = new ByteArrayInputStream(state);
bis = new BufferedInputStream(bais);
if(compress) {
is = new GZIPInputStream(bis);
} else {
is = bis;
}
ois = new ObjectInputStream(is);
if(ois != null) {
try {
objectValue = ois.readObject();
}
finally {
if (ois != null) {
try {
ois.close();
bis = null;
}
catch (IOException e) {
}
}
}
}
}
catch(ClassNotFoundException e)
{
// FIXME evaluate log level
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "Exception occurred in getAttributeValue", e);
}
throw e;
}
catch(IOException e)
{
// FIXME evaluate log level
// if (_logger.isLoggable(Level.FINE)) {
// _logger.fine("Exception occurred in getAttributeValue", e);
// }
throw e;
}
return objectValue;
}
protected static Object getAttributeValueCollection(byte[] state)
throws IOException, ClassNotFoundException
{
Collection attributeValueList = new ArrayList();
BufferedInputStream bis = null;
ByteArrayInputStream bais = null;
ObjectInputStream ois = null;
try
{
bais = new ByteArrayInputStream(state);
bis = new BufferedInputStream(bais);
ois = new ObjectInputStream(bis);
if(ois != null) {
try {
//first get List size
Object whatIsIt = ois.readObject();
int entriesSize = 0;
if(whatIsIt instanceof Integer) {
entriesSize = ((Integer)whatIsIt).intValue();
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.fine("ResplicationState>>getAttributeValueCollection: first obj not integer");
}
}
//int entriesSize = ((Integer) ois.readObject()).intValue();
//if (_logger.isLoggable(Level.FINE)) {
// _logger.fine("entriesSize = " + entriesSize);
//}
//attributeValueList = new ArrayList(entriesSize);
for (int i = 0; i < entriesSize; i++) {
Object nextAttributeValue = ois.readObject();
attributeValueList.add(nextAttributeValue);
}
}
finally {
if (ois != null) {
try {
ois.close();
bis = null;
}
catch (IOException e) {
}
}
}
}
}
catch(ClassNotFoundException e)
{
// FIXME evaluate log level
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "Exception occurred in getAttributeValue", e);
}
throw e;
}
catch(IOException e)
{
// FIXME evaluate log level
// if (_logger.isLoggable(Level.FINE)) {
// _logger.log(Level.FINE, "Exception occurred in getAttributeValue", e);
// }
throw e;
}
return attributeValueList;
}
/**
* Create an byte[] for the object that we can then pass to
* the ReplicationState.
*
* @param obj
* The attribute value we are serializing
*
*/
protected static byte[] getByteArray(Object obj)
throws IOException {
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
byte[] obs;
try {
bos = new ByteArrayOutputStream();
//use normal ObjectOutputStream if there is a failure during stream creation
if(oos == null) {
oos = new ObjectOutputStream(new BufferedOutputStream(bos));
}
oos.writeObject(obj);
oos.close();
oos = null;
obs = bos.toByteArray();
}
finally {
if ( oos != null ) {
oos.close();
}
}
return obs;
}
protected static byte[] getByteArrayFromCollection(Collection entries)
throws IOException {
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
byte[] obs;
try {
bos = new ByteArrayOutputStream();
//use normal ObjectOutputStream if there is a failure during stream creation
if(oos == null) {
oos = new ObjectOutputStream(new BufferedOutputStream(bos));
}
//first write out the entriesSize
int entriesSize = entries.size();
oos.writeObject(Integer.valueOf(entriesSize));
//then write out the entries
Iterator it = entries.iterator();
while(it.hasNext()) {
oos.writeObject(it.next());
}
oos.close();
oos = null;
obs = bos.toByteArray();
}
finally {
if ( oos != null ) {
oos.close();
}
}
if(_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,"size of attributes byte array: " + obs.length);
}
return obs;
}
// end Metadata related
/**
* is this state expired
*/
public boolean isExpired() {
//-1 means no expiration
if(this.getMaxInactiveInterval() == -1) {
return false;
}
return ( (System.currentTimeMillis() - this.getLastAccess())
> (this.getMaxInactiveInterval() * 1000) );
}
/**
* is this message a return message from normal message
* true if command is RETURN_MSG_COMMAND
*/
public boolean isReturnMessage() {
String theCommand = this.getCommand();
if(theCommand == null) {
return false;
} else {
return theCommand.equals(RETURN_MSG_COMMAND);
}
}
/**
* is this message a return message from normal message
* true if command is HC_COMMAND
*/
public boolean isHCMessage() {
String theCommand = this.getCommand();
if(theCommand == null) {
return false;
} else {
return theCommand.equals(HC_COMMAND);
}
}
/**
* is this message a return message from normal message
* true if command is RETURN_HC_MSG_COMMAND
*/
public boolean isHCReturnMessage() {
String theCommand = this.getCommand();
if(theCommand == null) {
return false;
} else {
return theCommand.equals(RETURN_HC_MSG_COMMAND);
}
}
/**
* is this message a return message from a broadcast
* true if command is RETURN_BROADCAST_MSG_COMMAND
*/
public boolean isReturnFromBroadcastMessage() {
String theCommand = this.getCommand();
if(theCommand == null) {
return false;
} else {
return theCommand.equals(RETURN_BROADCAST_MSG_COMMAND);
}
}
/**
* @return mode (e.g. MODE_WEB, MODE_EJB, MODE_SSO)
*/
public String getMode() {
return _mode;
}
/**
* @return _id (key)
*/
public Object getId() {
return _id;
}
/**
*
* @return _appId
*/
public String getAppId() {
return _appId;
}
/**
* @return version
*/
public long getVersion() {
return _version;
}
/**
* @param version the version
*/
public void setVersion(long version) {
_version = version;
}
/**
* @return last access time
*/
public long getLastAccess() {
return _lastAccess;
}
/**
* @param lastAccess last access time
*/
public void setLastAccess(long lastAccess) {
_lastAccess = lastAccess;
}
/**
* @return max inactive interval (seconds)
*/
public long getMaxInactiveInterval() {
return _maxInactiveInterval;
}
/**
* @return _extraParam
*/
public String getExtraParam() {
return _extraParam;
}
/**
* @param extraParam extraParam
*/
public void setExtraParam(String extraParam) {
_extraParam = extraParam;
}
/**
* @return _queryResult
*/
public Object getQueryResult() {
return _queryResult;
}
/**
* @param queryResult queryResult
*/
public void setQueryResult(Object queryResult) {
_queryResult = queryResult;
}
/**
* @return _instanceName
*/
public String getInstanceName() {
return _instanceName;
}
/**
* @return _command
*/
public String getCommand() {
return _command;
}
/**
* @return state
*/
public byte[] getState() {
return _state;
}
/**
* @return trunkState
*/
public byte[] getTrunkState() {
return _trunkState;
}
/**
* @return _containerExtraParamsState
*/
public byte[] getContainerExtraParamsState() {
return _containerExtraParamsState;
}
/**
* @param containerExtraParamsState containerExtraParamsState
*/
public void setContainerExtraParamsState(byte[] containerExtraParamsState) {
_containerExtraParamsState = containerExtraParamsState;
this.setDeserializedExtraParam(null);
}
/**
* Return the Container's ExtraParams (deserialized).
*/
public Object getContainerExtraParams() {
if (_cachedDeserializedExtraParam != null) {
return _cachedDeserializedExtraParam;
} else if (_containerExtraParamsState != null) {
try {
_cachedDeserializedExtraParam = getObjectValue(_containerExtraParamsState);
} catch (Exception ex) {
_logger.warning("unable to deserialize ContainerExtraParams for appid: " + getAppId() + " id: " + getId() + ":version:" + getVersion());
}
}
return _cachedDeserializedExtraParam;
}
public int hashCode() {
return _hc;
}
public boolean equals(Object obj) {
boolean result = false;
if (obj instanceof ReplicationState) {
ReplicationState other = (ReplicationState) obj;
if ((_id.equals(other._id) && (_appId.equals(other._appId)))) {
result = true;
}
}
return result;
}
public boolean isAckRequired() {
return _ackRequired;
}
public void setAckRequired(boolean ackRequired) {
this._ackRequired = ackRequired;
}
public boolean isNack() {
return _isNack;
}
public void setNack(boolean isNack) {
this._isNack = isNack;
}
public long getSendStartTime() {
return _sendStartTime;
}
public void setSendStartTime(long value) {
_sendStartTime = value;
}
public boolean isSent() {
return _sentFlag.get();
}
public void setAckIdsList(List list) {
_ackIdsList = list;
}
public List getAckIdsList() {
return _ackIdsList;
}
public void setSent(boolean value) {
_sentFlag.set(value);
}
public Object getDeserializedExtraParam() {
return _cachedDeserializedExtraParam;
}
public void setDeserializedExtraParam(Object extraParam) {
_cachedDeserializedExtraParam = extraParam;
}
public RouteAdvertisement getRouteAdvertisement(){
return _routeAdvertisement;
}
public void setRouteAdvertisement(RouteAdvertisement routeAdvertisement) {
_routeAdvertisement = routeAdvertisement;
}
public void setProperty(Object key, Object value) {
if(properties != null) {
properties.put(key, value);
}
}
public Object getProperty(Object key) {
return properties != null ? properties.get(key) : null;
}
public void setProperties(Map properties) {
this.properties = properties;
}
public void setProperties(String beKey, String origin) {
if(getProperties() == null) {
setProperties(new HashMap());
}
setProperty(ReplicationState.BEKEY, beKey);
setProperty(ReplicationState.ORIGINATING_INSTANCE_NAME, origin);
}
public void setState(byte[] state) {
this._state = state;
}
public Map getProperties() {
return properties;
}
public String toString() {
StringBuffer sb = new StringBuffer(100);
sb.append("_mode=" + _mode + "\n");
sb.append("_id=" + _id + "\n");
sb.append("_appId=" + _appId + "\n");
sb.append("_version=" + _version + "\n");
sb.append("_command=" + _command + "\n");
sb.append("_lastAccess=" + _lastAccess + "\n");
sb.append("_maxInactiveInterval=" + _maxInactiveInterval + "\n");
sb.append("_extraParam=" + _extraParam + "\n");
sb.append("_queryResult=" + _queryResult + "\n");
sb.append("_instanceName=" + _instanceName + "\n");
sb.append("isExpired=" + this.isExpired() + "\n");
sb.append("_ackRequired=" + this.isAckRequired() + "\n");
sb.append("_isNack=" + _isNack + "\n");
return sb.toString();
}
void setBiDiStyle(boolean value) {
bidiStyle = value;
}
boolean isBiDiStyle() {
return bidiStyle;
}
private List _ackIdsList = null;
private String _mode = null;
private Object _id = null;
private String _appId = null;
private long _lastAccess = 0L;
private long _maxInactiveInterval = 0L; //seconds
private long _version = -1L;
private String _extraParam = null;
private Object _queryResult = null;
String _instanceName = ReplicationUtil.getInstanceName();
private String _command = null;
private byte[] _state = null;
private byte[] _trunkState = null;
private byte[] _containerExtraParamsState = null;
private boolean _ackRequired = false;
private boolean _isNack = false;
private int _hc;
private volatile AtomicBoolean _sentFlag = new AtomicBoolean(false);
private long _sendStartTime = -1L;
private RouteAdvertisement _routeAdvertisement = null;
private transient Object _cachedDeserializedExtraParam = null;
private Map properties = new HashMap();
private boolean bidiStyle;
}