⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 defaultmoserver.java

📁 用snmp4j实现的agent,代码比较多,但是很值得一看,尤其是对于要用SNMP监控信息的编程者,可以仔细研究一下里面的代码.
💻 JAVA
字号:
/*_############################################################################
  _##
  _##  SNMP4J-Agent - DefaultMOServer.java
  _##
  _##  Copyright (C) 2005-2008  Frank Fock (SNMP4J.org)
  _##
  _##  Licensed 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.snmp4j.agent;

import java.util.*;
import java.util.Map.Entry;

import org.snmp4j.log.*;
import org.snmp4j.smi.*;

/**
 * The default MO server implementation uses a sorted map for the managed object
 * registry.
 *
 * @author Frank Fock
 * @version 1.2
 */
public class DefaultMOServer implements MOServer {

  private static final LogAdapter logger =
      LogFactory.getLogger(DefaultMOServer.class);

  private Set contexts;
  private SortedMap registry;
  private Map lockList;
  private Map lookupListener;
  private transient Vector contextListeners;
  private UpdateStrategy updateStrategy;


  public DefaultMOServer() {
    this.registry =
        Collections.synchronizedSortedMap(new TreeMap(new MOScopeComparator()));
    this.contexts = new LinkedHashSet(10);
    this.lockList = new Hashtable(10);
  }

  public ManagedObject lookup(MOQuery query) {
    SortedMap scope = registry.tailMap(query);
    Iterator it = scope.entrySet().iterator();
    while (it.hasNext()) {
      Map.Entry entry = (Entry) it.next();
      MOScope key = (MOScope) entry.getKey();
      if (!DefaultMOContextScope.isContextMatching(query.getScope(), key)) {
        continue;
      }
      Object o = entry.getValue();
      if (o instanceof ManagedObject) {
        ManagedObject mo = (ManagedObject) o;
        MOScope moScope = mo.getScope();
        if (query.getScope().isOverlapping(moScope)) {
          fireQueryEvent(mo, query);
          if (mo instanceof UpdatableManagedObject) {
            checkForUpdate((UpdatableManagedObject)mo, query);
          }
          if (query.matchesQuery(mo)) {
            fireLookupEvent(mo, query);
            return mo;
          }
        }
      }
      else if (logger.isWarnEnabled()) {
        logger.warn("Object looked up is not a ManagedObject: "+o);
      }
    }
    return null;
  }

  /**
   * Checks {@link #updateStrategy} whether the queried managed object needs
   * to be updated. This method is called on behalf of
   * {@link #lookup(MOQuery query)} after {@link #fireQueryEvent} and before
   * {@link #fireLookupEvent} is being called.
   *
   * @param mo
   *    an UpdatableManagedObject instance.
   * @param query
   *    the query that is interested in content of <code>mo</code>.
   * @since 1.2
   */
  protected void checkForUpdate(UpdatableManagedObject mo, MOQuery query) {
    if (updateStrategy != null) {
      if (updateStrategy.isUpdateNeeded(this, mo, query)) {
        if (logger.isDebugEnabled()) {
          logger.debug("Updating UpdatableManagedObject "+mo+
                       " on behalf of query "+query);
        }
        mo.update(query);
      }
    }
  }

  /**
   * Returns the <code>ManagedObject</code> with the specified <code>OID</code>
   * and registered in the supplied context.
   * <p>
   * Note: The query used to lookup the managed object will indicate an intended
   * read-only access for the {@link MOServerLookupEvent}s fired on behalf of
   * this method.
   * @param key
   *    the OID identifying the key (lower bound) of the
   *    <code>ManagedObject</code>.
   * @param context
   *    the optional context to look in. A <code>null</code> value searches
   *    in all contexts.
   * @return
   *    the <code>ManagedObject</code> instance or <code>null</code> if such
   *    an instance does not exists.
   * @since 1.1
   */
  public ManagedObject getManagedObject(OID key, OctetString context) {
    MOContextScope scope =
        new DefaultMOContextScope(context, key, true, key, true);
    return lookup(new DefaultMOQuery(scope));
  }

  protected void fireLookupEvent(ManagedObject mo, MOQuery query) {
    if (lookupListener != null) {
      List l = (List) lookupListener.get(mo);
      if (l != null) {
        MOServerLookupEvent event = new MOServerLookupEvent(this, mo, query);
        for (Iterator it = l.iterator(); it.hasNext(); ) {
          MOServerLookupListener item = (MOServerLookupListener) it.next();
          item.lookupEvent(event);
        }
      }
    }
  }

  protected void fireQueryEvent(ManagedObject mo, MOQuery query) {
    if (lookupListener != null) {
      List l = (List) lookupListener.get(mo);
      if (l != null) {
        MOServerLookupEvent event = new MOServerLookupEvent(this, mo, query);
        for (Iterator it = l.iterator(); it.hasNext(); ) {
          MOServerLookupListener item = (MOServerLookupListener) it.next();
          item.queryEvent(event);
        }
      }
    }
  }

  public OctetString[] getContexts() {
    return (OctetString[]) contexts.toArray(new OctetString[0]);
  }

  public boolean isContextSupported(OctetString context) {
    if ((context == null) || (context.length() == 0)) {
      return true;
    }
    return contexts.contains(context);
  }

  public SortedMap getRegistry() {
    return registry;
  }

  /**
   * Gets the update strategy for {@link UpdatableManagedObject}s. If the
   * strategy is <code>null</code> no updates will be performed on behalf
   * of calls to {@link #lookup}.
   *
   * @return
   *    the current UpdateStrategy instance or <code>null</code> if no
   *    strategy is active.
   * @since 1.2
   * @see #lookup
   */
  public UpdateStrategy getUpdateStrategy() {
    return updateStrategy;
  }

  /**
   * Sets the update strategy for {@link UpdatableManagedObject}s. If the
   * strategy is <code>null</code> no updates will be performed on behalf
   * of calls to {@link #lookup}.
   *
   * @param updateStrategy
   *    the new UpdateStrategy instance or <code>null</code> if no
   *    updates should be performed.
   * @since 1.2
   * @see #lookup
   */
  public void setUpdateStrategy(UpdateStrategy updateStrategy) {
    this.updateStrategy = updateStrategy;
  }

  public void register(ManagedObject mo, OctetString context)
      throws DuplicateRegistrationException
  {
    if (context == null) {
      MOContextScope contextScope =
          new DefaultMOContextScope(null, mo.getScope());
      ManagedObject other = lookup(new DefaultMOQuery(contextScope));
      if (other != null) {
        throw new DuplicateRegistrationException(contextScope,
                                                 other.getScope());
      }
      registry.put(mo.getScope(), mo);
      if (logger.isInfoEnabled()) {
        logger.info("Registered MO "+mo+" in default context with scope "+
                     mo.getScope());
      }
    }
    else {
      DefaultMOContextScope contextScope =
          new DefaultMOContextScope(context, mo.getScope());
      ManagedObject other = lookup(new DefaultMOQuery(contextScope));
      if (other != null) {
        throw new DuplicateRegistrationException(contextScope, other.getScope());
      }
      registry.put(contextScope, mo);
      if (logger.isInfoEnabled()) {
        logger.info("Registered MO "+mo+" in context "+context+" with scope "+
                     contextScope);
      }
    }
  }

  public void unregister(ManagedObject mo, OctetString context) {
    MOScope key;
    if (context == null) {
      key = mo.getScope();
    }
    else {
      key = new DefaultMOContextScope(context, mo.getScope());
    }
    Object r = registry.remove(key);
    if (r == null) {
      // OK, may be the upper bound of the scope has been adjusted so we need to
      // check that by iterating
      SortedMap tailMap = registry.tailMap(key);
      for (Iterator it = tailMap.entrySet().iterator(); it.hasNext();) {
        Map.Entry entry = (Entry) it.next();
        MOScope entryKey = (MOScope) entry.getKey();
        if ((entry.getValue().equals(mo)) &&
            (((context != null) &&
              (entryKey instanceof MOContextScope) &&
              (context.equals(((MOContextScope)entryKey).getContext()))) ||
             (context == null))) {
          r = entry.getValue();
          it.remove();
          break;
        }
      }
    }
    if (logger.isInfoEnabled()) {
      if (r != null) {
        logger.info("Removed registration " + r + " for " + mo +
                    " in context '" + context + "' sucessfully");
      }
      else {
        logger.warn("Removing registration failed for " + mo +
                    " in context '" + context + "'");
      }
    }
  }

  public void addContext(OctetString context) {
    contexts.add(context);
  }

  public void removeContext(OctetString context) {
    contexts.remove(context);
  }

  public synchronized void lock(Object owner, ManagedObject managedObject) {
    Lock lock;
    do {
      lock = (Lock) lockList.get(managedObject);
      if (lock == null) {
        lockList.put(managedObject, new Lock(owner));
        if (logger.isDebugEnabled()) {
          logger.debug("Acquired lock on "+managedObject+ " for "+owner);
        }
      }
      else if (lock.getOwner() != owner) {
        try {
          if (logger.isDebugEnabled()) {
            logger.debug("Waiting for lock on "+managedObject);
          }
          wait();
        }
        catch (InterruptedException ex) {
          logger.warn("Waiting for lock on "+managedObject+
                      " has been interrupted!");
          break;
        }
      }
      else {
        lock.add();
        if (logger.isDebugEnabled()) {
          logger.debug("Added lock on "+managedObject+ " for "+owner);
        }
        return;
      }
    }
    while (lock != null);
  }

  public synchronized void unlock(Object owner, ManagedObject managedObject) {
    Lock lock = (Lock) lockList.get(managedObject);
    if (lock == null) {
      return;
    }
    if (lock.getOwner() != owner) {
      if (logger.isDebugEnabled()) {
        logger.debug("Object '" + owner + "' is not owner of lock: " + lock);
      }
      return;
    }
    if (lock.remove()) {
      lockList.remove(managedObject);
      if (logger.isDebugEnabled()) {
        logger.debug("Removed lock on "+managedObject+ " by "+owner);
      }
      notify();
    }
  }

  public Iterator iterator() {
    SortedMap m = getRegistry();
    synchronized (m) {
      SortedMap r = new TreeMap(new MOScopeComparator());
      r.putAll(m);
      return r.entrySet().iterator();
    }
  }

  public synchronized void addLookupListener(MOServerLookupListener listener,
                                             ManagedObject mo) {
    if (lookupListener == null) {
      lookupListener = Collections.synchronizedMap(new HashMap());
    }
    List l = (List) lookupListener.get(mo);
    if (l == null) {
      l = Collections.synchronizedList(new LinkedList());
      lookupListener.put(mo, l);
    }
    l.add(listener);
  }

  public synchronized boolean removeLookupListener(MOServerLookupListener listener,
      ManagedObject mo)
  {
    if (lookupListener != null) {
      List l = (List) lookupListener.get(mo);
      if (l != null) {
        return l.remove(listener);
      }
    }
    return false;
  }

  public synchronized void addContextListener(ContextListener l) {
    if (contextListeners == null) {
      contextListeners = new Vector(2);
    }
    contextListeners.add(l);
  }

  public synchronized void removeContextListener(ContextListener l) {
    if (contextListeners != null) {
      contextListeners.remove(l);
    }
  }

  protected void fireContextChanged(ContextEvent event) {
    if (contextListeners != null) {
      Vector listeners = contextListeners;
      int count = listeners.size();
      for (int i = 0; i < count; i++) {
        ((ContextListener) listeners.elementAt(i)).contextChanged(event);
      }
    }
  }

  public String toString() {
    StringBuffer buf = new StringBuffer(getClass().getName());
    buf.append("[contexts="+contexts);
    buf.append("[keys={");
    for (Iterator it = registry.keySet().iterator(); it.hasNext();) {
      MOScope scope = (MOScope) it.next();
      buf.append(scope.getLowerBound());
      if (scope.isLowerIncluded()) {
        buf.append("+");
      }
      buf.append("-");
      buf.append(scope.getUpperBound());
      if (scope.isUpperIncluded()) {
        buf.append("+");
      }
      if (scope instanceof MOContextScope) {
        buf.append("("+((MOContextScope)scope).getContext()+")");
      }
      if (it.hasNext()) {
        buf.append(",");
      }
    }
    buf.append("}");
    buf.append(",registry="+registry);
    buf.append(",lockList="+lockList);
    buf.append(",lookupListener="+lookupListener);
    buf.append("]");
    return buf.toString();
  }

  static class Lock {
    private Object owner;
    private long creationTime;
    private int count = 0;

    private Lock() {
      this.creationTime = System.currentTimeMillis();
      this.count = 0;
    }

    Lock(Object owner) {
      this();
      this.owner = owner;
    }

    public long getCreationTime() {
      return creationTime;
    }

    public int getCount() {
      return count;
    }

    public synchronized void add() {
      count++;
    }

    public synchronized boolean remove() {
      return (--count) <= 0;
    }

    public Object getOwner() {
      return owner;
    }
  }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -