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