| /* |
| * 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.geode.internal.cache.tier.sockets; |
| |
| import java.io.DataInput; |
| import java.io.DataOutput; |
| import java.io.IOException; |
| import java.io.ObjectInput; |
| import java.io.ObjectOutput; |
| |
| import org.apache.geode.DataSerializer; |
| import org.apache.geode.distributed.DistributedSystem; |
| import org.apache.geode.internal.DataSerializableFixedID; |
| import org.apache.geode.internal.Version; |
| import org.apache.geode.internal.cache.EventID; |
| import org.apache.geode.internal.cache.tier.InterestType; |
| import org.apache.geode.internal.cache.tier.MessageType; |
| |
| /** |
| * Class <code>ClientInterestMessageImpl</code> represents an update to the a client's interest |
| * registrations made by the server on behalf of the client. |
| * |
| * |
| * @since GemFire 5.6 |
| */ |
| public class ClientInterestMessageImpl implements ClientMessage { |
| |
| private static final long serialVersionUID = -797925585426839008L; |
| |
| /** |
| * This <code>ClientMessage</code>'s <code>EventID</code> |
| */ |
| private EventID eventId; |
| |
| /** |
| * This <code>ClientMessage</code>'s key |
| */ |
| private Object keyOfInterest; |
| |
| /** |
| * This <code>ClientMessage</code>'s region name |
| */ |
| private String regionName; |
| |
| /** |
| * Whether the interest represented by this <code>ClientMessage</code> is durable |
| */ |
| private boolean isDurable; |
| |
| /** |
| * Whether the create or update events for this <code>ClientMessage</code> is sent as an |
| * invalidate |
| * |
| * @since GemFire 6.0.3 |
| */ |
| private boolean forUpdatesAsInvalidates; |
| |
| /** |
| * This <code>ClientMessage</code>'s interest type (key or regex) |
| */ |
| private int interestType; |
| |
| /** |
| * This <code>ClientMessage</code>'s interest result policy (none, key, key-value) |
| */ |
| private byte interestResultPolicy; |
| |
| /** |
| * This <code>ClientMessage</code>'s action (add or remove interest) |
| */ |
| private byte action; |
| |
| /** |
| * A byte representing a register interest message |
| */ |
| protected static final byte REGISTER = (byte) 0; |
| |
| /** |
| * A byte representing an unregister interest message |
| */ |
| protected static final byte UNREGISTER = (byte) 1; |
| |
| /** |
| * |
| * @param eventId The EventID of this message |
| * @param regionName The name of the region whose interest is changing |
| * @param keyOfInterest The key in the region whose interest is changing |
| * @param action The action (add or remove interest) |
| */ |
| public ClientInterestMessageImpl(EventID eventId, String regionName, Object keyOfInterest, |
| int interestType, byte interestResultPolicy, boolean isDurable, |
| boolean sendUpdatesAsInvalidates, byte action) { |
| this.eventId = eventId; |
| this.regionName = regionName; |
| this.keyOfInterest = keyOfInterest; |
| this.interestType = interestType; |
| this.interestResultPolicy = interestResultPolicy; |
| this.isDurable = isDurable; |
| this.forUpdatesAsInvalidates = sendUpdatesAsInvalidates; |
| this.action = action; |
| } |
| |
| public ClientInterestMessageImpl(DistributedSystem distributedSystem, |
| ClientInterestMessageImpl message, Object keyOfInterest) { |
| this.eventId = new EventID(distributedSystem); |
| this.regionName = message.regionName; |
| this.keyOfInterest = keyOfInterest; |
| this.interestType = message.interestType; |
| this.interestResultPolicy = message.interestResultPolicy; |
| this.isDurable = message.isDurable; |
| this.forUpdatesAsInvalidates = message.forUpdatesAsInvalidates; |
| this.action = message.action; |
| } |
| |
| /** |
| * Default constructor. |
| */ |
| public ClientInterestMessageImpl() {} |
| |
| @Override |
| public Message getMessage(CacheClientProxy proxy, boolean notify) throws IOException { |
| Version clientVersion = proxy.getVersion(); |
| Message message = null; |
| if (clientVersion.compareTo(Version.GFE_57) >= 0) { |
| message = getGFEMessage(); |
| } else { |
| throw new IOException( |
| "Unsupported client version for server-to-client message creation: " + clientVersion); |
| } |
| |
| return message; |
| } |
| |
| protected Message getGFEMessage() throws IOException { |
| Message message = new Message(isRegister() ? 7 : 6, Version.CURRENT); |
| message.setTransactionId(0); |
| |
| // Set the message type |
| switch (this.action) { |
| case REGISTER: |
| message.setMessageType(MessageType.CLIENT_REGISTER_INTEREST); |
| break; |
| case UNREGISTER: |
| message.setMessageType(MessageType.CLIENT_UNREGISTER_INTEREST); |
| break; |
| default: |
| String s = "Unknown action: " + this.action; |
| throw new IOException(s); |
| } |
| |
| // Add the region name |
| message.addStringPart(this.regionName, true); |
| |
| // Add the key |
| message.addStringOrObjPart(this.keyOfInterest); |
| |
| // Add the interest type |
| message.addObjPart(Integer.valueOf(this.interestType)); |
| |
| // Add the interest result policy (if register interest) |
| if (isRegister()) { |
| message.addObjPart(Byte.valueOf(this.interestResultPolicy)); |
| } |
| |
| // Add the isDurable flag |
| message.addObjPart(Boolean.valueOf(this.isDurable)); |
| |
| // Add the forUpdatesAsInvalidates flag |
| message.addObjPart(Boolean.valueOf(this.forUpdatesAsInvalidates)); |
| |
| // Add the event id |
| message.addObjPart(this.eventId); |
| |
| return message; |
| } |
| |
| @Override |
| public boolean shouldBeConflated() { |
| return false; |
| } |
| |
| @Override |
| public int getDSFID() { |
| return DataSerializableFixedID.CLIENT_INTEREST_MESSAGE; |
| } |
| |
| public void writeExternal(ObjectOutput out) throws IOException { |
| toData(out); |
| } |
| |
| public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { |
| fromData(in); |
| } |
| |
| @Override |
| public void toData(DataOutput out) throws IOException { |
| DataSerializer.writeObject(this.eventId, out); |
| DataSerializer.writeString(this.regionName, out); |
| DataSerializer.writeObject(this.keyOfInterest, out); |
| DataSerializer.writePrimitiveBoolean(this.isDurable, out); |
| DataSerializer.writePrimitiveBoolean(this.forUpdatesAsInvalidates, out); |
| DataSerializer.writePrimitiveInt(this.interestType, out); |
| DataSerializer.writePrimitiveByte(this.interestResultPolicy, out); |
| DataSerializer.writePrimitiveByte(this.action, out); |
| } |
| |
| @Override |
| public void fromData(DataInput in) throws IOException, ClassNotFoundException { |
| this.eventId = (EventID) DataSerializer.readObject(in); |
| this.regionName = DataSerializer.readString(in); |
| this.keyOfInterest = DataSerializer.readObject(in); |
| this.isDurable = DataSerializer.readPrimitiveBoolean(in); |
| this.forUpdatesAsInvalidates = DataSerializer.readPrimitiveBoolean(in); |
| this.interestType = DataSerializer.readPrimitiveInt(in); |
| this.interestResultPolicy = DataSerializer.readPrimitiveByte(in); |
| this.action = DataSerializer.readPrimitiveByte(in); |
| } |
| |
| @Override |
| public EventID getEventId() { |
| return this.eventId; |
| } |
| |
| public String getRegionName() { |
| return this.regionName; |
| } |
| |
| public Object getKeyOfInterest() { |
| return this.keyOfInterest; |
| } |
| |
| public int getInterestType() { |
| return this.interestType; |
| } |
| |
| public byte getInterestResultPolicy() { |
| return this.interestResultPolicy; |
| } |
| |
| public boolean getIsDurable() { |
| return this.isDurable; |
| } |
| |
| public boolean getForUpdatesAsInvalidates() { |
| return this.forUpdatesAsInvalidates; |
| } |
| |
| public boolean isKeyInterest() { |
| return this.interestType == InterestType.KEY; |
| } |
| |
| public boolean isRegister() { |
| return this.action == REGISTER; |
| } |
| |
| @Override |
| public String getRegionToConflate() { |
| return null; |
| } |
| |
| @Override |
| public Object getKeyToConflate() { |
| // This method can be called by HARegionQueue. |
| // Use this to identify the message type. |
| return "interest"; |
| } |
| |
| @Override |
| public Object getValueToConflate() { |
| // This method can be called by HARegionQueue |
| // Use this to identify the message type. |
| return "interest"; |
| } |
| |
| @Override |
| public void setLatestValue(Object value) {} |
| |
| public String toString() { |
| return new StringBuilder().append(getClass().getSimpleName()).append("[").append("eventId=") |
| .append(this.eventId).append("; regionName=").append(this.regionName) |
| .append("; keyOfInterest=").append(this.keyOfInterest).append("; isDurable=") |
| .append(this.isDurable).append("; forUpdatesAsInvalidates=") |
| .append(this.forUpdatesAsInvalidates).append("; interestType=").append(this.interestType) |
| .append("; interestResultPolicy=").append(this.interestResultPolicy).append("; action=") |
| .append(this.action).append("]").toString(); |
| } |
| |
| @Override |
| public Version[] getSerializationVersions() { |
| return null; |
| } |
| } |