com.alachisoft.ncache.client.internal.command.Command Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ncache-professional-client Show documentation
Show all versions of ncache-professional-client Show documentation
NCache Professional client for java.
/*
* Command.java
*
* Created on September 8, 2006, 12:37 PM
*
* Copyright 2005 Alachisoft, Inc. All rights reserved.
* ALACHISOFT PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.alachisoft.ncache.client.internal.command;
import Alachisoft.NCache.Common.DataStructures.BridgeOperation;
import Alachisoft.NCache.Common.Net.Address;
import com.alachisoft.ncache.client.internal.communication.Broker;
import com.alachisoft.ncache.client.internal.communication.Connection;
import com.alachisoft.ncache.client.internal.communication.Request;
import com.alachisoft.ncache.client.internal.communication.SendError;
import com.alachisoft.ncache.common.protobuf.NamedTagInfoProtocol;
import com.alachisoft.ncache.common.protobuf.QueryInfoProtocol;
import com.alachisoft.ncache.common.protobuf.TagInfoProtocol;
import com.alachisoft.ncache.runtime.exceptions.CommandException;
import com.alachisoft.ncache.runtime.util.HelperFxn;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.*;
public abstract class Command {
// region Fields
protected byte[] value = null;
protected byte[] commandBytes = null;
protected byte[] internalCommandSize = null;
private long requestId = -1;
private String[] bulkKeys;
private BridgeOperation[] bridgeOperations;
private CommandResponse result = null;
private String _cacheId;
static String NC_NULL_VAL = "NLV";
static String VERSION = "4200";
protected String name;
private long clientLastViewId = -1;
private String intendedRecipient;
protected String key;
public boolean isAsync = false ;
public boolean asyncCallbackSpecified = false;
private String ip = "";
protected boolean inquiryEnabled;
protected com.alachisoft.ncache.common.protobuf.CommandProtocol.Command _command;
protected int _commandID = 0;
private byte[] serialized;
private Address _finalDestinationAddress;
private boolean isSurrogationSupported;
private boolean isRetry;
private Request _parent;
private boolean supportsAcknowledgement;
private long acknowledgmentId;
public boolean pulseOnSend;
public boolean sentOverWire;
private SendError sendError;
// endregion
// region Properties
public int getCommandID() {
return _commandID;
}
public void setCommandID(int value) {
_commandID = value;
}
public byte[] getSerialized()
{
return serialized;
}
public void setSerialized(byte[] value)
{
serialized = value;
}
public Address getFinalDestinationAddress() {
return _finalDestinationAddress;
}
public void setFinalDestinationAddress(Address finalDestinationAddress) {
this._finalDestinationAddress = finalDestinationAddress;
}
public boolean getSupportsSurrogation() {
return isSurrogationSupported;
}
public void setSupportsSurrogation(boolean surrogationSupported) {
isSurrogationSupported = surrogationSupported;
}
public boolean getIsRetry() {
return isRetry;
}
public void setIsRetry(boolean retry) {
isRetry = retry;
}
public Request getParent() {
return _parent;
}
public void setParent(Request _parent) {
this._parent = _parent;
}
public boolean getIsInternalCommand() {
return getCommandRequestType() == RequestType.InternalCommand;
}
public abstract RequestType getCommandRequestType();
public abstract CommandType getCommandType();
public com.alachisoft.ncache.common.protobuf.CommandProtocol.Command.Type getType()
{
return _command.getType();
}
public long getRequestId() {
return requestId;
}
public void setRequestId(long value) {
requestId = value;
}
public boolean getSupportsAacknowledgement() {
return supportsAcknowledgement;
}
public void setSupportsAacknowledgement(boolean supportsAcknowledgement) {
this.supportsAcknowledgement = supportsAcknowledgement;
}
public long getClientLastViewId() {
return clientLastViewId;
}
public void setClientLastViewId(long clientLastViewId) {
this.clientLastViewId = clientLastViewId;
}
public String getIntendedRecipient() {
return intendedRecipient;
}
public void setIntendedRecipient(String intendedRecipient) {
this.intendedRecipient = intendedRecipient;
}
public CommandResponse getResponse() {
return result;
}
public void setResponse(CommandResponse res) {
this.result = res;
}
public String getKey() {
return key;
}
public String[] getBulkKeys() {
return bulkKeys;
}
public void setBulkKeys(String[] bulkKeys) {
this.bulkKeys = bulkKeys;
}
public Object getValue() {
return value;
}
public void setValue(byte[] bytes){ value = bytes; }
public BridgeOperation[] getBridgeOperations() {
return bridgeOperations;
}
public void setBridgeOperations(BridgeOperation[] bridgeOperations) {
this.bridgeOperations = bridgeOperations;
}
public String getCommandName() {
return name;
}
public boolean getIsSafe() {
return true;
}
protected boolean getIsKeyBased() {
return true;
}
public long getAcknowledgmentId() {
return acknowledgmentId;
}
public void setAcknowledgmentId(long acknowledgmentId) {
this.acknowledgmentId = acknowledgmentId;
}
public boolean getPulseOnSend() {
return pulseOnSend;
}
public void setPulseOnSend(boolean pulseOnSend) {
this.pulseOnSend = pulseOnSend;
}
public boolean getSentOverWire() {
return sentOverWire;
}
public void setSentOverWire(boolean sentOverWire) {
this.sentOverWire = sentOverWire;
}
public SendError getSendError() {
return sendError;
}
public void setSendError(SendError sendError) {
this.sendError = sendError;
}
public String getCacheId() {
return _cacheId;
}
public void setCacheId(String _cacheId) {
this._cacheId = _cacheId;
}
// endregion
//region Methods
protected byte[] constructCommand(byte[] serializedCommand) throws IOException
{
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
///Copy discarding buffer for server
byte[] discardingBuffer = new byte[20];
stream.write(discardingBuffer);
///Copy size of data in 10 bytes
byte[] size = new byte[CommandOptions.COMMAND_SIZE];
byte[] commandSize = String.valueOf(serializedCommand.length).getBytes(StandardCharsets.UTF_8);
System.arraycopy(commandSize, 0, size, 0, commandSize.length);
stream.write(size);
///Copy actual data
stream.write(serializedCommand);
///Return the packet
return stream.toByteArray();
} finally {
stream.close();
}
}
protected abstract void createCommand() throws CommandException;
public int getAcknowledgementOffset()
{
return 0;
}
public byte[] toByte(long acknowledgement, boolean requestInquiryEnabled) throws CommandException, IOException {
synchronized (this) {
if (commandBytes == null || inquiryEnabled != requestInquiryEnabled) {
inquiryEnabled = requestInquiryEnabled;
this.createCommand();
this.serializeCommand();
}
if (getSupportsAacknowledgement() && inquiryEnabled) {
byte[] acknowledgementBuffer = String.valueOf(acknowledgement).getBytes(StandardCharsets.UTF_8);
System.arraycopy(acknowledgementBuffer, 0, commandBytes, getAcknowledgementOffset(), acknowledgementBuffer.length);
}
return commandBytes;
}
}
protected void serializeCommandInternal(ByteArrayOutputStream stream) throws IOException
{
_command.writeTo(stream);
}
protected short getCommandHandle()
{
return 0;
}
protected void serializeCommand() throws IOException {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
//Writes a section for acknowledgment buffer.
byte[] acknowledgementBuffer = (getSupportsAacknowledgement() && inquiryEnabled) ? new byte[20] : new byte[0];
stream.write(acknowledgementBuffer, 0, acknowledgementBuffer.length);
// Write command type, write 0 for base Command.
byte[] commandType = HelperFxn.writeShort(getCommandHandle());
stream.write(commandType, 0, commandType.length);
// Writes a section for the command size.
byte[] size = new byte[Connection.CmdSizeHolderBytesCount];
stream.write(size, 0, size.length);
serializeCommandInternal(stream);
//All buffers acknowledgement/discarded/size will be using byte[] commandBytes
// As stream in java has no way to set its Position
commandBytes = stream.toByteArray();
//lenght calculation of command
int messageLen;
messageLen = stream.size() - (size.length + acknowledgementBuffer.length + commandType.length);
size = String.valueOf(messageLen).getBytes(StandardCharsets.UTF_8);
//Command size setting copy length at position filled dummy previously
int offset=acknowledgementBuffer.length + commandType.length;
System.arraycopy(size, 0, commandBytes, offset, size.length );
stream.close();
}
public void resetCommand()
{
if (_parent != null) {
this.commandBytes = null;
this._commandID = this._parent.getNextCommandID();
}
}
public static Command getDedicatedCommand(Collection commands, String address)
{
/*
* usama@30092014
* This function will be called only for bulk commands
* If commands are non-key commands, each command in passed commands will be the same,
* If commands are key based bulk command, each command will have seperate set of keys. Need to merge all keys to create a dedicated command.
*/
Command dedicatedCommand = null;
List commandsList = new ArrayList<>(commands);
dedicatedCommand = commandsList.get(0).getMergedCommand(commandsList);
dedicatedCommand.commandBytes = null;
dedicatedCommand.setClientLastViewId(Broker.ForcedViewId);
dedicatedCommand.getParent().getCommands().clear();
dedicatedCommand.getParent().addCommand(new Address(address, 9800), dedicatedCommand);
return dedicatedCommand;
}
public byte[] getSerializedSurrogateCommand() throws IOException, CommandException {
byte[] serializedbytes = null;
ByteArrayOutputStream stream = new ByteArrayOutputStream();
this.createCommand();
if (_command != null)
{
_command.writeTo(stream);
}
serializedbytes = stream.toByteArray();
return serializedbytes;
}
protected Command getMergedCommand(List commands)
{
return commands != null && commands.size() > 0 ? commands.get(0) : null;
}
protected String rebuildCommandWithTagInfo(HashMap tagInfo)
{
StringBuilder cmdString = new StringBuilder();
cmdString.append(tagInfo.get("type") + "\"");
Object obj = tagInfo.get("tags-list");
if (obj instanceof ArrayList) {
ArrayList tagsList = (ArrayList) obj;
cmdString.append(tagsList.size() + "\"");
Iterator tagsEnum = tagsList.iterator();
while (tagsEnum.hasNext()) {
Object current = tagsEnum.next();
if (current != null) {
cmdString.append(current.toString() + "\"");
} else {
cmdString.append(NC_NULL_VAL+"\"");
}
}
}
return cmdString.toString();
}
protected String rebuildCommandWithQueryInfo(HashMap queryInfo)
{
Map.Entry entry;
StringBuilder cmdString = new StringBuilder();
Iterator hashmapIt = queryInfo.entrySet().iterator();
while (hashmapIt.hasNext()) {
entry = (Map.Entry) hashmapIt.next();
cmdString.append(entry.getKey()).append("\"");
ArrayList values = (ArrayList) entry.getValue();
cmdString.append(values.size()).append("\"");
//New implementation involves a check here
for (int i = 0; i < values.size(); i++) {
cmdString.append(values.get(i)).append("\"");
}
}
return cmdString.toString();
}
@Override
public String toString()
{
return name + " : " + requestId;
}
//endregion
//region Not Used in .Net
protected int asyncCallbackId = -1;
public static QueryInfoProtocol.QueryInfo getQueryInfoObj(HashMap queryInfoDic) {
if (queryInfoDic == null) {
return null;
}
if (queryInfoDic.size() == 0) {
return null;
}
QueryInfoProtocol.QueryInfo.Builder builder = QueryInfoProtocol.QueryInfo.newBuilder();
Iterator queryInfoEnum = queryInfoDic.keySet().iterator();
while (queryInfoEnum.hasNext()) {
builder = builder.setHandleId((Integer) queryInfoEnum.next());
ArrayList values = (ArrayList) queryInfoDic.get(builder.getHandleId());
int valuesListSize = values.size();
for (int i = 0; i < valuesListSize; i++) {
Object val = values.get(i);
if (val != null) {
if (val instanceof Date) {
val = HelperFxn.getTicks((Date) val);
}
builder = builder.addAttributes(val.toString());
} else //[Asad] as per fix mentioned in .net client by [salman] we need to send null values too as a special placeholder
{
builder = builder.addAttributes("NCNULL");
}
}
}
return builder.build();
}
public static TagInfoProtocol.TagInfo getTagInfo(HashMap tagInfoDic) {
if (tagInfoDic == null || tagInfoDic.size() == 0) {
return null;
}
TagInfoProtocol.TagInfo.Builder builder = TagInfoProtocol.TagInfo.newBuilder();
builder = builder.setType(String.valueOf(tagInfoDic.get("type")));
Object obj = tagInfoDic.get("tags-list");
if (obj instanceof ArrayList) {
Iterator tagsEnum = ((ArrayList) obj).iterator();
while (tagsEnum.hasNext()) {
Object current = tagsEnum.next();
if (current != null) {
builder = builder.addTags(current.toString());
}
}
}
return builder.build();
}
public static NamedTagInfoProtocol.NamedTagInfo GetNamedTagInfoObj(HashMap namedTagInfoDic) {
if (namedTagInfoDic == null || namedTagInfoDic.size() == 0) {
return null;
}
NamedTagInfoProtocol.NamedTagInfo.Builder builder = NamedTagInfoProtocol.NamedTagInfo.newBuilder();
builder = builder.setType(String.valueOf(namedTagInfoDic.get("type")));
HashMap tagsList = (HashMap) namedTagInfoDic.get("named-tags-list");
Iterator namedTagEnumerator = tagsList.keySet().iterator();
while (namedTagEnumerator.hasNext()) {
Object current = namedTagEnumerator.next();
if (current != null) {
Object val = tagsList.get(current);
builder = builder.addNames(current.toString());
builder = builder.addTypes(val.getClass().getCanonicalName());
if (val instanceof Date) {
val = HelperFxn.getTicks((Date) val);
}
builder = builder.addVals(val.toString());
}
}
return builder.build();
}
//endregion
}