Package de.desy.tine.alarmUtils

Source Code of de.desy.tine.alarmUtils.AlarmMonitorCallback$GetAlarmsCallback

package de.desy.tine.alarmUtils;

import java.util.*;
import de.desy.tine.client.*;
import de.desy.tine.dataUtils.TDataType;
import de.desy.tine.definitions.TErrorList;
import de.desy.tine.server.alarms.*;
import de.desy.tine.server.logger.DbgLog;
import de.desy.tine.server.logger.MsgLog;

public class AlarmMonitorCallback implements TLinkCallback
{
  private long alarmDepth = 7200000; // depth in milliseconds (2 hours)
  private long timeNow = 0;
  private String ctx;
  private String srv = null;
  private String sys;
  private int sev = 7;
  private long lastAcquired = 0;
  private long lastNotified = 0;
  private int lastAcquiredTableEntry = -1;
  private LinkedList<TAlarmMessage[]> almTbl = new LinkedList<TAlarmMessage[]>();
  private TAlarmMessage[] alms = null;
  private int linkStatus;
  private long almTimeStamp = 0;
  private AlarmMonitorHandler almHandler = null;
  private AlarmMonitor almMonitor = null;
  private boolean almStateChanged = false;
  private boolean includeTerminated = false;
  private boolean acquireAll = false;
  private boolean needsToNotify = false;
  private class GetAlarmsCallback implements TLinkCallback
  {
    TAlarmMessage[] ams = null;
    public void setAlarms(TAlarmMessage[] ams) { this.ams = ams; }
    public TAlarmMessage[] getAlarms() { return ams; }
    public boolean pending = false;
    protected int lastnalarms = 0;
    public void callback(TLink link)
    {
      int cc;
      if ((cc=link.getLinkStatus()) != 0)
      {
        MsgLog.log("GetAlarmsCallback","getAlarms for " + link.getDeviceName() + " failed",cc,null,0);
        ams = null;
      }
      else
      {
        TDataType amst = link.getOutputDataObject();
        int n = amst.getArrayLength();
        int nret = amst.getCompletionLength();
        // the link god-damn worked! so it's okay to update the friggen lastAcquired !!!!
        almTimeStamp = thisTimeStamp; //timeNow;
        if (nret > 0)
        {
          almTimeStamp = link.getLastTimeStamp();
          lastAcquired = link.getLastTimeStamp(); //timeNow;
        }
        if (debugOutput)
        {
          Date d = new Date(almTimeStamp);
          System.out.println(link.getDeviceName()+" "+n+" alarms requested; "+nret+" returned; alarm time "+d.toString());
        }
        lastnalarms = nret;
        if (TLinkFactory.debugLevel > 0)
          DbgLog.log("GetAlarmsCallback","getAlarms for "+link.getDeviceName()+" : "+nret+" alarms returned ");
        if (nret == 0) ams = null;
        else if (nret < n)
        {
          TAlarmMessage[] a = new TAlarmMessage[nret];
          for (int i=0; i<nret; i++) a[i] = ams[i];
          ams = a;
        }
        if (ams != null) Arrays.sort(ams);
        updateAlarmList(ams);
        if (almStateChanged)
        {
          needsToNotify = true;
          if (TLinkFactory.debugLevel > 0)
            DbgLog.log("GetAlarmsCallback", "signal need to notify for "+link.getDeviceName());
        }
      }
      pending = false;
      link.close();
    }
  }
  private GetAlarmsCallback getAlarmsCallback = new GetAlarmsCallback();
  public void setAlarmMonitorHandler(AlarmMonitorHandler myHandler)
  {
    almHandler = myHandler;
  }
  public void setAlarmMonitor(AlarmMonitor myMonitor)
  {
    almMonitor = myMonitor;
    if (almMonitor != null) almHandler = almMonitor.getAmHdlr();
  }
  public AlarmMonitorCallback(String context, String server, String system, int severity)
  {
    this(context,server,system,severity,false,false);
  }
  public AlarmMonitorCallback(String context, String server, String system, int severity,boolean includeTerminated,boolean acquireAll)
  {
    ctx = context;
    srv = server;
    sys = system;
    sev = severity;
    this.includeTerminated = includeTerminated;
    this.acquireAll = acquireAll;
    String dbgval = System.getProperty("alarmUtils.debug");
    if (dbgval != null)
    {
      if (dbgval.compareToIgnoreCase("true") == 0) debugOutput = true;
      else
      {
        try {if (Integer.parseInt(dbgval) > 0) debugOutput = true;} catch (Exception e) {};
      }
    }
  }
  private long getAlarmSetTimeStamp(TAlarmMessage[] almset)
  {
    if (almset == null) return 0;
    long ts = 0, ats;
    for (int i=0; i<almset.length; i++)
    {
      ats = almset[i].getTimeStamp();
      if (ats > ts) ts = ats;
    }
    return ts;
  }
  private void updateAlarmList(TAlarmMessage[] newAlarms)
  {
    almStateChanged = true; // just set it to true
    synchronized (almTbl)
    {
      if (!isIncludeTerminated())
      {
        almTbl.clear();
        lastAcquiredTableEntry = -1;
      }
      if (newAlarms != null)
      {
        almTbl.add(newAlarms);
      }
      List<TAlarmMessage> almsets = new ArrayList<TAlarmMessage>();
      ListIterator<TAlarmMessage[]> it = almTbl.listIterator(0);
      while (it.hasNext())
      {
        TAlarmMessage[] m = it.next();
        if (getAlarmSetTimeStamp(m) > timeNow - alarmDepth)
        {
          for (int i = 0; i < m.length; i++)
          { // TODO: maybe use a hash list to avoid double entries ...
            almsets.add(m[i]);
          }
        }
        else
        { // remove old alarms from the current table
          almStateChanged = true; // this is already true !?
          it.remove();
          if (lastAcquiredTableEntry >= 0) lastAcquiredTableEntry--;
        }
      }
      alms = almsets.isEmpty() ? null : almsets.toArray(new TAlarmMessage[almsets.size()]);
    }
  }
  private void notifyCaller()
  {
    needsToNotify = false;
    lastNotified = lastAcquired;   
    if (almHandler != null) almHandler.alarmsHandler(almMonitor);
  }
  private boolean debugOutput = false;
  private long lastCallStart = 0;
  private long lastCallStop = 0;
  private long thisTimeStamp;
  private int idleCount = 0;
  private int waitPendingCount = 0;
  private int linkErrors = 0;
  private static final int ERROR_THRESHOLD = 5;
  private static final int NALARMS_CUSHION = 10;
  private int numDisabledAlarms;
  public int getNumberDisableAlarms() { return numDisabledAlarms; }
  public void callback(TLink link)
  { // callback of 'NALARMS' or 'NUMALARMS'
    if (almMonitor == null)
    {
      thisTimeStamp = lastCallStart = lastCallStop = waitPendingCount = 0;
      return;
    }
    linkStatus = link.getLinkStatus();
    if (linkStatus != 0)
    {
      if (TLinkFactory.debugLevel > 0) DbgLog.log("AlarmMonitorCallback",link.devName + " alarm monitor callback : " + TErrorList.getErrorString(linkStatus));
      if (linkErrors++ > ERROR_THRESHOLD)
      {
        almMonitor.setConnectionStatus(linkStatus);
        notifyCaller();
        linkErrors = 0;
      }
      return;
    }
    almMonitor.setConnectionStatus(0);
    linkErrors = 0;
    if (getAlarmsCallback.pending)
    {
      waitPendingCount++;
      if (TLinkFactory.debugLevel > 0) DbgLog.log("AlarmMonitorCallback",link.devName + " still acquiring last alarm set");
      return;
    }
    if (TLinkFactory.debugLevel > 0 && waitPendingCount > 0)
      DbgLog.log("AlarmMonitorCallback",link.devName+" acquiring new alarm set after "+waitPendingCount+" attempts");
    waitPendingCount = 0;
    // don't suppress the heartbeats (use them to clear old alarms)
    boolean acquire = false;
    boolean reacquire = false;
    thisTimeStamp = link.getLastTimeStamp();
    if (thisTimeStamp > almTimeStamp)
    { // set in getAlarmsCallback : almTimeStamp = thisTimeStamp;
      acquire = true;
      if (TLinkFactory.debugLevel > 0)
        DbgLog.log("AlarmMonitorCallback",link.devName + " signal reason to acquire new alarm set (timestamp "+thisTimeStamp+" vs "+almTimeStamp+")");
      idleCount = 0;
    }
    else
    { // keep track of number of passes with 'nothing to do' (reset in getLastAcquiredAlarms)
      // n.b.: this is probably NOT necessary ...
      if (includeTerminated)
      {
        idleCount++;
        if (idleCount > 60)
        {
          //needsToNotify = true; // set acquire to true if problems 'missing' still persist
          reacquire = acquire = true;
          idleCount = 0;
          if (debugOutput)
            System.out.println(sys+" : signalling idle phase readout of last alarms ...");
        }
      }
    }
    TDataType dt = link.getOutputDataObject();
    int[] n = new int[dt.getArrayLength()];
    dt.getData(n);
    numDisabledAlarms = n[2]; // n.b. all of what follows assumes we're talking to the CAS
    synchronized (almTbl)
    {
      // almStateChanged = false; <- don't do this here (only when getLastAcquired is called)
      //timeNow = System.currentTimeMillis();
      timeNow = thisTimeStamp;
      //TODO: tighten this up a bit ....
      if (includeTerminated)
      { // incremental acquire
        if (n[0] > 0 || reacquire)
        { // there are alarms still showing
          if (acquire)
          { // there are new alarms to get ! (n.b. start and stop times are inclusive!)
            if (TLinkFactory.debugLevel > 0)
              DbgLog.log("AlarmMonitorCallback",link.devName+" acquiring new alarm set ("+n[0]+" alarms");
            if (lastAcquired == 0)
            {
              timeNow = System.currentTimeMillis();
              lastAcquired = timeNow - alarmDepth;
            }
            int nget = n[0] + NALARMS_CUSHION;
            if (n[0] == 0) nget += getAlarmsCallback.lastnalarms;
            getAlarmsCallback.pending = true;
            if (debugOutput)
            { // turn on if problems persist ....
              System.out.print(sys+" ("+n[0]+") alarms -> acquire "+nget );
              Date d = new Date(lastAcquired);
              System.out.print(" (range: "+d.toString()+" to ");
              d.setTime(timeNow);
              System.out.println(d.toString()+")");
            }
            lastCallStart = lastAcquired; lastCallStop = timeNow;
            if (reacquire)
            { // oh, desperation .......
              lastCallStart -= 60000;
              lastCallStop = System.currentTimeMillis();
            }
            getAlarmsCallback.ams = TAlarmSystem.getAlarmsAsync(nget, ctx, srv, sys, lastCallStart, lastCallStop, sev, includeTerminated, acquireAll, getAlarmsCallback);
            if (getAlarmsCallback.ams == null)
            {
              DbgLog.log("AlarmMonitorCallback",link.devName+"getAlarmsAsync failed !");
              getAlarmsCallback.pending = false;
            }
          }
          else
          { // nothing to do
            if (needsToNotify)
            {
              if (TLinkFactory.debugLevel > 0)
                DbgLog.log("AlarmMonitorCallback",link.devName + " notifying caller of results");
              notifyCaller();
            }
            return;
          }
        }
        else
        { // no alarms to show
          if (acquire)
          {
            if (TLinkFactory.debugLevel > 0)
              DbgLog.log("AlarmMonitorCallback",link.devName+" no new alarms to acquire (alarms to remove!); last = "+new Date(lastAcquired).toString());
            //if (!needsToNotify) lastAcquired = timeNow;
            updateAlarmList(null);
            needsToNotify = true;
            almTimeStamp = thisTimeStamp;
          }
          else
          { // nothing to do
            if (needsToNotify)
            {
              if (TLinkFactory.debugLevel > 0)
                DbgLog.log("AlarmMonitorCallback",link.devName+" notifying caller of results (no new alarms)");
              notifyCaller();
            }
            return;
          }
        }
      }
      else
      { // not includeTerminated: just get this set and update
        if (n[1] > 0)
        { // there are alarms showing
          if (acquire)
          { // this should always be true for the non-terminated case
            getAlarmsCallback.pending = true;
            getAlarmsCallback.ams = TAlarmSystem.getAlarmsAsync(n[0]+NALARMS_CUSHION, ctx, srv, sys, timeNow - alarmDepth, timeNow, sev, includeTerminated,getAlarmsCallback);
            if (getAlarmsCallback.ams == null)
            {
              DbgLog.log("AlarmMonitorCallback",link.devName+"getAlarmsAsync failed !");
              getAlarmsCallback.pending = false;
            }
          }
          else
          { // nothing to do
            if (needsToNotify)
            {
              DbgLog.log("AlarmMonitorCallback",link.devName+"notifying caller of results (post-callback)");
              notifyCaller();
            }
            return;
          }
        }
        else
        { // no alarms to show
          if (acquire)
          {
            //if (!needsToNotify) lastAcquired = timeNow;
            updateAlarmList(null);
            needsToNotify = true;
          }
          else
          { // nothing to do
            if (needsToNotify) notifyCaller();
            return;
          }
        }
      }
    }
  }
  public TAlarmMessage[] getAlarms()
  {
    return alms;
  }
  public TAlarmMessage[] getLastAcquiredAlarms()
  {
    synchronized (almTbl)
    {
      almStateChanged = false; // is being read by caller
      int nalmSets = almTbl.size();
      int first = lastAcquiredTableEntry;
      if (nalmSets == 0) return null;
      if (first > nalmSets - 1)
      {
        DbgLog.log("getLastAcquiredAlarms",getSubsystem()+ " last acquired index " + first + " larger than alarm table size : " + almTbl.size());
        first = 0;
      }
      int last = nalmSets - 2; // was nalmSets -1;
      if (last < 0) last = 0;
      if (first < 0) first = 0;
      List<TAlarmMessage> lastLst = new ArrayList<TAlarmMessage>();
      ListIterator<TAlarmMessage[]> it = almTbl.listIterator(first);
      while (it.hasNext())
      {
        TAlarmMessage[] m = it.next();
        for (int i = 0; i < m.length; i++)
        {
          lastLst.add(m[i]);
          if (debugOutput)
          { // turn on if problems persist ...
            if ((m[i].getAlarmDescriptor() & TAlarmDescriptor.NEW) == TAlarmDescriptor.NEW ||
                (m[i].getAlarmDescriptor() & TAlarmDescriptor.TERMINATE) == TAlarmDescriptor.TERMINATE)
            {
              Date d = new Date(m[i].getTimeStamp());
              System.out.print(m[i].getAlarmSystem()+" "+m[i].getDevice()+" "+m[i].getAlarmTag()+" "+
                  m[i].getAlarmDescriptorAsString()+" "+d.toString());
              d.setTime(lastCallStart); System.out.print(" (range : "+d.toString());
              d.setTime(lastCallStop); System.out.println(" to "+d.toString()+")");
            }
          }
        }
      }
      lastAcquiredTableEntry = last;
      return lastLst.toArray(new TAlarmMessage[lastLst.size()]);
    }
  }
  public String getContext()
  {
    return ctx;
  }
  public long getLastAcquired()
  {
    return lastAcquired;
  }
  public String getServer()
  {
    return srv;
  }
  public String getSubsystem()
  {
    return sys;
  }
  public boolean isIncludeTerminated()
  {
    return includeTerminated;
  }
  public void setIncludeTerminated(boolean includeTerminated)
  {
    this.includeTerminated = includeTerminated;
  }
  public void setAcquireAll(boolean value)
  {
    acquireAll = value;
  }
}
TOP

Related Classes of de.desy.tine.alarmUtils.AlarmMonitorCallback$GetAlarmsCallback

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.