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

com.gemstone.gemfire.internal.cache.tier.sockets.ClientTombstoneMessage Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
 *
 * Licensed 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. See accompanying
 * LICENSE file.
 */
package com.gemstone.gemfire.internal.cache.tier.sockets;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Map;
import java.util.Set;

import com.gemstone.gemfire.DataSerializer;
import com.gemstone.gemfire.distributed.DistributedSystem;
import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
import com.gemstone.gemfire.internal.cache.EnumListenerEvent;
import com.gemstone.gemfire.internal.cache.EventID;
import com.gemstone.gemfire.internal.cache.LocalRegion;
import com.gemstone.gemfire.internal.cache.tier.Acceptor;
import com.gemstone.gemfire.internal.cache.tier.MessageType;
import com.gemstone.gemfire.internal.cache.versions.VersionSource;
import com.gemstone.gemfire.internal.shared.Version;
/**
 * 
 * @author bruce schuchardt
 *
 */
public class ClientTombstoneMessage  extends ClientUpdateMessageImpl{
  
  enum TOperation {
    GC, GC_PR
  }
  
  private Object removalInformation;
  private TOperation op;

  /** GC operation for non-partitioned regions */
  public static ClientTombstoneMessage gc(LocalRegion region,
      Map regionGCVersions, EventID eventId) {
    return new ClientTombstoneMessage(TOperation.GC, region, regionGCVersions, eventId);
  }
  
  /** GC operation for partitioned regions */
  public static ClientTombstoneMessage gc(LocalRegion region,
      Set removedKeys, EventID eventId) {
    return new ClientTombstoneMessage(TOperation.GC_PR, region, removedKeys, eventId);
  }
  
  private ClientTombstoneMessage(TOperation op, LocalRegion region,
      Object removalInformation, EventID eventId) {
    super(EnumListenerEvent.AFTER_TOMBSTONE_EXPIRATION, null, eventId, region.getLogWriterI18n());
    this.op = op;
    this.removalInformation = removalInformation;
    setRegionName(region.getFullPath()); // fix for bug #45962 - tombstone message must have the region name
  }

  /**
   * default constructor
   */
  public ClientTombstoneMessage() {
  }

  @Override
  public boolean shouldBeConflated()
  {
    return false;
  }
  
  /*
   * Returns a Message generated from the fields of this
   * ClientTombstoneMessage.
   */
  @Override
  protected Message getMessage(CacheClientProxy proxy, byte[] latestValue)
    throws IOException {
    if (Version.GFE_70.compareTo(proxy.getVersion()) <= 0) {
      return getGFE70Message(proxy.getVersion());
    }
    else {
      return null;
    }
  }

  protected Message getGFE70Message(Version clientVersion) {
    Message message = null;

    // The format:
    // part  0: operation (gc=0)
    // part  1: region name
    // part  2: operation ordinal
    // part  3: regionGCVersions
    // Last part: event ID
    int numParts = 4;
    message = new Message(numParts, clientVersion);
    // Set message type
    message.setMessageType(MessageType.TOMBSTONE_OPERATION);
    message.addStringPart(this.getRegionName());
    message.addIntPart(this.op.ordinal());
    message.addObjPart(this.removalInformation);
    message.addObjPart(getEventId());
    return message;
  }

  @Override
  public int getDSFID() {
    return CLIENT_TOMBSTONE_MESSAGE;
  }

  @Override
  public void toData(DataOutput out) throws IOException {
    
    out.writeByte(op.ordinal());
    out.writeByte(_operation.getEventCode());
    DataSerializer.writeString(getRegionName(), out);
    DataSerializer.writeObject(this.removalInformation, out);
    DataSerializer.writeObject(this._membershipId, out);
    DataSerializer.writeObject(this._eventIdentifier, out);
  }

  @Override
  public void fromData(DataInput in) throws IOException, ClassNotFoundException
  {
    // note: does not call super.fromData() since there are no keys, etc.
    // The message class hierarchy should be revised to have a more abstract
    // top-level class.
    this.op = TOperation.values()[in.readByte()];
    this._operation = EnumListenerEvent.getEnumListenerEvent(in.readByte());
    this.setRegionName(DataSerializer.readString(in));
    this.removalInformation = DataSerializer.readObject(in);
    this._membershipId = ClientProxyMembershipID.readCanonicalized(in);
    this._eventIdentifier = (EventID)DataSerializer.readObject(in);
    DistributedSystem ds = InternalDistributedSystem.getAnyInstance();
    if (ds != null) {
      this._logger = ds.getLogWriter().convertToLogWriterI18n();
    }
  }

  @Override
  public Object getKeyToConflate()
  {
    return null;
  }

  @Override
  public String getRegionToConflate()
  {
    return null;
  }

  @Override
  public Object getValueToConflate()
  {
    return null;
  }

  @Override
  public void setLatestValue(Object value)
  {
  }

  @Override
  public boolean isClientInterested(ClientProxyMembershipID clientId) {
    return Acceptor.VERSION.compareTo(Version.GFE_70) >= 0;
  }

  @Override
  public boolean needsNoAuthorizationCheck() {
    return true;
  }

  @Override
  public String toString()
  {
    StringBuffer buffer = new StringBuffer();
    buffer.append("ClientTombstoneMessage[op=").append(this.op)
      .append(";region=").append(getRegionName())
      .append(";removalInfo=").append(this.removalInformation)
      .append(";memberId=").append(getMembershipId())
      .append(";eventId=").append(getEventId()).append("]");
    return buffer.toString();
  }
}