/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ignite.internal.processors.rest.protocols.tcp; import java.util.UUID; import org.apache.ignite.internal.processors.rest.client.message.GridClientMessage; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.jetbrains.annotations.Nullable; /** * Memcached protocol request. */ public class GridMemcachedMessage implements GridClientMessage { /** */ private static final long serialVersionUID = 0L; /** Random UUID used for memcached clients authentication. */ private static final UUID MEMCACHED_ID = UUID.randomUUID(); /** Header length. */ public static final int HDR_LEN = 24; /** Flags length. */ public static final byte FLAGS_LENGTH = 4; /** Memcache client request flag. */ public static final byte MEMCACHE_REQ_FLAG = (byte)0x80; /** Response flag. */ public static final byte MEMCACHE_RES_FLAG = (byte)0x81; /** Custom client request flag. */ public static final byte IGNITE_REQ_FLAG = (byte)0x90; /** Client handshake flag. */ public static final byte IGNITE_HANDSHAKE_FLAG = (byte)0x91; /** Client handshake flag. */ public static final byte IGNITE_HANDSHAKE_RES_FLAG = (byte)0x92; /** Success status. */ public static final int SUCCESS = 0x0000; /** Key not found status. */ public static final int KEY_NOT_FOUND = 0x0001; /** Failure status. */ public static final int FAILURE = 0x0004; /** Serialized flag. */ public static final int SERIALIZED_FLAG = 1; /** Boolean flag. */ public static final int BOOLEAN_FLAG = (1 << 8); /** Integer flag. */ public static final int INT_FLAG = (2 << 8); /** Long flag. */ public static final int LONG_FLAG = (3 << 8); /** Date flag. */ public static final int DATE_FLAG = (4 << 8); /** Byte flag. */ public static final int BYTE_FLAG = (5 << 8); /** Float flag. */ public static final int FLOAT_FLAG = (6 << 8); /** Double flag. */ public static final int DOUBLE_FLAG = (7 << 8); /** Byte array flag. */ public static final int BYTE_ARR_FLAG = (8 << 8); /** Request flag. */ private byte reqFlag; /** Operation code. */ private byte opCode; /** Key length. */ private short keyLen; /** Extras length. */ private byte extrasLen; /** Status. */ private int status; /** Total body length. */ private int totalLen; /** Opaque. */ private byte[] opaque; /** Extras. */ private byte[] extras; /** Key. */ private Object key; /** Value. */ private Object val; /** Value to add/subtract */ private Long delta; /** Initial value for increment and decrement commands. */ private Long init; /** Expiration time. */ private Long expiration; /** Cache name. */ private String cacheName; /** * Creates empty packet which will be filled in parser. */ GridMemcachedMessage() { } /** * Creates copy of request packet for easy response construction. * * @param req Source request packet. */ GridMemcachedMessage(GridMemcachedMessage req) { assert req != null; reqFlag = req.reqFlag; opCode = req.opCode; opaque = new byte[req.opaque.length]; U.arrayCopy(req.opaque, 0, opaque, 0, req.opaque.length); } /** {@inheritDoc} */ @Override public long requestId() { return U.bytesToInt(opaque, 0); } /** {@inheritDoc} */ @Override public void requestId(long reqId) { U.intToBytes((int) reqId, opaque, 0); } /** {@inheritDoc} */ @Override public UUID clientId() { return MEMCACHED_ID; } /** {@inheritDoc} */ @Override public void clientId(UUID id) { // No-op. } /** {@inheritDoc} */ @Override public UUID destinationId() { return null; // No destination available for memcached packets. } /** {@inheritDoc} */ @Override public void destinationId(UUID id) { throw new UnsupportedOperationException("destId is not supported by memcached packets."); } /** {@inheritDoc} */ @Override public byte[] sessionToken() { return null; } /** {@inheritDoc} */ @Override public void sessionToken(byte[] sesTok) { // No-op. } /** * @return Request flag. */ public byte requestFlag() { return reqFlag; } /** * @param reqFlag Request flag. */ public void requestFlag(byte reqFlag) { this.reqFlag = reqFlag; } /** * @return Operation code. */ public byte operationCode() { return opCode; } /** * @param opCode Operation code. */ public void operationCode(byte opCode) { assert opCode >= 0; this.opCode = opCode; } /** * @return Key length. */ public short keyLength() { return keyLen; } /** * @param keyLen Key length. */ public void keyLength(short keyLen) { assert keyLen >= 0; this.keyLen = keyLen; } /** * @return Extras length. */ public byte extrasLength() { return extrasLen; } /** * @param extrasLen Extras length. */ public void extrasLength(byte extrasLen) { assert extrasLen >= 0; this.extrasLen = extrasLen; } /** * @return Status. */ public int status() { return status; } /** * @param status Status. */ public void status(int status) { this.status = status; } /** * @return Total length. */ public int totalLength() { return totalLen; } /** * @param totalLen Total length. */ public void totalLength(int totalLen) { assert totalLen >= 0; this.totalLen = totalLen; } /** * @return Opaque. */ public byte[] opaque() { return opaque; } /** * @param opaque Opaque. */ public void opaque(byte[] opaque) { assert opaque != null; this.opaque = opaque; } /** * @return Extras. */ public byte[] extras() { return extras; } /** * @param extras Extras. */ public void extras(byte[] extras) { assert extras != null; this.extras = extras; } /** * @return Key. */ public Object key() { return key; } /** * @param key Key. */ public void key(Object key) { assert key != null; this.key = key; } /** * @return Value. */ public Object value() { return val; } /** * @param val Value. */ public void value(Object val) { assert val != null; this.val = val; } /** * @return Expiration. */ @Nullable public Long expiration() { return expiration; } /** * @param expiration Expiration. */ public void expiration(long expiration) { this.expiration = expiration; } /** * @return Delta for increment and decrement commands. */ @Nullable public Long delta() { return delta; } /** * @param delta Delta for increment and decrement commands. */ public void delta(long delta) { this.delta = delta; } /** * @return Initial value for increment and decrement commands. */ @Nullable public Long initial() { return init; } /** * @param init Initial value for increment and decrement commands. */ public void initial(long init) { this.init = init; } /** * @return Cache name. */ @Nullable public String cacheName() { return cacheName; } /** * @param cacheName Cache name. */ public void cacheName(String cacheName) { assert cacheName != null; this.cacheName = cacheName; } /** * @return Whether request MUST have flags in extras. */ public boolean hasFlags() { return opCode == 0x01 || opCode == 0x02 || opCode == 0x03 || opCode == 0x11 || opCode == 0x12 || opCode == 0x13; } /** * @return Whether request has expiration field. */ public boolean hasExpiration() { return opCode == 0x01 || opCode == 0x02 || opCode == 0x03 || opCode == 0x11 || opCode == 0x12 || opCode == 0x13; } /** * @return Whether request has delta field. */ public boolean hasDelta() { return opCode == 0x05 || opCode == 0x06 || opCode == 0x15 || opCode == 0x16; } /** * @return Whether request has initial field. */ public boolean hasInitial() { return opCode == 0x05 || opCode == 0x06 || opCode == 0x15 || opCode == 0x16; } /** * @return Whether to add data to response. */ public boolean addData() { return opCode == 0x00 || opCode == 0x05 || opCode == 0x06 || opCode == 0x09 || opCode == 0x0B || opCode == 0x0C || opCode == 0x0D || opCode == 0x20 || opCode == 0x24 || opCode == 0x25 || opCode == 0x26 || opCode == 0x27 || opCode == 0x28 || opCode == 0x29; } /** * @return Whether to add flags to response. */ public boolean addFlags() { return opCode == 0x00 || opCode == 0x09 || opCode == 0x0C || opCode == 0x0D; } /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridMemcachedMessage.class, this); } }