| /* |
| * 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; |
| } |
| } |