com.gemstone.gemfire.cache.MembershipAttributes Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gemfire-core Show documentation
Show all versions of gemfire-core Show documentation
SnappyData store based off Pivotal GemFireXD
/*
* 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.cache;
import com.gemstone.gemfire.DataSerializable;
import com.gemstone.gemfire.DataSerializer;
import com.gemstone.gemfire.distributed.internal.membership.InternalRole;
import com.gemstone.gemfire.distributed.Role;
import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
import java.io.*;
import java.util.*;
/**
* Configuration attributes for defining reliability requirements and behavior
* for a Region
.
*
* MembershipAttributes
provides options for configuring a
* Region
to require one or more membership roles to be present
* in the system for reliable access to the Region
. Each
* {@link Role} is a user defined string name, such as Producer or Backup or
* FooProducer.
*
* The {@link LossAction} defines the behavior when one or
* more required roles are missing.
*
* The {@link ResumptionAction} specifies the action to be taken when
* reliability resumes.
*
* MembershipAttributes
have no effect unless one or more
* required roles are specified. These attributes are immutable after the
* Region
has been created.
*
* @author Kirk Lund
* @since 5.0
*/
public class MembershipAttributes implements DataSerializable, Externalizable {
/**
* Array of required role names by this process for reliable access to the
* region
*/
private /*final*/ Set requiredRoles;
/**
* The configuration defining how this process behaves when there are
* missing required roles
*/
private /*final*/ LossAction lossAction;
/**
* The action to take when missing required roles return to the system
*/
private /*final*/ ResumptionAction resumptionAction;
/**
* Creates a new MembershipAttributes
with the default
* configuration of no required roles.
*/
public MembershipAttributes() {
this.requiredRoles = Collections.emptySet();
this.lossAction = LossAction.FULL_ACCESS;
this.resumptionAction = ResumptionAction.NONE;
}
/**
* Creates a new MembershipAttributes
with the specified
* required role names. Reliability policy will default to {@linkplain
* LossAction#NO_ACCESS NO_ACCESS}, and resumption action will
* default to {@linkplain ResumptionAction#REINITIALIZE REINITIALIZE}.
*
* @param requiredRoles
* array of role names required by this process for reliable access to
* the region
* @throws IllegalArgumentException
* if no requiredRoles are specified
*/
public MembershipAttributes(String[] requiredRoles){
this(requiredRoles, LossAction.NO_ACCESS, ResumptionAction.REINITIALIZE);
}
/**
* Creates a new MembershipAttributes
with the specified
* required role names, reliability policy, and resumption action.
*
* @param requiredRoles
* array of role names required by this process for reliable access to
* the region
* @param lossAction
* the configuration defining how this process behaves when there are
* missing required roles
* @param resumptionAction
* the action to take when missing required roles return to the system
* @throws IllegalArgumentException
* if the resumptionAction is incompatible with the lossAction
* or if no requiredRoles are specified
*/
public MembershipAttributes(String[] requiredRoles,
LossAction lossAction,
ResumptionAction resumptionAction) {
this.requiredRoles = toRoleSet(requiredRoles);
if (this.requiredRoles.isEmpty()) {
throw new IllegalArgumentException(LocalizedStrings.MembershipAttributes_ONE_OR_MORE_REQUIRED_ROLES_MUST_BE_SPECIFIED.toLocalizedString());
}
this.lossAction = lossAction;
this.resumptionAction = resumptionAction;
}
/**
* Returns the set of {@linkplain com.gemstone.gemfire.distributed.Role
* Role}s that are required for the reliability of this region.
*/
public Set getRequiredRoles() {
return Collections.unmodifiableSet(this.requiredRoles);
}
/**
* Returns true if there are one or more required roles specified.
*/
public boolean hasRequiredRoles() {
return !this.requiredRoles.isEmpty();
}
/**
* Returns the reliability policy that describes behavior if any required
* roles are missing.
*/
public LossAction getLossAction() {
return this.lossAction;
}
/**
* Returns the resumption action that describes behavior when
*/
public ResumptionAction getResumptionAction() {
return this.resumptionAction;
}
private final Set toRoleSet(String[] roleNames) {
if (roleNames == null || roleNames.length == 0) {
return Collections.emptySet();
}
Set roleSet = new HashSet();
for (int i = 0; i < roleNames.length; i++) {
roleSet.add(InternalRole.getRole(roleNames[i]));
}
return roleSet;
}
/**
* Indicates whether some other object is "equal to" this one.
*
* @param other the reference object with which to compare.
* @return true if this object is the same as the obj argument;
* false otherwise.
*/
@Override
public boolean equals(Object other) {
if (other == this) return true;
if (other == null) return false;
if (!(other instanceof MembershipAttributes)) return false;
final MembershipAttributes that = (MembershipAttributes) other;
if (this.requiredRoles != that.requiredRoles &&
!(this.requiredRoles != null &&
this.requiredRoles.equals(that.requiredRoles))) return false;
if (this.lossAction != that.lossAction &&
!(this.lossAction != null &&
this.lossAction.equals(that.lossAction))) return false;
if (this.resumptionAction != that.resumptionAction &&
!(this.resumptionAction != null &&
this.resumptionAction.equals(that.resumptionAction))) return false;
return true;
}
/**
* Returns a hash code for the object. This method is supported for the
* benefit of hashtables such as those provided by java.util.Hashtable.
*
* @return the integer 0 if description is null; otherwise a unique integer.
*/
@Override
public int hashCode() {
int result = 17;
final int mult = 37;
result = mult * result +
(this.requiredRoles == null ? 0 : this.requiredRoles.hashCode());
result = mult * result +
(this.lossAction == null ? 0 : this.lossAction.hashCode());
result = mult * result +
(this.resumptionAction == null ? 0 : this.resumptionAction.hashCode());
return result;
}
/**
* Returns a string representation of the object.
*
* @return a string representation of the object
*/
@Override
public String toString() {
if (!hasRequiredRoles()) {
return "RequiredRoles(none)";
}
else {
final StringBuffer sb = new StringBuffer();
sb.append("RequiredRoles(");
boolean comma = false;
for (Iterator iter = this.requiredRoles.iterator(); iter.hasNext();) {
if (comma) sb.append(",");
Role role = iter.next();
sb.append(role.getName());
comma = true;
}
sb.append("); Policy:");
sb.append(this.lossAction.toString());
sb.append("; Action:");
sb.append(this.resumptionAction.toString());
return sb.toString();
}
}
public void toData(DataOutput out) throws IOException {
String[] names = new String[this.requiredRoles.size()];
Iterator iter = this.requiredRoles.iterator();
for (int i = 0; i < names.length; i++) {
names[i] = iter.next().getName();
}
DataSerializer.writeStringArray(names, out);
out.writeByte(this.lossAction.ordinal);
out.writeByte(this.resumptionAction.ordinal);
}
public void fromData(DataInput in)
throws IOException, ClassNotFoundException {
this.requiredRoles = toRoleSet(DataSerializer.readStringArray(in));
this.lossAction = LossAction.fromOrdinal(in.readByte());
this.resumptionAction = ResumptionAction.fromOrdinal(in.readByte());
}
public void writeExternal(ObjectOutput out) throws IOException {
// added to fix bug 36619
toData(out);
}
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException {
// added to fix bug 36619
fromData(in);
}
}