/**
* Helios, OpenSource Monitoring
* Brought to you by the Helios Development Group
*
* Copyright 2007, Helios Development Group and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*
*/
package org.helios.apmrouter;
import org.jboss.netty.buffer.ChannelBuffer;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* <p>Title: OpCode</p>
* <p>Description: Enumerates sender and receiver operation codes.</p>
* <p>Company: Helios Development Group LLC</p>
* @author Whitehead (nwhitehead AT heliosdev DOT org)
* <p><code>org.helios.apmrouter.OpCode</code></p>
*/
public enum OpCode {
/** An asynch send of a metric payload */
SEND_METRIC,
/** A return of a metric's token value back to a client that sent an untokenized metric */
SEND_METRIC_TOKEN,
/** A synchronous send of a single metric payload */
SEND_METRIC_DIRECT,
/** A direct metric trace handshake */
CONFIRM_METRIC(SEND_METRIC_DIRECT),
/** A synchronous send of a ping */
PING,
/** A direct metric trace handshake */
PING_RESPONSE(PING),
/** Inquiry as to the identity of a connecting agent */
WHO,
/** Response as to the identity of a connecting agent */
WHO_RESPONSE(WHO),
/** Indicates a client has started and is announcing itself */
HELLO,
/** A HELLO handshake from the server */
HELLO_CONFIRM(HELLO),
/** Indicates a client is about to disconnect */
BYE,
/** Directive from the server to flush metric catalog because a reset has occured */
RESET,
/** Confirm from the agent that the reset is complete */
RESET_CONFIRM(RESET),
/** A JMX request to the agent's MBeanServer */
JMX_REQUEST,
/** A response to a JMX request */
JMX_RESPONSE(JMX_REQUEST),
/** A JMX notification to a server listener */
JMX_NOTIFICATION,
/** Indicator sent to the agent that the server has closed the MBeanServerConnection but not the channel */
JMX_CONN_CLOSED,
/** Inquiry from server about available MBeanServers */
JMX_MBS_INQUIRY,
/** Response from agent to inquiry from server about available MBeanServers */
JMX_MBS_INQUIRY_RESPONSE(JMX_MBS_INQUIRY),
/** MetricURI subscription request */
METRIC_URI_SUBSCRIBE,
/** MetricURI subscription confirm */
METRIC_URI_SUB_CONFIRM(METRIC_URI_SUBSCRIBE),
/** MetricURI subscription cancel */
METRIC_URI_UNSUBSCRIBE,
/** MetricURI subscription cancel confirm */
METRIC_URI_UNSUB_CONFIRM(METRIC_URI_UNSUBSCRIBE),
/** MetricURI subscription event */
ON_METRIC_URI_EVENT,
/** Starts a SubDestination subscription */
START_SUB_DEST,
/** Starts a SubDestination subscription */
START_SUB_DEST_CONFIRM(START_SUB_DEST),
/** Stops a SubDestination subscription */
STOP_SUB_DEST,
/** Stops a SubDestination subscription */
STOP_SUB_DEST_CONFIRM(STOP_SUB_DEST);
public static void main(String[] args) {
for(OpCode op: OpCode.values()) {
System.out.println("[" + op.name() + "]:" + op.op());
}
}
private OpCode() {
code = (byte)ordinal();
}
private OpCode(OpCode req) {
code = (byte)(req.ordinal()*-1);
}
/** The byte representation of this OpCode */
private final byte code;
/**
* Returns the byte representation of this OpCode
* @return the byte representation of this OpCode
*/
public byte getCode() {
return code;
}
/** Map of OpCodes keyed by the byte code */
private static final Map<Byte, OpCode> BYTE2ENUM;
/** Map of OpCodes keyed by the ordinal */
private static final Map<Integer, OpCode> ORD2ENUM;
static {
Map<Byte, OpCode> tmp = new HashMap<Byte, OpCode>(OpCode.values().length);
Map<Integer, OpCode> itmp = new HashMap<Integer, OpCode>(OpCode.values().length);
for(OpCode op: OpCode.values()) {
itmp.put(op.ordinal(), op);
OpCode prior = tmp.put(op.code, op);
if(prior!=null){
throw new RuntimeException("Duplicate Byte Code for Ops: [" + op + "] and [" + prior + "]", new Throwable());
}
}
BYTE2ENUM = Collections.unmodifiableMap(tmp);
ORD2ENUM = Collections.unmodifiableMap(itmp);
}
/**
* Decodes the passed byte code to a OpCode.
* Throws a runtime exception if the byte code is invalud
* @param byteCode The byte code to decode
* @return the decoded OpCode
*/
public static OpCode valueOf(byte byteCode) {
OpCode op = BYTE2ENUM.get(byteCode);
if(op==null) throw new IllegalArgumentException("The passed byteCode [" + byteCode + "] is not a valid OpCode byteCode", new Throwable());
return op;
}
/**
* Decodes the passed ordinal to a OpCode.
* Throws a runtime exception if the ordinal is invalud
* @param ordinal The ordinal to decode
* @return the decoded OpCode
*/
public static OpCode ordinal(int ordinal) {
OpCode op = ORD2ENUM.get(ordinal);
if(op==null) throw new IllegalArgumentException("The passed ordinal [" + ordinal + "] is not a valid OpCode ordinal", new Throwable());
return op;
}
/**
* Indicates if the passed byte represents a valid OpCode
* @param op the bytes to test
* @return true if the passed byte represents a valid OpCode, false otherwise
*/
public static boolean isOpCode(byte op) {
return BYTE2ENUM.containsKey(op);
}
/**
* Returns the ordinal as a byte
* @return the ordinal as a byte
*/
public byte op() {
return code;
}
/**
* Determines the op Code of the request in the passed buffer
* @param buff The buffer to read the op code from
* @return The decoded op type
*/
public static OpCode valueOf(ChannelBuffer buff) {
if(buff==null) throw new IllegalArgumentException("The passed buffer was null", new Throwable());
return valueOf(buff.getByte(0));
}
}