All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.crankuptheamps.client.Command Maven / Gradle / Ivy

////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2010-2022 60East Technologies Inc., All Rights Reserved.
//
// This computer software is owned by 60East Technologies Inc. and is
// protected by U.S. copyright laws and other laws and by international
// treaties.  This computer software is furnished by 60East Technologies
// Inc. pursuant to a written license agreement and may be used, copied,
// transmitted, and stored only in accordance with the terms of such
// license agreement and with the inclusion of the above copyright notice.
// This computer software or any other copies thereof may not be provided
// or otherwise made available to any other person.
//
// U.S. Government Restricted Rights.  This computer software: (a) was
// developed at private expense and is in all respects the proprietary
// information of 60East Technologies Inc.; (b) was not developed with
// government funds; (c) is a trade secret of 60East Technologies Inc.
// for all purposes of the Freedom of Information Act; and (d) is a
// commercial item and thus, pursuant to Section 12.212 of the Federal
// Acquisition Regulations (FAR) and DFAR Supplement Section 227.7202,
// Government's use, duplication or disclosure of the computer software
// is subject to the restrictions set forth by 60East Technologies Inc..
//
////////////////////////////////////////////////////////////////////////////
package com.crankuptheamps.client;

import com.crankuptheamps.client.fields.CommandField;
import com.crankuptheamps.client.exception.AMPSException;

import java.nio.charset.StandardCharsets;

/**
 * 
 * Command is an encapsulation of a single AMPS command sent by the client.
 * Using Command you can build commands to be executed by the client,
 * with message processing happening either synchronously via the
 * {@link Client} execute() method or asynchronously via the executeAsync()
 * methods.
 *
 * Command is designed to be used as a "builder" enabling AMPS commands
 * to be built easily, for example:
 * 
 * 
 * Client client = new Client(...);
 * for(Message m : client.execute(new Command("sow").setTopic("topic"))) { ... }
 * 
* * Notice that the {@link Message} class can represent both command messages * to AMPS and response messages from AMPS. In contrast, Command represents * only commands to AMPS, so the class includes only properties that * are valid on outgoing commands. * * @since 4.0.0.0 */ public class Command { Message _message; private boolean _expiration_isSet; private byte[] _data; private byte[] _topic; private CommandId _commandId; private CommandId _queryId; private CommandId _subId; private int _dataLength; private int _dataOffset; private int _topicLength; private int _topicOffset; private int _ackType; private int _batchSize = 10; private int _command; private int _expiration; private int _topN = -1; private long _clientSequenceNumber; private long _timeout = 0; private String _bookmark; private String _correlationId; private String _dataString; private String _filter; private String _options; private String _orderBy; private String _sowKey; private String _sowKeys; private String _topicString; /** * Set the command and reinitialize all other fields to their default * on-construction values. * @param command */ private void init(final int command) { _command = command; _bookmark = null; _commandId = null; _correlationId = null; _data = null; _dataString = null; _filter = null; _options = null; _orderBy = null; _queryId = null; _sowKey = null; _sowKeys = null; _subId = null; _topic = null; _topicString = null; _ackType = Message.AckType.None; _batchSize = 10; _clientSequenceNumber = 0; _expiration = 0; _timeout = 0; _topN = -1; _expiration_isSet = false; if((_command & Message.Command.NoDataCommands) == 0 || _command == Message.Command.SOWDelete) { _commandId = com.crankuptheamps.client.CommandId.nextIdentifier(); if(isSow()) { _queryId = _commandId; } if(isSubscribe()) { _subId = _commandId; } } } /** * Returns the SOW key on this command. * @return the sow key * @since 4.0.0.0 * @deprecated Use getSowKey() instead. */ @Deprecated public String getSOWKey() { return _sowKey; } /** * Returns the SOW key on this command. * @return the sow key * @since 5.0.0.0 */ public String getSowKey() { return _sowKey; } /** * The SowKey for a command is used to publish to a SOW topic with * explicit keys set by the user rather than AMPS. The SOW key for a * message is available through the {@link Message#getSowKey} method * on a message. * @param sowKey the sow key to set * @return Returns this instance so that various operations can be chained together. * @since 4.3.0.0 * @deprecated Use setSowKey() instead. */ @Deprecated public Command setSOWKey(String sowKey) { _sowKey = sowKey; return this; } /** * The SowKey for a command is used to publish to a SOW topic with * explicit keys set by the user rather than AMPS. The SOW key for a * message is available through the {@link Message#getSowKey} method * on a message. * @param sowKey the sow key to set * @return Returns this instance so that various operations can be chained together. * @since 5.0.0.0 */ public Command setSowKey(String sowKey) { _sowKey = sowKey; return this; } /** * Returns the SOW key on this command. * @return the sow key * @since 5.0.0.0 */ public String getSowKeys() { return _sowKeys; } /** * Returns the SOW key on this command. * @return the sow key * @since 4.3.0.0 * @deprecated Use getSowKeys() instead */ @Deprecated public String getSOWKeys() { return _sowKeys; } /** * The SowKeys for a command are a comma-separated list * of the keys that AMPS assigns to SOW messages. The SOW key for a * message is available through the {@link Message#getSowKey} method * on a message. * @param sowKeys the sow keys to set * @return Returns this instance so that various operations can be chained together. * @since 5.0.0.0 */ public Command setSowKeys(String sowKeys) { _sowKeys = sowKeys; return this; } /** * The SowKeys for a command are a comma-separated list * of the keys that AMPS assigns to SOW messages. The SOW key for a * message is available through the {@link Message#getSowKey} method * on a message. * @param sowKeys the sow keys to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 * @deprecated Use setSowKeys() instead. */ @Deprecated public Command setSOWKeys(String sowKeys) { _sowKeys = sowKeys; return this; } /** * Returns true if this command creates a subscription. * @return true if this command creates a subscription. * @since 4.0.0.0 */ public final boolean isSubscribe() { return _command == Message.Command.DeltaSubscribe || _command == Message.Command.SOWAndDeltaSubscribe || _command == Message.Command.SOWAndSubscribe || _command == Message.Command.Subscribe; } /** * Returns true if this command queries a SOW. * @return true if this command queries a SOW. * @since 4.0.0.0 */ public final boolean isSow() { return _command == Message.Command.SOW || _command == Message.Command.SOWAndDeltaSubscribe || _command == Message.Command.SOWAndSubscribe; } /** * Returns true if this command can be associated with a client sequence number. * * @return true if this command can be associated with a client sequence number. * @since 4.0.0.0 */ public boolean needsSequenceNumber() { return _command == Message.Command.Publish || _command == Message.Command.DeltaPublish || _command == Message.Command.SOWDelete; } private int translateCommand(String command_) { CommandField cf = new CommandField(); cf.set(command_.getBytes(StandardCharsets.ISO_8859_1)); if(!CommandField.encodeCommand(cf.getValue()).equals(command_)) { throw new IllegalArgumentException("unknown command type " + command_); } return cf.getValue(); } /** * Create a new Command with no command type or arguments set. * @since 4.0.0.0 */ public Command() { } /** * Create a Command with the Command field set. * @param command A {@link Message.Command} value indicating the AMPS command. * @since 4.0.0.0 */ public Command(final int command) { init(command); } /** * Create a Command with the Command field set. * @param command A string indicating the AMPS command. * @since 4.0.0.0 */ public Command(final String command) { init(translateCommand(command)); } /** * Resets this command with a new Command type and re-initializes all other fields. * @param command A {@link Message.Command} value indicating the AMPS command. * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command reset(final int command) { init(command); return this; } /** * Resets this command with a new Command type and re-initializes all other fields. * @param command A string value indicating the AMPS command. * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command reset(final String command) { init(translateCommand(command)); return this; } /** * @return the commandId, which is automatically generated for some command types. * @since 4.0.0.0 */ public CommandId getCommandId() { return _commandId; } /** * Set the commandId for this command. * @param commandId the commandId to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setCommandId(CommandId commandId) { _commandId = commandId; return this; } /** * Get the queryId for this command. * @return the queryId * @since 4.0.0.0 */ public CommandId getQueryId() { return _queryId; } /** * Set the queryId for this command. * @param queryId the queryId to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setQueryId(CommandId queryId) { _queryId = queryId; return this; } /** * Return the command type for this command. * @return the command * @since 4.0.0.0 */ public int getCommand() { return _command; } /** * Set the command type for this command. * @param command the command to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setCommand(int command) { _command = command; return this; } /** * Get the topic set on this command. * @return the topic * @since 4.0.0.0 */ public String getTopic() { if (_topic == null) return _topicString; if (_message == null) return new String(_topic,_topicOffset,_topicLength, StandardCharsets.ISO_8859_1); else return new String(_topic,_topicOffset,_topicLength, _message.getDecoder().charset()); } /** * Set the topic for this command. * @param topic the topic to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setTopic(String topic) { _topicString = topic; _topic = null; return this; } /** * Set the topic for this command from raw bytes. * @param topic The raw bytes to be used for the topic. * @param offset The offset into topic where the topic data begins * @param length The length of the topic. * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setTopic(byte[] topic, int offset, int length) { _topic = topic; _topicString = null; _topicLength = length; _topicOffset = 0; return this; } /** * Get the filter for this command. * @return the filter * @since 4.0.0.0 */ public String getFilter() { return _filter; } /** * Set the filter for this command. * @param filter the filter to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setFilter(String filter) { _filter = filter; return this; } /** * Get the orderBy clause for this command. * @return the orderBy * @since 4.0.0.0 */ public String getOrderBy() { return _orderBy; } /** * Set the orderBy clause for this command. * @param orderBy the orderBy to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setOrderBy(String orderBy) { _orderBy = orderBy; return this; } /** * Get the subId set on this command. * @return the subId * @since 4.0.0.0 */ public CommandId getSubId() { return _subId; } /** * Set the subId for this command. * @param subId the subId to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setSubId(CommandId subId) { if(subId != null) _subId = subId; return this; } /** * Set the subId for this command. * @param subId the subId to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setSubId(String subId) { if(subId != null) _subId = new CommandId(subId); return this; } /** * Get the bookmark for this command. * @return the bookmark * @since 4.0.0.0 */ public String getBookmark() { return _bookmark; } /** * Set the bookmark for this command. * @param bookmark the bookmark to set * @return Returns the instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setBookmark(String bookmark) { _bookmark = bookmark; return this; } /** * Get the options for this command. * @return the options * @since 4.0.0.0 */ public String getOptions() { return _options; } /** * Set the options for this command. Options are a comma-delimited list. * @param options the options to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setOptions(String options) { _options = options; return this; } /** * Get the ackType for this command. * @return the ackType * @since 4.0.0.0 */ public int getAckType() { return _ackType; } /** * Set the ackType for this command. Different ackTypes are supported * for each command. See the Command Reference for details. * @param ackType the ackType to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setAckType(int ackType) { if (ackType == Message.AckType.None || ackType == Message.AckType.Persisted) { if (_commandId != null && (_command & Message.Command.NoDataCommands) != 0) { _commandId = null; } } else if (_commandId == null) { _commandId = CommandId.nextIdentifier(); } _ackType = ackType; return this; } /** * Adds an additional ackType to the ackTypes already set * for this Command. * @param ackType the ackType to add * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command addAckType(int ackType) { _ackType |= ackType; return this; } /** * Get the data set on this command. * @return the data * @since 4.0.0.0 */ public String getData() { if (_data == null) return _dataString; if (_message == null) return new String(_data,_dataOffset,_dataLength, StandardCharsets.ISO_8859_1); else return new String(_data,_dataOffset,_dataLength, _message.getDecoder().charset()); } /** * Set the data for this command. * @param data the data to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setData(String data) { _dataString = data; _data = null; return this; } /** * Set the data for this command. * @param data The raw bytes to be used for the data. * @param offset The offset into data where the data begins. * @param length The length of the data. * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setData(byte[] data, int offset, int length) { _dataString = null; _data = data; _dataOffset = offset; _dataLength = length; return this; } /** * Set the data for this command. * @param builder a {@link CompositeMessageBuilder} to set self's data from. * @return Returns this instance so that various operations can be chained together. */ public Command setData(CompositeMessageBuilder builder) { _dataString = null; _data = builder._bytes; _dataOffset = 0; _dataLength = builder._position; return this; } /** * Get the timeout set on this command. * @return the timeout * @since 4.0.0.0 */ public long getTimeout() { return _timeout; } /** * Set the timeout for this command (in milliseconds). If the client does * not receive and consume a processed ack within the specified timeout, * this method throws an exception. Notice that the timeout is monitored * in the AMPS client, not on the server, and the client receive thread * receives and consumes the ack from the server. * @param timeout the timeout to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setTimeout(long timeout) { _timeout = timeout; return this; } /** * Get the topN value for this command. * @return the topN * @since 4.0.0.0 */ public int getTopN() { return _topN; } /** * Set the topN value for this command. This parameter sets a maximum * number of records returned by a SOW query. * @param topN the topN to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setTopN(int topN) { _topN = topN; return this; } /** * Get the batchSize set on this command. * @return the batchSize * @since 4.0.0.0 */ public int getBatchSize() { return _batchSize; } /** * Set the batchSize for this command. This sets the number of records * returned in a batch during a SOW query. * @param batchSize the batchSize to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setBatchSize(int batchSize) { _batchSize = batchSize; return this; } /** * Get the expiration set on this command. This method returns 0 if * no expiration is set. Use {@link Command#hasExpiration() } to check if an * expiration is set. * @return the expiration * @since 4.0.0.0 */ public int getExpiration() { if(!_expiration_isSet) return 0; return _expiration; } /** * Returns true if this command has an expiration set. * @return true if an expiration is set. * @since 4.0.0.0 */ public boolean hasExpiration() { return _expiration_isSet; } /** * Set the expiration for this command. For a publish command to a * SOW topic or a queue, the expiration sets the amount of time * to retain the message in the SOW or the queue. * @param expiration the expiration to set * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setExpiration(int expiration) { _expiration = expiration; _expiration_isSet = true; return this; } /** * Clears any expiration value set on self. * @since 4.0.0.0 */ public void unsetExpiration() { _expiration_isSet = false; } /** * Binds self to a given client, preparing a message from that client to be sent. * @param client_ The client to bind against * @return The CommandId for this command, if one is set, or null. * @throws AMPSException Thrown when preparing the command fails. * @since 4.0.0.0 */ protected CommandId prepare(Client client_) throws AMPSException { if(_message == null) { _message = client_.allocateMessage(); } else { _message.reset(); } _message.setCommand(_command); if(_commandId !=null) _message.setCommandId(_commandId); _message.setAckType(_ackType); if(_bookmark != null) _message.setBookmark(_bookmark); if(_data != null) _message.setData(_data,_dataOffset,_dataLength); else if(_dataString != null) _message.setData(_dataString); if(_filter !=null) _message.setFilter(_filter); if(_options !=null) _message.setOptions(_options); if(_orderBy !=null) _message.setOrderBy(_orderBy); if(_queryId !=null) _message.setQueryId(_queryId); if(_subId !=null) _message.setSubId(_subId); if(_topic !=null) _message.setTopic(_topic,_topicOffset,_topicLength); else if(_topicString != null) _message.setTopic(_topicString); if(_expiration_isSet) _message.setExpiration(_expiration); if(_sowKey !=null) _message.setSowKey(_sowKey); if(_sowKeys !=null) _message.setSowKeys(_sowKeys); if(_batchSize > 1 && (_command == Message.Command.SOW || _command == Message.Command.SOWAndSubscribe || _command == Message.Command.SOWAndDeltaSubscribe)) { _message.setBatchSize(_batchSize); } if(_topN != -1) _message.setTopN(_topN); if(_correlationId != null) _message.setCorrelationId(_correlationId); if(_clientSequenceNumber > 0 && needsSequenceNumber()) { _message.setSequence(_clientSequenceNumber); } return _commandId; } /** * Sets the client sequence number for this command. * @param seqNumber Sequence number for this command * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setClientSequenceNumber(long seqNumber) { _clientSequenceNumber = seqNumber; return this; } /** * Get the client sequence number set on this command. * @return the client sequence number generated for this command, or 0 if none was generated. * @since 4.0.0.0 */ public long getClientSequenceNumber() { return _clientSequenceNumber; } /** * Sets the correlation Id for this command. The correlation ID * is an arbitrary string that can be used for whatever purpose the * application needs. It is not interpreted or used by AMPS. However, * the correlation ID must only contain characters that are valid base64 * encoded characters. * @param correlationId_ The CorrelationId is a user provided string included in the log message for a logon. * AMPS does not interpret or use this string for any other purpose. * @return Returns this instance so that various operations can be chained together. * @since 4.0.0.0 */ public Command setCorrelationId(String correlationId_) { _correlationId = correlationId_; return this; } /** * Returns the correlation Id set on this command * @return Returns the correlation id * @since 4.0.0.0 */ public String getCorrelationId() { return _correlationId; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy