http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b6c305f8/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/ManagedSystemMemberImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/ManagedSystemMemberImpl.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/ManagedSystemMemberImpl.java new file mode 100644 index 0000000..abc6d01 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/ManagedSystemMemberImpl.java @@ -0,0 +1,258 @@ +/* + * 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.admin.api.impl; + +import org.apache.geode.internal.admin.api.AdminException; +import org.apache.geode.internal.admin.api.ConfigurationParameter; +import org.apache.geode.internal.admin.api.ManagedEntityConfig; +import org.apache.geode.internal.admin.GemFireVM; + +import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS; + +/** + * A <code>SystemMember</code> that is also managed (or manageable) by the admin API. + * + * This class must be public so that its methods can be invoked reflectively (for MBean operations) + * on instances of its subclasses. + * + * @since GemFire 4.0 + */ +public abstract class ManagedSystemMemberImpl extends SystemMemberImpl + implements InternalManagedEntity { + + /** Controller for starting and stopping local or remote managers */ + protected ManagedEntityController controller; + + /** The state of this managed entity (see bug 32455) */ + private int state = UNKNOWN; + + /** A lock that is obtained while this entity's state changes */ + private final Object stateChange = new Object(); + + ////////////////////// Constructors ////////////////////// + + /** + * Creates a new <code>ManagedSystemMemberImpl</code> that represents an existing member of an + * <code>AdminDistributedSystem</code>. + */ + protected ManagedSystemMemberImpl(AdminDistributedSystemImpl system, GemFireVM vm) + throws AdminException { + + super(system, vm); + this.controller = system.getEntityController(); + } + + /** + * Creates a new <code>ManagedSystemMemberImpl</code> that represents a non-existing member with + * the given <code>ManagedEntityConfig</code> that has not yet been started. + */ + protected ManagedSystemMemberImpl(AdminDistributedSystemImpl system, ManagedEntityConfig config) + throws AdminException { + + super(system); + this.internalId = null; + this.id = getNewId(); + this.host = config.getHost(); + this.name = this.id; + this.controller = system.getEntityController(); + } + + ////////////////////// Instance Methods ////////////////////// + + public String getWorkingDirectory() { + return this.getEntityConfig().getWorkingDirectory(); + } + + public void setWorkingDirectory(String workingDirectory) { + this.getEntityConfig().setWorkingDirectory(workingDirectory); + } + + public String getProductDirectory() { + return this.getEntityConfig().getProductDirectory(); + } + + public void setProductDirectory(String productDirectory) { + this.getEntityConfig().setProductDirectory(productDirectory); + } + + @Override + public String getHost() { + return this.getEntityConfig().getHost(); + } + + public int setState(int state) { + if (this.stateChange == null) { + // The initial state is set in the constructor before + // stateChange is initialized. + int oldState = this.state; + this.state = state; + return oldState; + + } else { + synchronized (this.stateChange) { + int oldState = this.state; + this.state = state; + + this.stateChange.notifyAll(); + + return oldState; + } + } + } + + /** + * Returns whether or not this managed system member needs to be stopped. If this member is + * stopped or is stopping, then it does not need to be stopped. Otherwise, it will atomically + * place this member in the {@link #STOPPING} state. See bug 32455. + */ + protected boolean needToStop() { + synchronized (this.stateChange) { + if (this.state == STOPPED || this.state == STOPPING) { + return false; + + } else { + setState(STOPPING); + return true; + } + } + } + + /** + * Returns whether or not this managed system member needs to be started. If this member is + * started or is starting, then it does not need to be started. Otherwise, it will atomically + * place this member in the {@link #STARTING} state. See bug 32455. + */ + protected boolean needToStart() { + synchronized (this.stateChange) { + if (this.state == RUNNING || this.state == STARTING) { + return false; + + } else { + setState(STARTING); + return true; + } + } + } + + /** + * Sets the state of this managed system member depending on whether or not <code>vm</code> is + * <code>null</code>. + */ + @Override + void setGemFireVM(GemFireVM vm) throws AdminException { + super.setGemFireVM(vm); + if (vm != null) { + this.setState(RUNNING); + + } else { + this.setState(STOPPED); + } + } + + /** + * Waits until this system member's "state" is {@link #RUNNING}. + */ + public boolean waitToStart(long timeout) throws InterruptedException { + + if (Thread.interrupted()) + throw new InterruptedException(); + + long start = System.currentTimeMillis(); + while (System.currentTimeMillis() - start < timeout) { + synchronized (this.stateChange) { + if (this.state == RUNNING) { + break; + + } else { + this.stateChange.wait(System.currentTimeMillis() - start); + } + } + } + + synchronized (this.stateChange) { + return this.state == RUNNING; + } + } + + /** + * Waits until this system member's "state" is {@link #STOPPED}. + */ + public boolean waitToStop(long timeout) throws InterruptedException { + + if (Thread.interrupted()) + throw new InterruptedException(); + long start = System.currentTimeMillis(); + while (System.currentTimeMillis() - start < timeout) { + synchronized (this.stateChange) { + if (this.state == STOPPED) { + break; + + } else { + this.stateChange.wait(System.currentTimeMillis() - start); + } + } + } + + synchronized (this.stateChange) { + return this.state == STOPPED; + } + } + + /** + * Appends configuration information to a <code>StringBuffer</code> that contains a command line. + * Handles certain configuration parameters specially. + */ + protected void appendConfiguration(StringBuffer sb) { + ConfigurationParameter[] params = this.getConfiguration(); + for (int i = 0; i < params.length; i++) { + ConfigurationParameter param = params[i]; + + if (!param.isModifiable()) { + continue; + } + + String name = param.getName(); + String value = param.getValueAsString(); + + if (value != null && !value.equals("")) { + if (name.equals(LOCATORS)) { + // Use the new locator syntax so that is plays nicely with + // rsh. See bug 32306. + String locator = value; + int firstBracket = locator.indexOf('['); + int lastBracket = locator.indexOf(']'); + + if (firstBracket > -1 && lastBracket > -1) { + String host = locator.substring(0, firstBracket); + String port = locator.substring(firstBracket + 1, lastBracket); + locator = host + ":" + port; + } + + sb.append(" "); + sb.append(name); + sb.append("="); + sb.append(locator); + + } else { + sb.append(" "); + sb.append(name); + sb.append("="); + sb.append(value); + } + } + } + } + +}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b6c305f8/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/MemberHealthConfigImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/MemberHealthConfigImpl.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/MemberHealthConfigImpl.java new file mode 100644 index 0000000..2f2334d --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/MemberHealthConfigImpl.java @@ -0,0 +1,95 @@ +/* + * 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.admin.api.impl; + +import org.apache.geode.internal.admin.api.MemberHealthConfig; + +// @todo Make this class (and all of its subclasses) {@link java.io.Externalizable} or +// {@link org.apache.geode.DataSerializable}. +/** + * The implementation of <code>MemberHealthConfig</code> + * + * + * @since GemFire 3.5 + */ +public abstract class MemberHealthConfigImpl implements MemberHealthConfig, java.io.Serializable { + + private static final long serialVersionUID = 3966032573073580490L; + + /** + * The maximum process size (in megabytes) of a healthy member of the distributed system. + */ + private long maxVMProcessSize = DEFAULT_MAX_VM_PROCESS_SIZE; + + /** + * The maximum number of enqueued incoming or outgoing messages that a healthy member of a + * distributed system can have. + */ + private long maxMessageQueueSize = DEFAULT_MAX_MESSAGE_QUEUE_SIZE; + + /** + * The maximum number message replies that can timeout in a healthy member. + */ + private long maxReplyTimeouts = DEFAULT_MAX_REPLY_TIMEOUTS; + + /** + * The maximum multicast retransmit / multicast message count ratio + */ + private double maxRetransmissionRatio = DEFAULT_MAX_RETRANSMISSION_RATIO; + + + /////////////////////// Constructors /////////////////////// + + /** + * Creates a new <code>MemberHealthConfigImpl</code> with the default configuration. + */ + MemberHealthConfigImpl() { + + } + + ///////////////////// Instance Methods ////////////////////// + + public long getMaxVMProcessSize() { + return this.maxVMProcessSize; + } + + public void setMaxVMProcessSize(long size) { + this.maxVMProcessSize = size; + } + + public long getMaxMessageQueueSize() { + return this.maxMessageQueueSize; + } + + public void setMaxMessageQueueSize(long maxMessageQueueSize) { + this.maxMessageQueueSize = maxMessageQueueSize; + } + + public long getMaxReplyTimeouts() { + return this.maxReplyTimeouts; + } + + public void setMaxReplyTimeouts(long maxReplyTimeouts) { + this.maxReplyTimeouts = maxReplyTimeouts; + } + + public double getMaxRetransmissionRatio() { + return this.maxRetransmissionRatio; + } + + public void setMaxRetransmissionRatio(double ratio) { + this.maxRetransmissionRatio = ratio; + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b6c305f8/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/MemberHealthEvaluator.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/MemberHealthEvaluator.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/MemberHealthEvaluator.java new file mode 100644 index 0000000..11fc8f4 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/MemberHealthEvaluator.java @@ -0,0 +1,248 @@ +/* + * 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.admin.api.impl; + +import org.apache.geode.CancelException; +import org.apache.geode.cache.CacheFactory; +import org.apache.geode.distributed.internal.*; +import org.apache.geode.internal.*; +import org.apache.geode.internal.admin.api.GemFireHealthConfig; +import org.apache.geode.internal.admin.api.MemberHealthConfig; +import org.apache.geode.internal.i18n.LocalizedStrings; +import org.apache.geode.internal.cache.CachePerfStats; +import org.apache.geode.internal.cache.GemFireCacheImpl; +import org.apache.geode.internal.statistics.GemFireStatSampler; +import org.apache.geode.internal.statistics.platform.ProcessStats; + +import java.util.*; + +/** + * Contains the logic for evaluating the health of a GemFire distributed system member according to + * the thresholds provided in a {@link MemberHealthConfig}. + * + * @see VMStats + * @see ProcessStats + * @see DMStats + * + * + * @since GemFire 3.5 + */ +/** + * + */ +class MemberHealthEvaluator extends AbstractHealthEvaluator { + + /** The config from which we get the evaluation criteria */ + private MemberHealthConfig config; + + /** The description of the member being evaluated */ + private String description; + + // /** Statistics about this VM (may be null) */ + // private VMStatsContract vmStats; + + /** Statistics about this process (may be null) */ + private ProcessStats processStats; + + /** Statistics about the distribution manager */ + private DMStats dmStats; + + /** The previous value of the reply timeouts stat */ + private long prevReplyTimeouts; + + ////////////////////// Constructors ////////////////////// + + /** + * Creates a new <code>MemberHealthEvaluator</code> + */ + MemberHealthEvaluator(GemFireHealthConfig config, DM dm) { + super(config, dm); + + this.config = config; + InternalDistributedSystem system = dm.getSystem(); + + GemFireStatSampler sampler = system.getStatSampler(); + if (sampler != null) { + // Sampling is enabled + // this.vmStats = sampler.getVMStats(); + this.processStats = sampler.getProcessStats(); + } + + this.dmStats = dm.getStats(); + + StringBuffer sb = new StringBuffer(); + sb.append("Application VM member "); + sb.append(dm.getId()); + int pid = OSProcess.getId(); + if (pid != 0) { + sb.append(" with pid "); + sb.append(pid); + } + this.description = sb.toString(); + } + + //////////////////// Instance Methods //////////////////// + + @Override + protected String getDescription() { + return this.description; + } + + /** + * Checks to make sure that the {@linkplain ProcessStats#getProcessSize VM's process size} is less + * than the {@linkplain MemberHealthConfig#getMaxVMProcessSize threshold}. If not, the status is + * "okay" health. + */ + void checkVMProcessSize(List status) { + // There is no need to check isFirstEvaluation() + if (this.processStats == null) { + return; + } + + long vmSize = this.processStats.getProcessSize(); + long threshold = this.config.getMaxVMProcessSize(); + if (vmSize > threshold) { + String s = + LocalizedStrings.MemberHealthEvaluator_THE_SIZE_OF_THIS_VM_0_MEGABYTES_EXCEEDS_THE_THRESHOLD_1_MEGABYTES + .toLocalizedString(new Object[] {Long.valueOf(vmSize), Long.valueOf(threshold)}); + status.add(okayHealth(s)); + } + } + + /** + * Checks to make sure that the size of the distribution manager's + * {@linkplain DMStats#getOverflowQueueSize() overflow} message queue does not exceed the + * {@linkplain MemberHealthConfig#getMaxMessageQueueSize threshold}. If not, the status is "okay" + * health. + */ + void checkMessageQueueSize(List status) { + long threshold = this.config.getMaxMessageQueueSize(); + long overflowSize = this.dmStats.getOverflowQueueSize(); + if (overflowSize > threshold) { + String s = + LocalizedStrings.MemberHealthEvaluator_THE_SIZE_OF_THE_OVERFLOW_QUEUE_0_EXCEEDS_THE_THRESHOLD_1 + .toLocalizedString( + new Object[] {Long.valueOf(overflowSize), Long.valueOf(threshold)}); + status.add(okayHealth(s)); + } + } + + /** + * Checks to make sure that the number of {@linkplain DMStats#getReplyTimeouts reply timeouts} + * does not exceed the {@linkplain MemberHealthConfig#getMaxReplyTimeouts threshold}. If not, the + * status is "okay" health. + */ + void checkReplyTimeouts(List status) { + if (isFirstEvaluation()) { + return; + } + + long threshold = this.config.getMaxReplyTimeouts(); + long deltaReplyTimeouts = this.dmStats.getReplyTimeouts() - prevReplyTimeouts; + if (deltaReplyTimeouts > threshold) { + String s = + LocalizedStrings.MemberHealthEvaluator_THE_NUMBER_OF_MESSAGE_REPLY_TIMEOUTS_0_EXCEEDS_THE_THRESHOLD_1 + .toLocalizedString( + new Object[] {Long.valueOf(deltaReplyTimeouts), Long.valueOf(threshold)}); + status.add(okayHealth(s)); + } + } + + /** + * See if the multicast retransmission ratio is okay + */ + void checkRetransmissionRatio(List status) { + double threshold = this.config.getMaxRetransmissionRatio(); + int mcastMessages = this.dmStats.getMcastWrites(); + if (mcastMessages > 100000) { // avoid initial state & int overflow + // the ratio we actually use here is (retransmit requests) / (mcast datagram writes) + // a single retransmit request may include multiple missed messages + double ratio = + (this.dmStats.getMcastRetransmits() * 1.0) / (this.dmStats.getMcastWrites() * 1.0); + if (ratio > threshold) { + String s = "The number of message retransmissions (" + ratio + ") exceeds the threshold (" + + threshold + ")"; + status.add(okayHealth(s)); + } + } + } + + /** + * The function keeps updating the health of the cache based on roles required by the regions and + * their reliablity policies. + * + */ + + void checkCacheRequiredRolesMeet(List status) { + // will have to call here okeyHealth() or poorHealth() + // GemFireCache cache = (GemFireCache)CacheFactory.getAnyInstance(); + + // CachePerfStats cPStats= null; + try { + GemFireCacheImpl cache = (GemFireCacheImpl) CacheFactory.getAnyInstance(); + CachePerfStats cPStats = null; + cPStats = cache.getCachePerfStats(); + + if (cPStats.getReliableRegionsMissingFullAccess() > 0) { + // health is okay. + int numRegions = cPStats.getReliableRegionsMissingFullAccess(); + status.add(okayHealth( + LocalizedStrings.MemberHealthEvaluator_THERE_ARE_0_REGIONS_MISSING_REQUIRED_ROLES_BUT_ARE_CONFIGURED_FOR_FULL_ACCESS + .toLocalizedString(Integer.valueOf(numRegions)))); + } else if (cPStats.getReliableRegionsMissingLimitedAccess() > 0) { + // health is poor + int numRegions = cPStats.getReliableRegionsMissingLimitedAccess(); + status.add(poorHealth( + LocalizedStrings.MemberHealthEvaluator_THERE_ARE_0_REGIONS_MISSING_REQUIRED_ROLES_AND_CONFIGURED_WITH_LIMITED_ACCESS + .toLocalizedString(Integer.valueOf(numRegions)))); + } else if (cPStats.getReliableRegionsMissingNoAccess() > 0) { + // health is poor + int numRegions = cPStats.getReliableRegionsMissingNoAccess(); + status.add(poorHealth( + LocalizedStrings.MemberHealthEvaluator_THERE_ARE_0_REGIONS_MISSING_REQUIRED_ROLES_AND_CONFIGURED_WITHOUT_ACCESS + .toLocalizedString(Integer.valueOf(numRegions)))); + } // else{ + // health is good/okay + // status.add(okayHealth("All regions have there required roles meet")); + // } + } catch (CancelException ignore) { + } + } + + + /** + * Updates the previous values of statistics + */ + private void updatePrevious() { + this.prevReplyTimeouts = this.dmStats.getReplyTimeouts(); + } + + @Override + protected void check(List status) { + checkVMProcessSize(status); + checkMessageQueueSize(status); + checkReplyTimeouts(status); + // will have to add another call to check for roles + // missing and reliablity attributed. + checkCacheRequiredRolesMeet(status); + + updatePrevious(); + } + + @Override + void close() { + + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b6c305f8/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/PrepareBackupRequest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/PrepareBackupRequest.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/PrepareBackupRequest.java new file mode 100644 index 0000000..a394d50 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/PrepareBackupRequest.java @@ -0,0 +1,133 @@ +/* + * 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.admin.api.impl; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.logging.log4j.Logger; + +import org.apache.geode.CancelException; +import org.apache.geode.cache.persistence.PersistentID; +import org.apache.geode.distributed.DistributedMember; +import org.apache.geode.distributed.internal.DM; +import org.apache.geode.distributed.internal.DistributionManager; +import org.apache.geode.distributed.internal.DistributionMessage; +import org.apache.geode.distributed.internal.ReplyException; +import org.apache.geode.internal.admin.remote.AdminFailureResponse; +import org.apache.geode.internal.admin.remote.AdminMultipleReplyProcessor; +import org.apache.geode.internal.admin.remote.AdminResponse; +import org.apache.geode.internal.admin.remote.CliLegacyMessage; +import org.apache.geode.internal.cache.GemFireCacheImpl; +import org.apache.geode.internal.cache.persistence.BackupManager; +import org.apache.geode.internal.i18n.LocalizedStrings; +import org.apache.geode.internal.logging.LogService; +import org.apache.geode.internal.logging.log4j.LocalizedMessage; + +/** + * A request to from an admin VM to all non admin members to start a backup. In the prepare phase of + * the backup, the members will suspend bucket destroys to make sure buckets aren't missed during + * the backup. + * + * + */ +public class PrepareBackupRequest extends CliLegacyMessage { + private static final Logger logger = LogService.getLogger(); + + public PrepareBackupRequest() { + + } + + public static Map<DistributedMember, Set<PersistentID>> send(DM dm, Set recipients) { + PrepareBackupRequest request = new PrepareBackupRequest(); + request.setRecipients(recipients); + + PrepareBackupReplyProcessor replyProcessor = new PrepareBackupReplyProcessor(dm, recipients); + request.msgId = replyProcessor.getProcessorId(); + dm.putOutgoing(request); + try { + replyProcessor.waitForReplies(); + } catch (ReplyException e) { + if (!(e.getCause() instanceof CancelException)) { + throw e; + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + AdminResponse response = request.createResponse((DistributionManager) dm); + response.setSender(dm.getDistributionManagerId()); + replyProcessor.process(response); + return replyProcessor.results; + } + + @Override + protected AdminResponse createResponse(DistributionManager dm) { + GemFireCacheImpl cache = GemFireCacheImpl.getInstance(); + HashSet<PersistentID> persistentIds; + if (cache == null) { + persistentIds = new HashSet<PersistentID>(); + } else { + try { + BackupManager manager = cache.startBackup(getSender()); + persistentIds = manager.prepareBackup(); + } catch (IOException e) { + logger.error( + LocalizedMessage.create(LocalizedStrings.CliLegacyMessage_ERROR, this.getClass()), e); + return AdminFailureResponse.create(dm, getSender(), e); + } + } + + + return new PrepareBackupResponse(this.getSender(), persistentIds); + } + + public int getDSFID() { + return PREPARE_BACKUP_REQUEST; + } + + private static class PrepareBackupReplyProcessor extends AdminMultipleReplyProcessor { + Map<DistributedMember, Set<PersistentID>> results = + Collections.synchronizedMap(new HashMap<DistributedMember, Set<PersistentID>>()); + + public PrepareBackupReplyProcessor(DM dm, Collection initMembers) { + super(dm, initMembers); + } + + @Override + protected boolean stopBecauseOfExceptions() { + return false; + } + + @Override + protected void process(DistributionMessage msg, boolean warn) { + if (msg instanceof PrepareBackupResponse) { + final HashSet<PersistentID> persistentIds = + ((PrepareBackupResponse) msg).getPersistentIds(); + if (persistentIds != null && !persistentIds.isEmpty()) { + results.put(msg.getSender(), persistentIds); + } + } + super.process(msg, warn); + } + + + + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b6c305f8/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/PrepareBackupResponse.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/PrepareBackupResponse.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/PrepareBackupResponse.java new file mode 100644 index 0000000..5e68179 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/PrepareBackupResponse.java @@ -0,0 +1,80 @@ +/* + * 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.admin.api.impl; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.HashSet; + +import org.apache.geode.DataSerializer; +import org.apache.geode.cache.persistence.PersistentID; +import org.apache.geode.distributed.internal.membership.InternalDistributedMember; +import org.apache.geode.internal.admin.remote.AdminResponse; + +/** + * The response to the {@link PrepareBackupRequest} + * + * + */ +public class PrepareBackupResponse extends AdminResponse { + + private HashSet<PersistentID> persistentIds; + + public PrepareBackupResponse() { + super(); + } + + public PrepareBackupResponse(InternalDistributedMember sender, + HashSet<PersistentID> persistentIds) { + this.setRecipient(sender); + this.persistentIds = persistentIds; + } + + public HashSet<PersistentID> getPersistentIds() { + return persistentIds; + } + + @Override + public void fromData(DataInput in) throws IOException, ClassNotFoundException { + super.fromData(in); + persistentIds = DataSerializer.readHashSet(in); + } + + + + @Override + public void toData(DataOutput out) throws IOException { + super.toData(out); + DataSerializer.writeHashSet(persistentIds, out); + } + + + + @Override + protected Object clone() throws CloneNotSupportedException { + // TODO Auto-generated method stub + return super.clone(); + } + + public int getDSFID() { + return PREPARE_BACKUP_RESPONSE; + } + + @Override + public String toString() { + return getClass().getName() + ": " + persistentIds; + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b6c305f8/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/StatisticImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/StatisticImpl.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/StatisticImpl.java new file mode 100755 index 0000000..d9ce318 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/StatisticImpl.java @@ -0,0 +1,93 @@ +/* + * 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.admin.api.impl; + +import org.apache.geode.internal.admin.Stat; +import org.apache.geode.internal.admin.api.Statistic; + +/** + * Implementation of a single statistic in a <code>StatisticResource</code> + * + * @since GemFire 3.5 + * + */ +public class StatisticImpl implements Statistic { + + private static final long serialVersionUID = 3899296873901634399L; + + private Stat internalStat; + + protected StatisticImpl() {} + + protected StatisticImpl(Stat internalStat) { + this.internalStat = internalStat; + } + + /** + * @return the identifying name of this stat + */ + public String getName() { + return this.internalStat.getName(); + } + + /** + * @return the value of this stat as a <code>java.lang.Number</code> + */ + public Number getValue() { + return this.internalStat.getValue(); + } + + /** + * @return a display string for the unit of measurement (if any) this stat represents + */ + public String getUnits() { + return this.internalStat.getUnits(); + } + + /** + * @return true if this stat represents a numeric value which always increases + */ + public boolean isCounter() { + return this.internalStat.isCounter(); + } + + /** + * @return the full description of this stat + */ + public String getDescription() { + return this.internalStat.getDescription(); + } + + /** + * Sets the internal stat which allows us to reuse the wrapper object and handle refreshes along + * with isWriteable set to false on the attribute. + */ + protected void setStat(Stat internalStat) { + this.internalStat = internalStat; + } + + /** + * Returns a string representation of the object. + * + * @return a string representation of the object + */ + @Override + public String toString() { + return getName(); + } + +} + http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b6c305f8/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/StatisticResourceImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/StatisticResourceImpl.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/StatisticResourceImpl.java new file mode 100755 index 0000000..0470a88 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/StatisticResourceImpl.java @@ -0,0 +1,177 @@ +/* + * 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.admin.api.impl; + +import org.apache.geode.internal.admin.api.AdminException; +import org.apache.geode.internal.admin.api.StatisticResource; +import org.apache.geode.internal.admin.api.SystemMember; +import org.apache.geode.internal.admin.api.Statistic; +import org.apache.geode.internal.Assert; +import org.apache.geode.internal.admin.Stat; +import org.apache.geode.internal.admin.StatResource; +import org.apache.geode.internal.i18n.LocalizedStrings; +// import org.apache.geode.internal.admin.SystemMember; + +import java.util.ArrayList; +// import java.util.Date; +import java.util.List; + +/** + * Provides monitoring of a statistic resource. + * + * @since GemFire 3.5 + */ +public class StatisticResourceImpl implements StatisticResource { + + /** The underlying remote StatResource which this object delegates to */ + protected StatResource statResource; + /** Displayable name of this statistic resource */ + protected String name; + /** Description of this statistic resource */ + protected String description; + /** Classification type of this statistic resource */ + protected String type; + /** GemFire system member which owns this statistic resource */ + protected SystemMember member; + /** The array of statistics in this resource */ + protected Statistic[] statistics; // = new Statistic[0]; + + // ------------------------------------------------------------------------- + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * Constructs an instance of StatisticResourceImpl. + * + * @param statResource the admin StatResource to manage/monitor + * @param member the SystemMember owning this resource + * @exception AdminException if unable to create this StatisticResource for administration + */ + public StatisticResourceImpl(StatResource statResource, SystemMember member) + throws AdminException { + this.statResource = statResource; + this.member = member; + this.name = this.statResource.getName(); + this.description = this.statResource.getDescription(); + this.type = this.statResource.getType(); + } + + // ------------------------------------------------------------------------- + // Attributes accessors and mutators + // ------------------------------------------------------------------------- + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + public String getType() { + return this.type; + } + + public String getOwner() { + return this.member.toString(); + } + + public Statistic[] getStatistics() { + if (this.statistics == null) { + try { + refresh(); + } catch (AdminException e) { + this.statistics = new Statistic[0]; + } + } + return this.statistics; + } + + public long getUniqueId() { + return this.statResource.getResourceUniqueID(); + } + + // ------------------------------------------------------------------------- + // Operations + // ------------------------------------------------------------------------- + + public void refresh() throws AdminException { + Stat[] stats = null; + if (this.statResource != null) { + stats = this.statResource.getStats(); + } + if (stats == null || stats.length < 1) { + throw new AdminException( + LocalizedStrings.StatisticResourceImpl_FAILED_TO_REFRESH_STATISTICS_0_FOR_1 + .toLocalizedString(getType() + "-" + getName(), getOwner())); + } + + if (this.statistics == null || this.statistics.length < 1) { + // define new statistics instances... + List statList = new ArrayList(); + for (int i = 0; i < stats.length; i++) { + statList.add(createStatistic(stats[i])); + } + this.statistics = (Statistic[]) statList.toArray(new Statistic[0]); + } else { + // update the existing instances... + for (int i = 0; i < stats.length; i++) { + updateStatistic(stats[i]); + } + } + } + + // ------------------------------------------------------------------------- + // Non-public implementation methods + // ------------------------------------------------------------------------- + + /** + * Updates the value of the {@link Statistic} corresponding to the internal + * {@link org.apache.geode.internal.admin.Stat} + * + * @param stat the internal stat to use in updating the matching statistic + */ + private void updateStatistic(Stat stat) { + for (int i = 0; i < this.statistics.length; i++) { + if (this.statistics[i].getName().equals(stat.getName())) { + ((StatisticImpl) this.statistics[i]).setStat(stat); + return; + } + } + Assert.assertTrue(false, "Unknown stat: " + stat.getName()); + } + + /** + * Creates a new {@link StatisticImpl} to represent the internal + * {@link org.apache.geode.internal.admin.Stat} + * + * @param stat the internal stat to wrap in a new statistic + */ + protected Statistic createStatistic(Stat stat) { + return new StatisticImpl(stat); + } + + /** + * Returns a string representation of the object. + * + * @return a string representation of the object + */ + @Override + public String toString() { + return getName(); + } + +} + http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b6c305f8/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberBridgeServerImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberBridgeServerImpl.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberBridgeServerImpl.java new file mode 100644 index 0000000..fd3411a --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberBridgeServerImpl.java @@ -0,0 +1,234 @@ +/* + * 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.admin.api.impl; + +import java.io.Serializable; + +import org.apache.geode.InternalGemFireException; +import org.apache.geode.internal.admin.api.AdminException; +import org.apache.geode.internal.admin.api.SystemMemberBridgeServer; +import org.apache.geode.internal.admin.api.SystemMemberCacheServer; +import org.apache.geode.cache.server.ServerLoadProbe; +import org.apache.geode.internal.admin.*; +import org.apache.geode.internal.i18n.LocalizedStrings; + +/** + * Implementation of an object used for managing cache servers. + * + * @since GemFire 4.0 + */ +public class SystemMemberBridgeServerImpl + implements SystemMemberCacheServer, SystemMemberBridgeServer { + + /** The VM in which the bridge server resides */ + private final GemFireVM vm; + + /** The cache server by this bridge server */ + private CacheInfo cache; + + /** Information about the bridge server */ + private AdminBridgeServer bridgeInfo; + + ///////////////////// Constructors ///////////////////// + + /** + * Creates a new <code>SystemMemberBridgeServerImpl</code> that administers the given bridge + * server in the given VM. + */ + protected SystemMemberBridgeServerImpl(SystemMemberCacheImpl cache, AdminBridgeServer bridgeInfo) + + throws AdminException { + + this.vm = cache.getVM(); + this.cache = cache.getCacheInfo(); + this.bridgeInfo = bridgeInfo; + } + + //////////////////// Instance Methods //////////////////// + + /** + * Throws an <code>AdminException</code> if this bridge server is running. + */ + private void checkRunning() throws AdminException { + if (this.isRunning()) { + throw new AdminException( + LocalizedStrings.SystemMemberBridgeServerImpl_CANNOT_CHANGE_THE_CONFIGURATION_OF_A_RUNNING_BRIDGE_SERVER + .toLocalizedString()); + } + } + + public int getPort() { + return this.bridgeInfo.getPort(); + } + + public void setPort(int port) throws AdminException { + checkRunning(); + this.bridgeInfo.setPort(port); + } + + public void start() throws AdminException { + this.vm.startBridgeServer(this.cache, this.bridgeInfo); + } + + public boolean isRunning() { + return this.bridgeInfo.isRunning(); + } + + public void stop() throws AdminException { + this.vm.stopBridgeServer(this.cache, this.bridgeInfo); + } + + /** + * Returns the VM-unique id of this bridge server + */ + protected int getBridgeId() { + return this.bridgeInfo.getId(); + } + + public void refresh() { + try { + this.bridgeInfo = this.vm.getBridgeInfo(this.cache, this.bridgeInfo.getId()); + + } catch (AdminException ex) { + throw new InternalGemFireException( + LocalizedStrings.SystemMemberBridgeServerImpl_UNEXPECTED_EXCEPTION_WHILE_REFRESHING + .toLocalizedString(), + ex); + } + } + + public String getBindAddress() { + return this.bridgeInfo.getBindAddress(); + } + + public void setBindAddress(String address) throws AdminException { + checkRunning(); + this.bridgeInfo.setBindAddress(address); + } + + public String getHostnameForClients() { + return this.bridgeInfo.getHostnameForClients(); + } + + public void setHostnameForClients(String name) throws AdminException { + checkRunning(); + this.bridgeInfo.setHostnameForClients(name); + } + + public void setNotifyBySubscription(boolean b) throws AdminException { + checkRunning(); + this.bridgeInfo.setNotifyBySubscription(b); + } + + public boolean getNotifyBySubscription() { + return this.bridgeInfo.getNotifyBySubscription(); + } + + public void setSocketBufferSize(int socketBufferSize) throws AdminException { + checkRunning(); + this.bridgeInfo.setSocketBufferSize(socketBufferSize); + } + + public int getSocketBufferSize() { + return this.bridgeInfo.getSocketBufferSize(); + } + + public void setTcpDelay(boolean setting) throws AdminException { + checkRunning(); + this.bridgeInfo.setTcpNoDelay(setting); + } + + public boolean getTcpDelay() { + return this.bridgeInfo.getTcpNoDelay(); + } + + public void setMaximumTimeBetweenPings(int maximumTimeBetweenPings) throws AdminException { + checkRunning(); + this.bridgeInfo.setMaximumTimeBetweenPings(maximumTimeBetweenPings); + } + + public int getMaximumTimeBetweenPings() { + return this.bridgeInfo.getMaximumTimeBetweenPings(); + } + + public int getMaxConnections() { + return this.bridgeInfo.getMaxConnections(); + } + + public void setMaxConnections(int maxCons) throws AdminException { + checkRunning(); + this.bridgeInfo.setMaxConnections(maxCons); + } + + public int getMaxThreads() { + return this.bridgeInfo.getMaxThreads(); + } + + public void setMaxThreads(int maxThreads) throws AdminException { + checkRunning(); + this.bridgeInfo.setMaxThreads(maxThreads); + } + + public int getMaximumMessageCount() { + return this.bridgeInfo.getMaximumMessageCount(); + } + + public void setMaximumMessageCount(int maxMessageCount) throws AdminException { + checkRunning(); + this.bridgeInfo.setMaximumMessageCount(maxMessageCount); + } + + public int getMessageTimeToLive() { + return this.bridgeInfo.getMessageTimeToLive(); + } + + public void setMessageTimeToLive(int messageTimeToLive) throws AdminException { + checkRunning(); + this.bridgeInfo.setMessageTimeToLive(messageTimeToLive); + } + + public void setGroups(String[] groups) throws AdminException { + checkRunning(); + this.bridgeInfo.setGroups(groups); + } + + public String[] getGroups() { + return this.bridgeInfo.getGroups(); + } + + public String getLoadProbe() { + return this.bridgeInfo.getLoadProbe().toString(); + } + + public void setLoadProbe(ServerLoadProbe loadProbe) throws AdminException { + checkRunning(); + if (!(loadProbe instanceof Serializable)) { + throw new IllegalArgumentException( + "Load probe must be Serializable to be used with admin API"); + } + this.bridgeInfo.setLoadProbe(loadProbe); + } + + public long getLoadPollInterval() { + return this.bridgeInfo.getLoadPollInterval(); + } + + public void setLoadPollInterval(long loadPollInterval) throws AdminException { + checkRunning(); + this.bridgeInfo.setLoadPollInterval(loadPollInterval); + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b6c305f8/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberCacheEventImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberCacheEventImpl.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberCacheEventImpl.java new file mode 100644 index 0000000..5f2e6bd --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberCacheEventImpl.java @@ -0,0 +1,55 @@ +/* + * 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.admin.api.impl; + +import org.apache.geode.distributed.DistributedMember; +import org.apache.geode.cache.Operation; +import org.apache.geode.internal.admin.api.SystemMemberCacheEvent; +import org.apache.geode.internal.admin.api.SystemMemberCacheListener; + +/** + * An event that describes an operation on a cache. Instances of this are delivered to a + * {@link SystemMemberCacheListener} when a a cache is created or closed. + * + * @since GemFire 5.0 + */ +public class SystemMemberCacheEventImpl extends SystemMembershipEventImpl + implements SystemMemberCacheEvent { + + /** The operation done by this event */ + private Operation op; + + /////////////////////// Constructors /////////////////////// + + /** + * Creates a new <code>SystemMemberCacheEvent</code> for the member with the given id. + */ + protected SystemMemberCacheEventImpl(DistributedMember id, Operation op) { + super(id); + this.op = op; + } + + ///////////////////// Instance Methods ///////////////////// + + public Operation getOperation() { + return this.op; + } + + @Override + public String toString() { + return super.toString() + " op=" + this.op; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b6c305f8/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberCacheEventProcessor.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberCacheEventProcessor.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberCacheEventProcessor.java new file mode 100644 index 0000000..605f172 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberCacheEventProcessor.java @@ -0,0 +1,146 @@ +/* + * 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.admin.api.impl; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.logging.log4j.Logger; + +import org.apache.geode.DataSerializer; +import org.apache.geode.internal.admin.api.SystemMemberCacheEvent; +import org.apache.geode.internal.admin.api.SystemMemberCacheListener; +import org.apache.geode.internal.admin.api.SystemMemberRegionEvent; +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.Operation; +import org.apache.geode.cache.Region; +import org.apache.geode.distributed.internal.DistributionManager; +import org.apache.geode.distributed.internal.HighPriorityDistributionMessage; +import org.apache.geode.distributed.internal.InternalDistributedSystem; +import org.apache.geode.internal.logging.LogService; + +/** + * This class processes the message to be delivered to admin node. [This needs to be redesigned and + * reimplemented... see 32887] + * + * @since GemFire 5.0 + */ +public class SystemMemberCacheEventProcessor { + private static final Logger logger = LogService.getLogger(); + + + /* + * Sends cache create/close message to Admin VMs + */ + public static void send(Cache c, Operation op) { + send(c, null, op); + } + + /* + * Sends region creation/destroy message to Admin VMs + */ + public static void send(Cache c, Region region, Operation op) { + InternalDistributedSystem system = (InternalDistributedSystem) c.getDistributedSystem(); + Set recps = system.getDistributionManager().getAdminMemberSet(); + // @todo darrel: find out if any of these guys have region listeners + if (recps.isEmpty()) { + return; + } + SystemMemberCacheMessage msg = new SystemMemberCacheMessage(); + if (region == null) { + msg.regionPath = null; + } else { + msg.regionPath = region.getFullPath(); + } + msg.setRecipients(recps); + msg.op = op; + system.getDistributionManager().putOutgoing(msg); + } + + + public static final class SystemMemberCacheMessage extends HighPriorityDistributionMessage { + protected String regionPath; + protected Operation op; + + @Override + protected void process(DistributionManager dm) { + AdminDistributedSystemImpl admin = AdminDistributedSystemImpl.getConnectedInstance(); + if (admin == null) { + if (logger.isDebugEnabled()) { + logger.debug("Ignoring message because there is no admin distributed system present: {}", + this); + } + return; // probably shutting down or still connecting + } + List listeners = admin.getCacheListeners(); + Iterator itr = listeners.iterator(); + SystemMemberCacheListener listener = null; + while (itr.hasNext()) { + listener = (SystemMemberCacheListener) itr.next(); + if (this.regionPath == null) { + SystemMemberCacheEvent event = new SystemMemberCacheEventImpl(getSender(), this.op); + if (this.op == Operation.CACHE_CREATE) { + listener.afterCacheCreate(event); + } else { + listener.afterCacheClose(event); + } + } else { + SystemMemberRegionEvent event = + new SystemMemberRegionEventImpl(getSender(), this.op, this.regionPath); + if (this.op.isRegionDestroy()) { + listener.afterRegionLoss(event); + } else { + listener.afterRegionCreate(event); + } + } + } + } + + public int getDSFID() { + return ADMIN_CACHE_EVENT_MESSAGE; + } + + @Override + public void fromData(DataInput in) throws IOException, ClassNotFoundException { + super.fromData(in); + this.regionPath = DataSerializer.readString(in); + this.op = Operation.fromOrdinal(in.readByte()); + } + + @Override + public void toData(DataOutput out) throws IOException { + super.toData(out); + DataSerializer.writeString(this.regionPath, out); + out.writeByte(this.op.ordinal); + } + + @Override + public String toString() { + StringBuffer buff = new StringBuffer(); + buff.append("SystemMemberCacheMessage (region='"); + buff.append(this.regionPath); + buff.append("'; sender="); + buff.append(this.sender); + buff.append("; op="); + buff.append(this.op); + buff.append(")"); + return buff.toString(); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b6c305f8/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberCacheImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberCacheImpl.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberCacheImpl.java new file mode 100644 index 0000000..c9615f6 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberCacheImpl.java @@ -0,0 +1,310 @@ +/* + * 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.admin.api.impl; + +import org.apache.geode.cache.*; +import org.apache.geode.internal.Assert; +import org.apache.geode.internal.ObjIdMap; +import org.apache.geode.internal.admin.*; +import org.apache.geode.internal.admin.api.AdminException; +import org.apache.geode.internal.admin.api.CacheDoesNotExistException; +import org.apache.geode.internal.admin.api.GemFireMemberStatus; +import org.apache.geode.internal.admin.api.RegionSubRegionSnapshot; +import org.apache.geode.internal.admin.api.Statistic; +import org.apache.geode.internal.admin.api.SystemMemberBridgeServer; +import org.apache.geode.internal.admin.api.SystemMemberCache; +import org.apache.geode.internal.admin.api.SystemMemberCacheServer; +import org.apache.geode.internal.admin.api.SystemMemberRegion; +import org.apache.geode.internal.i18n.LocalizedStrings; + +import java.util.*; + +/** + * View of a GemFire system member's cache. + * + * @since GemFire 3.5 + */ +public class SystemMemberCacheImpl implements SystemMemberCache { + protected final GemFireVM vm; + protected CacheInfo info; + protected Statistic[] statistics; + + /** Maps the id of a bridge server to its SystemMemberBridgeServer */ + private ObjIdMap bridgeServers = new ObjIdMap(); + + // constructors + public SystemMemberCacheImpl(GemFireVM vm) throws CacheDoesNotExistException { + this.vm = vm; + this.info = vm.getCacheInfo(); + if (this.info == null) { + throw new CacheDoesNotExistException( + LocalizedStrings.SystemMemberCacheImpl_THE_VM_0_DOES_NOT_CURRENTLY_HAVE_A_CACHE + .toLocalizedString(vm.getId())); + } + initStats(); + } + + // attributes + /** + * The name of the cache. + */ + public String getName() { + String result = this.info.getName(); + if (result == null || result.length() == 0) { + result = "default"; + } + return result; + } + + /** + * Value that uniquely identifies an instance of a cache for a given member. + */ + public int getId() { + return this.info.getId(); + } + + public boolean isClosed() { + return this.info.isClosed(); + } + + public int getLockTimeout() { + return this.info.getLockTimeout(); + } + + public void setLockTimeout(int seconds) throws AdminException { + this.info = this.vm.setCacheLockTimeout(this.info, seconds); + } + + public int getLockLease() { + return this.info.getLockLease(); + } + + public void setLockLease(int seconds) throws AdminException { + this.info = this.vm.setCacheLockLease(this.info, seconds); + } + + public int getSearchTimeout() { + return this.info.getSearchTimeout(); + } + + public void setSearchTimeout(int seconds) throws AdminException { + this.info = this.vm.setCacheSearchTimeout(this.info, seconds); + } + + public int getUpTime() { + return this.info.getUpTime(); + } + + public java.util.Set getRootRegionNames() { + Set set = this.info.getRootRegionNames(); + if (set == null) { + set = Collections.EMPTY_SET; + } + return set; + } + // operations + + public void refresh() { + if (!this.info.isClosed()) { + CacheInfo cur = vm.getCacheInfo(); + if (cur == null || (this.info.getId() != cur.getId())) { + // it is a different instance of the cache. So set our version + // to closed + this.info.setClosed(); + } else { + this.info = cur; + updateStats(); + } + } + } + + public GemFireMemberStatus getSnapshot() { + // System.out.println(">>>SystemMemberCacheJmxImpl::getSnapshot:pre::: " + this.vm); + GemFireMemberStatus stat = this.vm.getSnapshot(); + // System.out.println(">>>SystemMemberCacheJmxImpl::getSnapshot:post::: " + stat); + return stat; + } + + public RegionSubRegionSnapshot getRegionSnapshot() { + // System.out.println(">>>SystemMemberCacheJmxImpl::getRegionSnapshot:pre::: " + this.vm); + RegionSubRegionSnapshot snap = this.vm.getRegionSnapshot(); + // System.out.println(">>>SystemMemberCacheJmxImpl::getRegionSnapshot:post::: " + snap); + return snap; + } + + public Statistic[] getStatistics() { + return this.statistics; + } + + public SystemMemberRegion getRegion(String path) throws AdminException { + Region r = this.vm.getRegion(this.info, path); + if (r == null) { + return null; + } else { + return createSystemMemberRegion(r); + } + } + + public SystemMemberRegion createRegion(String name, RegionAttributes attrs) + throws AdminException { + Region r = this.vm.createVMRootRegion(this.info, name, attrs); + if (r == null) { + return null; + + } else { + return createSystemMemberRegion(r); + } + } + + public SystemMemberRegion createVMRegion(String name, RegionAttributes attrs) + throws AdminException { + return createRegion(name, attrs); + } + + + // internal methods + private void initStats() { + StatResource resource = this.info.getPerfStats(); + if (resource == null) { + // See bug 31397 + Assert.assertTrue(this.isClosed()); + return; + } + + Stat[] stats = resource.getStats(); + if (stats == null || stats.length < 1) { + this.statistics = new Statistic[0]; + return; + } + + // define new statistics instances... + List statList = new ArrayList(); + for (int i = 0; i < stats.length; i++) { + statList.add(createStatistic(stats[i])); + } + this.statistics = (Statistic[]) statList.toArray(new Statistic[statList.size()]); + } + + private void updateStats() { + StatResource resource = this.info.getPerfStats(); + if (resource == null) { + // See bug 31397 + Assert.assertTrue(this.isClosed()); + return; + } + + Stat[] stats = resource.getStats(); + if (stats == null || stats.length < 1) { + return; + } + + for (int i = 0; i < stats.length; i++) { + updateStatistic(stats[i]); + } + } + + private void updateStatistic(Stat stat) { + for (int i = 0; i < this.statistics.length; i++) { + if (this.statistics[i].getName().equals(stat.getName())) { + ((StatisticImpl) this.statistics[i]).setStat(stat); + return; + } + } + Assert.assertTrue(false, "Unknown stat: " + stat.getName()); + } + + /** + * Returns the <code>CacheInfo</code> that describes this cache. Note that this operation does not + * {@link #refresh} the <code>CacheInfo</code>. + */ + public CacheInfo getCacheInfo() { + return this.info; + } + + public GemFireVM getVM() { + return this.vm; + } + + protected Statistic createStatistic(Stat stat) { + return new StatisticImpl(stat); + } + + protected SystemMemberRegion createSystemMemberRegion(Region r) throws AdminException { + SystemMemberRegionImpl sysMemberRegion = new SystemMemberRegionImpl(this, r); + sysMemberRegion.refresh(); + return sysMemberRegion; + } + + public SystemMemberCacheServer addCacheServer() throws AdminException { + + AdminBridgeServer bridge = this.vm.addCacheServer(this.info); + SystemMemberCacheServer admin = createSystemMemberBridgeServer(bridge); + bridgeServers.put(bridge.getId(), admin); + return admin; + } + + private Collection getCacheServersCollection() throws AdminException { + Collection bridges = new ArrayList(); + + int[] bridgeIds = this.info.getBridgeServerIds(); + for (int i = 0; i < bridgeIds.length; i++) { + int id = bridgeIds[i]; + SystemMemberBridgeServer bridge = (SystemMemberBridgeServer) bridgeServers.get(id); + if (bridge == null) { + AdminBridgeServer info = this.vm.getBridgeInfo(this.info, id); + if (info != null) { + bridge = createSystemMemberBridgeServer(info); + bridgeServers.put(info.getId(), bridge); + } + } + + if (bridge != null) { + bridges.add(bridge); + } + } + return bridges; + } + + public SystemMemberCacheServer[] getCacheServers() throws AdminException { + Collection bridges = getCacheServersCollection(); + SystemMemberCacheServer[] array = new SystemMemberCacheServer[bridges.size()]; + return (SystemMemberCacheServer[]) bridges.toArray(array); + }; + + /** + * Creates a new instance of <Code>SystemMemberBridgeServer</code> with the given configuration. + */ + protected SystemMemberBridgeServerImpl createSystemMemberBridgeServer(AdminBridgeServer bridge) + throws AdminException { + + return new SystemMemberBridgeServerImpl(this, bridge); + } + + public boolean isServer() throws AdminException { + return this.info.isServer(); + } + + + /** + * Returns a string representation of the object. + * + * @return a string representation of the object + */ + @Override + public String toString() { + return getName(); + } +} + http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b6c305f8/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberImpl.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberImpl.java new file mode 100755 index 0000000..f292994 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberImpl.java @@ -0,0 +1,490 @@ +/* + * 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.admin.api.impl; + +import org.apache.geode.CancelException; +import org.apache.geode.SystemFailure; +import org.apache.geode.distributed.DistributedMember; +import org.apache.geode.distributed.Role; +import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.distributed.internal.DistributionConfigImpl; +import org.apache.geode.distributed.internal.membership.InternalDistributedMember; +import org.apache.geode.internal.Config; +import org.apache.geode.internal.ConfigSource; +import org.apache.geode.internal.admin.GemFireVM; +import org.apache.geode.internal.admin.StatResource; +import org.apache.geode.internal.admin.api.AdminDistributedSystem; +import org.apache.geode.internal.admin.api.AdminException; +import org.apache.geode.internal.admin.api.CacheDoesNotExistException; +import org.apache.geode.internal.admin.api.ConfigurationParameter; +import org.apache.geode.internal.admin.api.RuntimeAdminException; +import org.apache.geode.internal.admin.api.StatisticResource; +import org.apache.geode.internal.admin.api.SystemMember; +import org.apache.geode.internal.admin.api.SystemMemberCache; +import org.apache.geode.internal.admin.api.SystemMemberType; +import org.apache.geode.internal.i18n.LocalizedStrings; +import org.apache.geode.internal.logging.LogService; +import org.apache.logging.log4j.Logger; + +import java.net.InetAddress; +import java.util.*; + +/** + * Member of a GemFire system. + * + * @since GemFire 3.5 + */ +public class SystemMemberImpl implements SystemMember, ConfigurationParameterListener { + + private static final Logger logger = LogService.getLogger(); + + /** + * Identifying name of this member. Note that by default this is the string form of internalId but + * the ManagedSystemMemberImpl subclass resets it to getNewId() + */ + protected String id; + + /** Unique internal id that the system impl identifies this member with */ + protected InternalDistributedMember internalId; + + /** The name of this system member */ + protected String name; + + /** Host name of the machine this member resides on */ + protected String host; + + /** The internal configuration this impl delegates to for runtime config */ + // private Config config; + + /** + * The configuration parameters for this member. Maps the name of the ConfigurationParameter to + * the ConfigurationParameter. + */ + protected Map parms = new HashMap(); + + /** The {@link AdminDistributedSystem} this is a member of */ + protected AdminDistributedSystem system; + + /** Internal GemFire vm to delegate to */ + private GemFireVM vm; + + // ------------------------------------------------------------------------- + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * Constructs new <code>SystemMemberImpl</code> for a <code>ManagedEntity</code> that has yet to + * be started. + * + * @param system the distributed system this member belongs to + */ + protected SystemMemberImpl(AdminDistributedSystem system) throws AdminException { + + this.system = system; + refreshConfig(getDefaultConfig()); + } + + /** + * Constructs new <code>SystemMemberImpl</code> from the given <code>GemFireVM</code>. This + * constructor is invoked when we discover a new member of the distributed system. + * + * @param system the distributed system this member belongs to + * @param vm internal GemFire vm to delegate to + */ + public SystemMemberImpl(AdminDistributedSystem system, GemFireVM vm) throws AdminException { + + this(system); + setGemFireVM(vm); + } + + /** + * Constructs the instance of SystemMember using the corresponding InternalDistributedMember + * instance of a DS member for the given AdminDistributedSystem. + * + * @param system Current AdminDistributedSystem instance + * @param member InternalDistributedMember instance for which a SystemMember instance is to be + * constructed. + * @throws AdminException if construction of SystemMember fails + * + * @since GemFire 6.5 + */ + protected SystemMemberImpl(AdminDistributedSystem system, InternalDistributedMember member) + throws AdminException { + this(system); + updateByInternalDistributedMember(member); + } + + // ------------------------------------------------------------------------- + // Attribute accessors and mutators + // ------------------------------------------------------------------------- + + /** + * Returns a <code>Config</code> object with the appropriate default values for a newly-created + * system member. + */ + protected Config getDefaultConfig() { + Properties props = new Properties(); + return new DistributionConfigImpl(props); + } + + public final AdminDistributedSystem getDistributedSystem() { + return this.system; + } + + public final InternalDistributedMember getInternalId() { + return internalId; + } + + public final String getId() { + return this.id; + } + + public final String getName() { + return this.name; + } + + public String getHost() { + return this.host; + } + + public final InetAddress getHostAddress() { + return InetAddressUtil.toInetAddress(this.getHost()); + } + + // ------------------------------------------------------------------------- + // Operations + // ------------------------------------------------------------------------- + + public final String getLog() { + String childTail = null; + String mainTail = null; + GemFireVM vm = getGemFireVM(); + if (vm != null) { + String[] log = vm.getSystemLogs(); + if (log != null && log.length > 0) + mainTail = log[0]; + if (log != null && log.length > 1) + childTail = log[1]; + } + + if (childTail == null && mainTail == null) { + return LocalizedStrings.SystemMemberImpl_NO_LOG_FILE_CONFIGURED_LOG_MESSAGES_WILL_BE_DIRECTED_TO_STDOUT + .toLocalizedString(); + } else { + StringBuffer result = new StringBuffer(); + if (mainTail != null) { + result.append(mainTail); + } + if (childTail != null) { + result.append( + "\n" + LocalizedStrings.SystemMemberImpl_TAIL_OF_CHILD_LOG.toLocalizedString() + "\n"); + result.append(childTail); + } + return result.toString(); + } + } + + public final java.util.Properties getLicense() { + GemFireVM vm = getGemFireVM(); + if (vm == null) + return null; + return new Properties(); + } + + public final String getVersion() { + GemFireVM vm = getGemFireVM(); + if (vm == null) + return null; + return vm.getVersionInfo(); + } + + public StatisticResource[] getStat(String statisticsTypeName) throws AdminException { + StatisticResource[] res = new StatisticResource[0]; + if (this.vm != null) { + res = getStatsImpl(this.vm.getStats(statisticsTypeName)); + } + return res.length == 0 ? null : res; + } + + public StatisticResource[] getStats() throws AdminException { + StatisticResource[] statsImpl = new StatisticResource[0]; + if (this.vm != null) { + statsImpl = getStatsImpl(this.vm.getStats(null)); + } + return statsImpl; + } + + public final boolean hasCache() { + GemFireVM member = getGemFireVM(); + if (member == null) { + return false; + + } else { + return member.getCacheInfo() != null; + } + } + + public final SystemMemberCache getCache() throws AdminException { + GemFireVM vm = getGemFireVM(); // fix for bug 33505 + if (vm == null) + return null; + try { + return createSystemMemberCache(vm); + + } catch (CancelException ex) { + return null; + + } catch (CacheDoesNotExistException ex) { + return null; + } + } + + public void refreshConfig() throws AdminException { + GemFireVM vm = getGemFireVM(); + if (vm == null) + return; + refreshConfig(vm.getConfig()); + } + + /** + * Sets the value of this system member's distribution-related configuration based on the given + * <code>Config</code> object. + */ + public final void refreshConfig(Config config) throws AdminException { + if (config == null) { + throw new AdminException( + LocalizedStrings.SystemMemberImpl_FAILED_TO_REFRESH_CONFIGURATION_PARAMETERS_FOR_0 + .toLocalizedString(new Object[] {getId()})); + } + + String[] names = config.getAttributeNames(); + if (names == null || names.length < 1) { + throw new AdminException( + LocalizedStrings.SystemMemberImpl_FAILED_TO_REFRESH_CONFIGURATION_PARAMETERS_FOR_0 + .toLocalizedString(new Object[] {getId()})); + } + + for (int i = 0; i < names.length; i++) { + String name = names[i]; + Object value = config.getAttributeObject(name); + if (value != null) { + ConfigurationParameter parm = createConfigurationParameter(name, // name + config.getAttributeDescription(name), // description + value, // value + config.getAttributeType(name), // valueType + config.isAttributeModifiable(name)); // isModifiable + ((ConfigurationParameterImpl) parm).addConfigurationParameterListener(this); + this.parms.put(name, parm); + } + } + } + + public final ConfigurationParameter[] getConfiguration() { + ConfigurationParameter[] array = new ConfigurationParameter[this.parms.size()]; + this.parms.values().toArray(array); + return array; + } + + public ConfigurationParameter[] setConfiguration(ConfigurationParameter[] parms) + throws AdminException { + + for (int i = 0; i < parms.length; i++) { + ConfigurationParameter parm = parms[i]; + this.parms.put(parm.getName(), parm); + } + + GemFireVM vm = getGemFireVM(); + if (vm != null) { + // update internal vm's config... + Config config = vm.getConfig(); + for (int i = 0; i < parms.length; i++) { + config.setAttributeObject(parms[i].getName(), parms[i].getValue(), ConfigSource.runtime()); + } + vm.setConfig(config); + } + + return this.getConfiguration(); + } + + public SystemMemberType getType() { + return SystemMemberType.APPLICATION; + } + + // ------------------------------------------------------------------------- + // Listener callbacks + // ------------------------------------------------------------------------- + + // -- ConfigurationParameterListener --- + public void configurationParameterValueChanged(ConfigurationParameter parm) { + try { + setConfiguration(new ConfigurationParameter[] {parm}); + } catch (AdminException e) { + // this shouldn't occur since this is a config listener method... + logger.warn(e.getMessage(), e); + throw new RuntimeAdminException(e); + } catch (java.lang.Exception e) { + logger.warn(e.getMessage(), e); + } + // catch (java.lang.RuntimeException e) { + // logWriter.warning(e); + // throw e; + // } + catch (VirtualMachineError err) { + SystemFailure.initiateFailure(err); + // If this ever returns, rethrow the error. We're poisoned + // now, so don't let this thread continue. + throw err; + } catch (java.lang.Error e) { + // Whenever you catch Error or Throwable, you must also + // catch VirtualMachineError (see above). However, there is + // _still_ a possibility that you are dealing with a cascading + // error condition, so you also need to check to see if the JVM + // is still usable: + SystemFailure.checkFailure(); + logger.error(e.getMessage(), e); + throw e; + } + } + + // ------------------------------------------------------------------------- + // Overridden method(s) from java.lang.Object + // ------------------------------------------------------------------------- + + @Override + public String toString() { + return getName(); + } + + // ------------------------------------------------------------------------- + // Template methods with default behavior impl'ed. Override if needed. + // ------------------------------------------------------------------------- + + /** + * Returns the <code>GemFireVM</code> that underlies this <code>SystemMember</code>. + */ + protected final GemFireVM getGemFireVM() { + return this.vm; + } + + /** + * Sets the <code>GemFireVM</code> that underlies this <code>SystemMember</code>. This method is + * used when a member, such as a cache server, is started by the admin API. + */ + void setGemFireVM(GemFireVM vm) throws AdminException { + this.vm = vm; + if (vm != null) { + this.internalId = vm.getId(); + this.id = this.internalId.toString(); + this.name = vm.getName(); + this.host = InetAddressUtil.toString(vm.getHost()); + } else { + this.internalId = null; + this.id = null; + // leave this.name set to what it is (how come?) + this.host = this.getHost(); + } + + if (DistributionConfig.DEFAULT_NAME.equals(this.name)) { + // Fix bug 32877 + this.name = this.id; + } + + if (vm != null) { + this.refreshConfig(); + } + } + + /** + * Updates this SystemMember instance using the corresponding InternalDistributedMember + * + * @param member InternalDistributedMember instance to update this SystemMember + * + * @since GemFire 6.5 + */ + private void updateByInternalDistributedMember(InternalDistributedMember member) { + if (member != null) { + this.internalId = member; + this.id = this.internalId.toString(); + this.host = this.internalId.getHost(); + this.name = this.internalId.getName(); + if (this.name == null || DistributionConfig.DEFAULT_NAME.equals(this.name)) { + /* + * name could be null & referring to description of a fix for 32877 + */ + this.name = this.id; + } + } + } + + /** + * Template method for creating {@link StatisticResource}. + * + * @param stat the internal stat resource to wrap with {@link StatisticResource} + * @return new impl instance of {@link StatisticResource} + */ + protected StatisticResource createStatisticResource(StatResource stat) throws AdminException { + return new StatisticResourceImpl(stat, this); + } + + /** + * Template method for creating {@link ConfigurationParameter}. + * + * @param name the name of this parameter which cannot change + * @param description full description to use + * @param value the value of this parameter + * @param type the class type of the value + * @param userModifiable true if this is modifiable; false if read-only + * @return new impl instance of {@link ConfigurationParameter} + */ + protected ConfigurationParameter createConfigurationParameter(String name, String description, + Object value, Class type, boolean userModifiable) { + return new ConfigurationParameterImpl(name, description, value, type, userModifiable); + } + + /** + * Template method for creating {@link SystemMemberCache}. + * + * @param vm the GemFire vm to retrieve cache info from + * @return new impl instance of {@link SystemMemberCache} + */ + protected SystemMemberCache createSystemMemberCache(GemFireVM vm) throws AdminException { + return new SystemMemberCacheImpl(vm); + } + + /** Wrap the internal stats with impls of {@link StatisticResource} */ + protected StatisticResource[] getStatsImpl(StatResource[] stats) throws AdminException { + List statList = new ArrayList(); + for (int i = 0; i < stats.length; i++) { + statList.add(createStatisticResource(stats[i])); + } + return (StatisticResource[]) statList.toArray(new StatisticResource[0]); + } + + public String[] getRoles() { + Set roles = this.internalId.getRoles(); + String[] roleNames = new String[roles.size()]; + Iterator iter = roles.iterator(); + for (int i = 0; i < roleNames.length; i++) { + Role role = (Role) iter.next(); + roleNames[i] = role.getName(); + } + return roleNames; + } + + public DistributedMember getDistributedMember() { + return this.internalId; + } +} + http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b6c305f8/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberRegionEventImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberRegionEventImpl.java b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberRegionEventImpl.java new file mode 100644 index 0000000..c89100e --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/api/impl/SystemMemberRegionEventImpl.java @@ -0,0 +1,57 @@ +/* + * 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.admin.api.impl; + +import org.apache.geode.distributed.DistributedMember; +import org.apache.geode.cache.Operation; +import org.apache.geode.internal.admin.api.SystemMemberCacheListener; +import org.apache.geode.internal.admin.api.SystemMemberRegionEvent; + +/** + * An event that describes an operation on a region. Instances of this are delivered to a + * {@link SystemMemberCacheListener} when a a region comes or goes. + * + * @since GemFire 5.0 + */ +public class SystemMemberRegionEventImpl extends SystemMemberCacheEventImpl + implements SystemMemberRegionEvent { + + /** + * The path of region created/destroyed + */ + private final String regionPath; + + /////////////////////// Constructors /////////////////////// + + /** + * Creates a new <code>SystemMemberRegionEvent</code> for the member with the given id. + */ + protected SystemMemberRegionEventImpl(DistributedMember id, Operation op, String regionPath) { + super(id, op); + this.regionPath = regionPath; + } + + ///////////////////// Instance Methods ///////////////////// + + public String getRegionPath() { + return this.regionPath; + } + + @Override + public String toString() { + return super.toString() + " region=" + this.regionPath; + } + +}