001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2008-2010 Sun Microsystems, Inc.
015 * Portions Copyright 2011-2016 ForgeRock AS.
016 */
017package org.opends.server.replication.server;
018
019import java.util.Date;
020import java.util.Set;
021
022import org.forgerock.i18n.slf4j.LocalizedLogger;
023import org.forgerock.opendj.config.server.ConfigException;
024import org.opends.server.api.MonitorData;
025import org.forgerock.opendj.server.config.server.MonitorProviderCfg;
026import org.opends.server.api.MonitorProvider;
027import org.opends.server.core.DirectoryServer;
028import org.opends.server.replication.common.DSInfo;
029import org.opends.server.replication.common.ServerState;
030import org.opends.server.types.InitializationException;
031
032/**
033 * This class defines a server handler dedicated to the remote LDAP servers
034 * connected to a remote Replication Server.
035 * This class is necessary because we want to provide monitor entries for them
036 * and because the monitor API only allows one entry by MonitorProvider instance
037 * so that no other class can provide the monitor entry for these objects.
038 *
039 * One instance of this class is created for each instance of remote LDAP server
040 * connected to a remote Replication Server.
041 */
042public class LightweightServerHandler
043  extends MonitorProvider<MonitorProviderCfg>
044{
045  /** The tracer object for the debug logger. */
046  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
047
048  private final ReplicationServerHandler replServerHandler;
049
050  /** All the information for this DS. */
051  private final DSInfo dsInfo;
052
053  /**
054   * Creates a new LightweightServerHandler with the provided serverId,
055   * connected to the remote Replication Server represented by
056   * replServerHandler.
057   *
058   * @param replServerHandler
059   *          The server handler of the RS this remote DS is connected to
060   * @param dsInfo
061   *          all the info for the represented DS
062   */
063  public LightweightServerHandler(ReplicationServerHandler replServerHandler,
064      DSInfo dsInfo)
065  {
066    this.replServerHandler = replServerHandler;
067    this.dsInfo = dsInfo;
068
069    if (logger.isTraceEnabled())
070    {
071      debugInfo("()");
072    }
073  }
074
075  /**
076   * Creates a DSInfo structure representing this remote DS.
077   * @return The DSInfo structure representing this remote DS
078   */
079  public DSInfo toDSInfo()
080  {
081    return dsInfo;
082  }
083
084  /**
085   * Get the serverID associated with this LDAP server / directory server.
086   *
087   * @return The serverId.
088   */
089  public int getServerId()
090  {
091    return dsInfo.getDsId();
092  }
093
094  /**
095   * Start this server handler processing.
096   */
097  public void startHandler()
098  {
099    if (logger.isTraceEnabled())
100    {
101      debugInfo("start");
102    }
103    DirectoryServer.deregisterMonitorProvider(this);
104    DirectoryServer.registerMonitorProvider(this);
105  }
106
107  /**
108   * Stop this server handler processing.
109   */
110  public void stopHandler()
111  {
112    if (logger.isTraceEnabled())
113    {
114      debugInfo("stop");
115    }
116    DirectoryServer.deregisterMonitorProvider(this);
117  }
118
119  private void debugInfo(String message)
120  {
121    final ReplicationServerDomain domain = replServerHandler.getDomain();
122    logger.trace("In " + domain.getLocalRSMonitorInstanceName()
123        + " LWSH for remote server " + getServerId() + " connected to:"
124        + replServerHandler.getMonitorInstanceName() + " " + message);
125  }
126
127  /** {@inheritDoc} */
128  @Override
129  public void initializeMonitorProvider(MonitorProviderCfg configuration)
130                          throws ConfigException,InitializationException
131  {
132    // Nothing to do for now
133  }
134
135  /**
136   * Retrieves the name of this monitor provider.  It should be unique among all
137   * monitor providers, including all instances of the same monitor provider.
138   *
139   * @return  The name of this monitor provider.
140   */
141  @Override
142  public String getMonitorInstanceName()
143  {
144    return "Connected directory server DS(" + dsInfo.getDsId() + ") "
145        + dsInfo.getDsUrl()
146        + ",cn=" + replServerHandler.getMonitorInstanceName();
147  }
148
149  @Override
150  public MonitorData getMonitorData()
151  {
152    MonitorData attributes = new MonitorData(8);
153
154    final int serverId = dsInfo.getDsId();
155    final ReplicationServerDomain domain = replServerHandler.getDomain();
156    attributes.add("server-id", serverId);
157    attributes.add("domain-name", domain.getBaseDN());
158    attributes.add("connected-to", replServerHandler.getMonitorInstanceName());
159
160    // Retrieves the topology counters
161    final ReplicationDomainMonitorData md = domain.getDomainMonitorData();
162    ServerState remoteState = md.getLDAPServerState(serverId);
163    if (remoteState == null)
164    {
165      remoteState = new ServerState();
166    }
167
168    Set<String> serverState = remoteState.toStringSet();
169    if (serverState.isEmpty())
170    {
171      attributes.add("server-state", "unknown");
172    }
173    else
174    {
175      attributes.add("server-state", serverState);
176    }
177
178    // Oldest missing update
179    long approxFirstMissingDate = md.getApproxFirstMissingDate(serverId);
180    if (approxFirstMissingDate > 0)
181    {
182      attributes.add("approx-older-change-not-synchronized", new Date(approxFirstMissingDate));
183      attributes.add("approx-older-change-not-synchronized-millis", approxFirstMissingDate);
184    }
185    attributes.add("missing-changes", md.getMissingChanges(serverId));
186    attributes.add("approximate-delay", md.getApproxDelay(serverId));
187
188    return attributes;
189  }
190}