blob: ad0bdf10aed8c413fead03e3a330b0225606b65f [file] [log] [blame]
/*
* 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.admin.internal;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.apache.logging.log4j.Logger;
import org.apache.geode.CancelException;
import org.apache.geode.SystemFailure;
import org.apache.geode.admin.AdminDistributedSystem;
import org.apache.geode.admin.AdminException;
import org.apache.geode.admin.CacheDoesNotExistException;
import org.apache.geode.admin.ConfigurationParameter;
import org.apache.geode.admin.RuntimeAdminException;
import org.apache.geode.admin.StatisticResource;
import org.apache.geode.admin.SystemMemberCache;
import org.apache.geode.admin.SystemMemberType;
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.logging.LogService;
/**
* Member of a GemFire system.
*
* @since GemFire 3.5
*/
public class SystemMemberImpl implements org.apache.geode.admin.SystemMember,
org.apache.geode.admin.internal.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 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);
}
@Override
public AdminDistributedSystem getDistributedSystem() {
return this.system;
}
public InternalDistributedMember getInternalId() {
return internalId;
}
@Override
public String getId() {
return this.id;
}
@Override
public String getName() {
return this.name;
}
@Override
public String getHost() {
return this.host;
}
@Override
public InetAddress getHostAddress() {
return InetAddressUtil.toInetAddress(this.getHost());
}
// -------------------------------------------------------------------------
// Operations
// -------------------------------------------------------------------------
@Override
public 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 "No log file configured, log messages will be directed to stdout.";
} else {
StringBuffer result = new StringBuffer();
if (mainTail != null) {
result.append(mainTail);
}
if (childTail != null) {
result.append(
"\n" + "-------------------- tail of child log --------------------" + "\n");
result.append(childTail);
}
return result.toString();
}
}
@Override
public java.util.Properties getLicense() {
GemFireVM vm = getGemFireVM();
if (vm == null)
return null;
return new Properties();
}
@Override
public String getVersion() {
GemFireVM vm = getGemFireVM();
if (vm == null)
return null;
return vm.getVersionInfo();
}
@Override
public StatisticResource[] getStat(String statisticsTypeName)
throws org.apache.geode.admin.AdminException {
StatisticResource[] res = new StatisticResource[0];
if (this.vm != null) {
res = getStatsImpl(this.vm.getStats(statisticsTypeName));
}
return res.length == 0 ? null : res;
}
@Override
public StatisticResource[] getStats() throws org.apache.geode.admin.AdminException {
StatisticResource[] statsImpl = new StatisticResource[0];
if (this.vm != null) {
statsImpl = getStatsImpl(this.vm.getStats(null));
}
return statsImpl;
}
@Override
public boolean hasCache() {
GemFireVM member = getGemFireVM();
if (member == null) {
return false;
} else {
return member.getCacheInfo() != null;
}
}
@Override
public SystemMemberCache getCache() throws org.apache.geode.admin.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;
}
}
@Override
public void refreshConfig() throws org.apache.geode.admin.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 void refreshConfig(Config config) throws org.apache.geode.admin.AdminException {
if (config == null) {
throw new AdminException(
String.format("Failed to refresh configuration parameters for: %s",
new Object[] {getId()}));
}
String[] names = config.getAttributeNames();
if (names == null || names.length < 1) {
throw new AdminException(
String.format("Failed to refresh configuration parameters for: %s",
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);
}
}
}
@Override
public ConfigurationParameter[] getConfiguration() {
ConfigurationParameter[] array = new ConfigurationParameter[this.parms.size()];
this.parms.values().toArray(array);
return array;
}
@Override
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();
}
@Override
public SystemMemberType getType() {
return SystemMemberType.APPLICATION;
}
// -------------------------------------------------------------------------
// Listener callbacks
// -------------------------------------------------------------------------
// -- org.apache.geode.admin.internal.ConfigurationParameterListener ---
@Override
public void configurationParameterValueChanged(ConfigurationParameter parm) {
try {
setConfiguration(new ConfigurationParameter[] {parm});
} catch (org.apache.geode.admin.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 (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 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 org.apache.geode.admin.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 org.apache.geode.admin.AdminException {
return new SystemMemberCacheImpl(vm);
}
/** Wrap the internal stats with impls of {@link StatisticResource} */
protected StatisticResource[] getStatsImpl(StatResource[] stats)
throws org.apache.geode.admin.AdminException {
List<StatisticResource> statList = new ArrayList<>();
for (int i = 0; i < stats.length; i++) {
statList.add(createStatisticResource(stats[i]));
}
return statList.toArray(new StatisticResource[0]);
}
@Override
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;
}
@Override
public DistributedMember getDistributedMember() {
return this.internalId;
}
}