/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2008-2010 Sun Microsystems, Inc. * Portions Copyright 2014-2015 ForgeRock AS */ package org.opends.guitools.controlpanel.datamodel; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.opends.guitools.controlpanel.util.ConfigFromDirContext; import org.opends.quicksetup.UserData; import org.opends.server.tools.tasks.TaskEntry; import org.opends.server.types.AttributeType; import org.opends.server.types.DN; import org.opends.server.types.ObjectClass; import org.opends.server.types.OpenDsException; import org.opends.server.types.Schema; import com.forgerock.opendj.util.OperatingSystem; import static org.opends.guitools.controlpanel.datamodel.BasicMonitoringAttributes.*; import static org.opends.guitools.controlpanel.util.Utilities.*; import static org.opends.server.types.CommonSchemaElements.*; /** * This is just a class used to provide a data model describing what the * StatusPanelDialog will show to the user. */ public class ServerDescriptor { private static String localHostName = UserData.getDefaultHostName(); private ServerStatus status; private int openConnections; private Set<BackendDescriptor> backends = new HashSet<>(); private Set<ConnectionHandlerDescriptor> listeners = new HashSet<>(); private ConnectionHandlerDescriptor adminConnector; private Set<DN> administrativeUsers = new HashSet<>(); private String installPath; private String instancePath; private String openDSVersion; private String javaVersion; private ArrayList<OpenDsException> exceptions = new ArrayList<>(); private boolean isWindowsServiceEnabled; private boolean isSchemaEnabled; private Schema schema; private CustomSearchResult rootMonitor; private CustomSearchResult jvmMemoryUsage; private CustomSearchResult systemInformation; private CustomSearchResult entryCaches; private CustomSearchResult workQueue; private Set<TaskEntry> taskEntries = new HashSet<>(); private long runningTime = -1; private boolean isAuthenticated; private String hostName = localHostName; private boolean isLocal = true; /** Enumeration indicating the status of the server. */ public enum ServerStatus { /** Server Started. */ STARTED, /** Server Stopped. */ STOPPED, /** Server Starting. */ STARTING, /** Server Stopping. */ STOPPING, /** Not connected to remote. */ NOT_CONNECTED_TO_REMOTE, /** Status Unknown. */ UNKNOWN } /** Default constructor. */ public ServerDescriptor() { } /** * Return the administrative users. * @return the administrative users. */ public Set<DN> getAdministrativeUsers() { return administrativeUsers; } /** * Set the administrative users. * @param administrativeUsers the administrative users to set */ public void setAdministrativeUsers(Set<DN> administrativeUsers) { this.administrativeUsers = Collections.unmodifiableSet(administrativeUsers); } /** * Returns whether the schema is enabled or not. * @return <CODE>true</CODE> if the schema is enabled and <CODE>false</CODE> * otherwise. */ public boolean isSchemaEnabled() { return isSchemaEnabled; } /** * Sets whether the schema is enabled or not. * @param isSchemaEnabled <CODE>true</CODE> if the schema is enabled and * <CODE>false</CODE> otherwise. */ public void setSchemaEnabled(boolean isSchemaEnabled) { this.isSchemaEnabled = isSchemaEnabled; } /** * Return the instance path where the server databases and configuration is * located. * @return the instance path where the server databases and configuration is * located */ public String getInstancePath() { return instancePath; } /** * Sets the instance path where the server databases and configuration is * located. * @param instancePath the instance path where the server databases and * configuration is located. */ public void setInstancePath(String instancePath) { this.instancePath = instancePath; } /** * Return the install path where the server is installed. * @return the install path where the server is installed. */ public String getInstallPath() { return installPath; } /** * Sets the install path where the server is installed. * @param installPath the install path where the server is installed. */ public void setInstallPath(String installPath) { this.installPath = installPath; } /** * Returns whether the install and the instance are on the same server * or not. * @return whether the install and the instance are on the same server * or not. */ public boolean sameInstallAndInstance() { boolean sameInstallAndInstance; String instance = getInstancePath(); String install = getInstallPath(); try { if (instance != null) { sameInstallAndInstance = instance.equals(install); if (!sameInstallAndInstance && (isLocal() || OperatingSystem.isWindows())) { File f1 = new File(instance); File f2 = new File(install); sameInstallAndInstance = f1.getCanonicalFile().equals(f2.getCanonicalFile()); } } else { sameInstallAndInstance = install == null; } } catch (IOException ioe) { sameInstallAndInstance = false; } return sameInstallAndInstance; } /** * Return the java version used to run the server. * @return the java version used to run the server. */ public String getJavaVersion() { return javaVersion; } /** * Set the java version used to run the server. * @param javaVersion the java version used to run the server. */ public void setJavaVersion(String javaVersion) { this.javaVersion = javaVersion; } /** * Returns the number of open connection in the server. * @return the number of open connection in the server. */ public int getOpenConnections() { return openConnections; } /** * Set the number of open connections. * @param openConnections the number of open connections. */ public void setOpenConnections(int openConnections) { this.openConnections = openConnections; } /** * Returns the version of the server. * @return the version of the server. */ public String getOpenDSVersion() { return openDSVersion; } /** * Sets the version of the server. * @param openDSVersion the version of the server. */ public void setOpenDSVersion(String openDSVersion) { this.openDSVersion = openDSVersion; } /** * Returns the status of the server. * @return the status of the server. */ public ServerStatus getStatus() { return status; } /** * Sets the status of the server. * @param status the status of the server. */ public void setStatus(ServerStatus status) { this.status = status; } /** * Returns the task entries. * @return the task entries. */ public Set<TaskEntry> getTaskEntries() { return taskEntries; } /** * Sets the the task entries. * @param taskEntries the task entries. */ public void setTaskEntries(Set<TaskEntry> taskEntries) { this.taskEntries = Collections.unmodifiableSet(taskEntries); } /** {@inheritDoc} */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof ServerDescriptor)) { return false; } ServerDescriptor desc = (ServerDescriptor) o; return desc.getStatus() == getStatus() && desc.isLocal() == isLocal() && desc.isAuthenticated() == isAuthenticated() && desc.getOpenConnections() == getOpenConnections() && areEqual(getInstallPath(), desc.getInstallPath()) && areEqual(getInstancePath(), desc.getInstancePath()) && areEqual(getJavaVersion(), desc.getJavaVersion()) && areEqual(getOpenDSVersion(), desc.getOpenDSVersion()) && areEqual(desc.getAdministrativeUsers(), getAdministrativeUsers()) && areEqual(desc.getConnectionHandlers(), getConnectionHandlers()) && areEqual(desc.getBackends(), getBackends()) && areEqual(desc.getExceptions(), getExceptions()) && desc.isSchemaEnabled() == isSchemaEnabled() && areSchemasEqual(getSchema(), desc.getSchema()) && (!OperatingSystem.isWindows() || desc.isWindowsServiceEnabled() == isWindowsServiceEnabled()) && desc.getTaskEntries().equals(getTaskEntries()); } /** {@inheritDoc} */ @Override public int hashCode() { String s = installPath + openDSVersion + javaVersion + isAuthenticated; return status.hashCode() + openConnections + s.hashCode(); } /** * Return whether we were authenticated when retrieving the information of * this ServerStatusDescriptor. * @return <CODE>true</CODE> if we were authenticated when retrieving the * information of this ServerStatusDescriptor and <CODE>false</CODE> * otherwise. */ public boolean isAuthenticated() { return isAuthenticated; } /** * Sets whether we were authenticated when retrieving the information of * this ServerStatusDescriptor. * @param isAuthenticated whether we were authenticated when retrieving the * information of this ServerStatusDescriptor. */ public void setAuthenticated(boolean isAuthenticated) { this.isAuthenticated = isAuthenticated; } /** * Returns the backend descriptors of the server. * @return the backend descriptors of the server. */ public Set<BackendDescriptor> getBackends() { return backends; } /** * Sets the backend descriptors of the server. * @param backends the database descriptors to set. */ public void setBackends(Set<BackendDescriptor> backends) { this.backends = Collections.unmodifiableSet(backends); } /** * Returns the listener descriptors of the server. * @return the listener descriptors of the server. */ public Set<ConnectionHandlerDescriptor> getConnectionHandlers() { return listeners; } /** * Sets the listener descriptors of the server. * @param listeners the listener descriptors to set. */ public void setConnectionHandlers(Set<ConnectionHandlerDescriptor> listeners) { this.listeners = Collections.unmodifiableSet(listeners); } /** * Sets the schema of the server. * @param schema the schema of the server. */ public void setSchema(Schema schema) { this.schema = schema; } /** * Returns the schema of the server. * @return the schema of the server. */ public Schema getSchema() { return schema; } /** * Returns the host name of the server. * @return the host name of the server. */ public String getHostname() { return hostName; } /** * Sets the host name of the server. * @param hostName the host name of the server. */ public void setHostname(String hostName) { this.hostName = hostName; } /** * Returns <CODE>true</CODE> if we are trying to manage the local host and * <CODE>false</CODE> otherwise. * @return <CODE>true</CODE> if we are trying to manage the local host and * <CODE>false</CODE> otherwise. */ public boolean isLocal() { return isLocal; } /** * Sets whether this server represents the local instance or a remote server. * @param isLocal whether this server represents the local instance or a * remote server (in another machine or in another installation on the same * machine). */ public void setIsLocal(boolean isLocal) { this.isLocal = isLocal; } /** * Returns the exceptions that occurred while reading the configuration. * @return the exceptions that occurred while reading the configuration. */ public List<OpenDsException> getExceptions() { return Collections.unmodifiableList(exceptions); } /** * Sets the exceptions that occurred while reading the configuration. * @param exceptions exceptions that occurred while reading the * configuration. */ public void setExceptions(Collection<OpenDsException> exceptions) { this.exceptions.clear(); this.exceptions.addAll(exceptions); } /** * Tells whether the windows service is enabled or not. * @return <CODE>true</CODE> if the windows service is enabled and * <CODE>false</CODE> otherwise. */ public boolean isWindowsServiceEnabled() { return isWindowsServiceEnabled; } /** * Sets whether the windows service is enabled or not. * @param isWindowsServiceEnabled <CODE>true</CODE> if the windows service is * enabled and <CODE>false</CODE> otherwise. */ public void setWindowsServiceEnabled(boolean isWindowsServiceEnabled) { this.isWindowsServiceEnabled = isWindowsServiceEnabled; } /** * Returns whether the server is running under a windows system or not. * @return whether the server is running under a windows system or not. */ public boolean isWindows() { if (isLocal()) { return OperatingSystem.isWindows(); } CustomSearchResult sr = getSystemInformationMonitor(); if (sr == null) { return false; } String os = getFirstValueAsString(sr, "operatingSystem"); return os != null && OperatingSystem.WINDOWS.equals(OperatingSystem.forName(os)); } /** * Method used to compare schemas. * Returns <CODE>true</CODE> if the two schemas are equal and * <CODE>false</CODE> otherwise. * @param schema1 the first schema. * @param schema2 the second schema. * @return <CODE>true</CODE> if the two schemas are equal and * <CODE>false</CODE> otherwise. */ public static boolean areSchemasEqual(Schema schema1, Schema schema2) { if (schema1 == schema2) { return true; } else if (schema2 == null) { return schema1 != null; } else if (schema1 == null) { return false; } return areAttributeTypesEqual(schema1, schema2) && areObjectClassesEqual(schema1, schema2) && areEqual(schema1.getMatchingRules(), schema2.getMatchingRules()) && areEqual(schema1.getSyntaxes(), schema2.getSyntaxes()); } private static boolean areAttributeTypesEqual(Schema schema1, Schema schema2) { final Map<String, AttributeType> attrs1 = schema1.getAttributeTypes(); final Map<String, AttributeType> attrs2 = schema2.getAttributeTypes(); if (attrs1.size() != attrs2.size()) { return false; } for (String name : attrs1.keySet()) { AttributeType attr1 = attrs1.get(name); AttributeType attr2 = attrs2.get(name); if (attr2 == null && !areAttributesEqual(attr1, attr2)) { return false; } } return true; } private static boolean areObjectClassesEqual(Schema schema1, Schema schema2) { final Map<String, ObjectClass> ocs1 = schema1.getObjectClasses(); final Map<String, ObjectClass> ocs2 = schema2.getObjectClasses(); if (ocs1.size() != ocs2.size()) { return false; } for (String name : ocs1.keySet()) { ObjectClass oc1 = ocs1.get(name); ObjectClass oc2 = ocs2.get(name); if (oc2 == null || !areObjectClassesEqual(oc1, oc2)) { return false; } } return true; } /** * Method used to compare attributes defined in the schema. * Returns <CODE>true</CODE> if the two schema attributes are equal and * <CODE>false</CODE> otherwise. * @param schema1 the first schema attribute. * @param schema2 the second schema attribute. * @return <CODE>true</CODE> if the two schema attributes are equal and * <CODE>false</CODE> otherwise. */ private static boolean areAttributesEqual(AttributeType attr1, AttributeType attr2) { return attr1.getOID().equals(attr2.getOID()) && attr1.isCollective() == attr2.isCollective() && attr1.isNoUserModification() == attr2.isNoUserModification() && attr1.isObjectClass() == attr2.isObjectClass() && attr1.isObsolete() == attr2.isObsolete() && attr1.isOperational() == attr2.isOperational() && attr1.isSingleValue() == attr2.isSingleValue() && areEqual(attr1.getApproximateMatchingRule(), attr2.getApproximateMatchingRule()) && areEqual(getDefinitionWithFileName(attr1), getDefinitionWithFileName(attr2)) && areEqual(attr1.getDescription(), attr2.getDescription()) && areEqual(attr1.getEqualityMatchingRule(), attr2.getEqualityMatchingRule()) && areEqual(attr1.getOrderingMatchingRule(), attr2.getOrderingMatchingRule()) && areEqual(attr1.getSubstringMatchingRule(), attr2.getSubstringMatchingRule()) && areEqual(attr1.getSuperiorType(), attr2.getSuperiorType()) && areEqual(attr1.getSyntax(), attr2.getSyntax()) && areEqual(attr1.getSyntax().getOID(), attr2.getSyntax().getOID()) && areEqual(attr1.getExtraProperties().keySet(), attr2.getExtraProperties().keySet()) && areEqual(toSet(attr1.getNormalizedNames()), toSet(attr2.getNormalizedNames())) && areEqual(toSet(attr1.getUserDefinedNames()), toSet(attr2.getUserDefinedNames())); } /** * Method used to compare objectclasses defined in the schema. * Returns <CODE>true</CODE> if the two schema objectclasses are equal and * <CODE>false</CODE> otherwise. * @param schema1 the first schema objectclass. * @param schema2 the second schema objectclass. * @return <CODE>true</CODE> if the two schema objectclasses are equal and * <CODE>false</CODE> otherwise. */ private static boolean areObjectClassesEqual(ObjectClass oc1, ObjectClass oc2) { return oc1.getOID().equals(oc2.getOID()) && oc1.isExtensibleObject() == oc2.isExtensibleObject() && areEqual(getDefinitionWithFileName(oc1), getDefinitionWithFileName(oc2)) && areEqual(oc1.getDescription(), oc2.getDescription()) && areEqual(oc1.getObjectClassType(), oc2.getObjectClassType()) && areEqual(oc1.getOptionalAttributes(), oc2.getOptionalAttributes()) && areEqual(oc1.getRequiredAttributes(), oc2.getRequiredAttributes()) && areEqual(oc1.getSuperiorClasses(), oc2.getSuperiorClasses()) && areEqual(oc1.getExtraProperties().keySet(), oc2.getExtraProperties().keySet()) && areEqual(toSet(oc1.getNormalizedNames()), toSet(oc2.getNormalizedNames())) && areEqual(toSet(oc1.getUserDefinedNames()), toSet(oc2.getUserDefinedNames())); } private static Set<Object> toSet(Iterable<?> iterable) { Set<Object> s = new HashSet<>(); for (Object o : iterable) { s.add(o); } return s; } /** * Commodity method used to compare two objects that might be * <CODE>null</CODE>. * @param o1 the first object. * @param o2 the second object. * @return if both objects are <CODE>null</CODE> returns true. If not returns * <CODE>true</CODE> if both objects are equal according to the Object.equal * method and <CODE>false</CODE> otherwise. */ private static boolean areEqual(Object o1, Object o2) { if (o1 != null) { return o1.equals(o2); } return o2 == null; } /** * Returns the admin connector. * @return the admin connector. */ public ConnectionHandlerDescriptor getAdminConnector() { return adminConnector; } /** * Sets the admin connector. * @param adminConnector the admin connector. */ public void setAdminConnector(ConnectionHandlerDescriptor adminConnector) { this.adminConnector = adminConnector; } /** * Sets the monitoring entry for the entry caches. * @param entryCaches the monitoring entry for the entry caches. */ public void setEntryCachesMonitor(CustomSearchResult entryCaches) { this.entryCaches = entryCaches; } /** * Sets the monitoring entry for the JVM memory usage. * @param jvmMemoryUsage the monitoring entry for the JVM memory usage. */ public void setJvmMemoryUsageMonitor(CustomSearchResult jvmMemoryUsage) { this.jvmMemoryUsage = jvmMemoryUsage; } /** * Sets the root entry of the monitoring tree. * @param rootMonitor the root entry of the monitoring tree. */ public void setRootMonitor(CustomSearchResult rootMonitor) { this.rootMonitor = rootMonitor; runningTime = computeRunningTime(rootMonitor); } private long computeRunningTime(CustomSearchResult rootMonitor) { if (rootMonitor != null) { try { String start = getFirstValueAsString(rootMonitor, START_DATE.getAttributeName()); String current = getFirstValueAsString(rootMonitor, CURRENT_DATE.getAttributeName()); Date startTime = ConfigFromDirContext.utcParser.parse(start); Date currentTime = ConfigFromDirContext.utcParser.parse(current); return currentTime.getTime() - startTime.getTime(); } catch (Throwable t) { return -1; } } return -1; } /** * Returns the running time of the server in milliseconds. Returns -1 if * no running time could be found. * @return the running time of the server in milliseconds. */ public long getRunningTime() { return runningTime; } /** * Sets the monitoring entry for the system information. * @param systemInformation entry for the system information. */ public void setSystemInformationMonitor(CustomSearchResult systemInformation) { this.systemInformation = systemInformation; } /** * Sets the monitoring entry of the work queue. * @param workQueue entry of the work queue. */ public void setWorkQueueMonitor(CustomSearchResult workQueue) { this.workQueue = workQueue; } /** * Returns the monitoring entry for the entry caches. * @return the monitoring entry for the entry caches. */ public CustomSearchResult getEntryCachesMonitor() { return entryCaches; } /** * Returns the monitoring entry for the JVM memory usage. * @return the monitoring entry for the JVM memory usage. */ public CustomSearchResult getJvmMemoryUsageMonitor() { return jvmMemoryUsage; } /** * Returns the root entry of the monitoring tree. * @return the root entry of the monitoring tree. */ public CustomSearchResult getRootMonitor() { return rootMonitor; } /** * Returns the monitoring entry for the system information. * @return the monitoring entry for the system information. */ public CustomSearchResult getSystemInformationMonitor() { return systemInformation; } /** * Returns the monitoring entry for the work queue. * @return the monitoring entry for the work queue. */ public CustomSearchResult getWorkQueueMonitor() { return workQueue; } }