Skip to content
MonitorComponent.java 14.4 KiB
Newer Older
/**
 *
 */
package alma.TMCDB.MonitorCollectorImpl;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import org.omg.CORBA.Any;
import org.omg.CORBA.InterfaceDef;
import org.omg.CORBA.InterfaceDefHelper;
import org.omg.CORBA.Object;
import org.slf4j.event.Level;
import alma.ACS.CBdouble;
import alma.ACS.CBdoubleHelper;
import alma.ACS.CBdoubleOperations;
import alma.ACS.CBdoublePOA;
import alma.ACS.CBdoublePOATie;
import alma.ACS.CBlongPOA;
import alma.ACS.CallbackHelper;
import alma.ACS.CharacteristicComponent;
import alma.ACS.CharacteristicComponentDesc;
import alma.ACS.NoSuchCharacteristic;
import alma.ACS.Property;
import alma.ACS.PropertyDesc;
import alma.TMCDB.MonitorBlob;
import alma.TMCDB.MonitorDataBlock;
import alma.TMCDB.doubleBlobData;
import alma.TMCDB.doubleBlobDataSeqHolder;
import alma.TMCDB.longBlobData;
import alma.TMCDB.longBlobDataSeqHolder;
import alma.acs.container.ContainerServices;
import alma.acs.logging.AcsLogLevel;
import alma.acs.time.TimeHelper;
import alma.acstime.Epoch;
import alma.TMCDB.MonitorCollectorImpl.MonitorPoint;

/**
 * @author Claudio Tanci
 *
 */
public class MonitorComponent {

	private ContainerServices containerServices_m;
	private CharacteristicComponent component_m;
	private CharacteristicComponentDesc compDesc_m;
	private int numOfProp_m=0;
	private Logger m_logger;
	private boolean monitoring_m = false;

	/*
	 *  Time of monitoring start
	 *	TODO which Java type? is CORBA::ULongLong in acsCommonC.h
	 *  here is a long for compatibility with monitorDataBlock_m.startTime et similar
	 */
	private Epoch m_monitoringStartTime =null;

	/*
	 * List of monitored points, in C++ is a list with seqIndex_m as index. Here
	 * I'll use an HashMap with names as keys for the moment
	 */
	private Map<String, MonitorPointHelper> monitorPoints_m =null;

	/*
	 * Index for each monitored points in monitorDataBlock_m.monitorBlobs[].
	 * Names as keys.
	 * TODO: evaluate monitorPoints_m implementation as an array as in C++ implementation to get rid of this.
	 */
	private Map<String, Integer> monitorBlocksIndex_m = new HashMap<String, Integer>();
	private MonitorDataBlock monitorDataBlock_m =null;

	/**
	 * @param comp
	 * @param m_containerServices
	 */
	public MonitorComponent(CharacteristicComponent comp,
			ContainerServices m_containerServices) {

		containerServices_m = m_containerServices;
		component_m = comp;
		compDesc_m = comp.descriptor();
		numOfProp_m = compDesc_m.properties.length;
		monitorDataBlock_m = new MonitorDataBlock();
		monitorDataBlock_m.componentName = comp.name();
		monitorDataBlock_m.startTime = 0L;
		monitorDataBlock_m.stopTime = 0L;
		m_logger=containerServices_m.getLogger();
	}

//	public void finalize() {
//		// TODO log this, if this happen there is a bug somewhere as close() as to be called.
//		close();
//	}

	/*
	 * Implements an C++ implementation destructor equivalent.
	 * To be called when the monitor point is not used anymore.
	 */
	public void close() {
		for (String propName : monitorPoints_m.keySet()) {
			monitorPoints_m.get(propName).stopMonitoring();
			monitorPoints_m.get(propName).deactivate(containerServices_m);
		}
		monitorPoints_m.clear();
	}

	public void enable_archiving(String propertyName) {

		String prop = component_m.name()+":"+propertyName;

		m_logger.info("MonitorComponent.enable_archiving "+prop);

		for (String propName : monitorPoints_m.keySet()) {
			if (monitorPoints_m.get(propName).getPropertyName().equals(prop))
				monitorPoints_m.get(propName).enable_archiving();
		}
	}

	public synchronized void addAllProperties() {

		m_logger.log(AcsLogLevel.DEBUG,"MonitorComponent.addAllProperties");
		int monitored=0;
		String[]  ty =new String[numOfProp_m];
		String[]  na =new String[numOfProp_m];
		Property[] pro = new Property[numOfProp_m];
		long[] archInt = new long[numOfProp_m];
		// TODO: what implementation of List/Collection for monitorPoints_m?
		if (numOfProp_m>0) {
	
			for (PropertyDesc p : compDesc_m.properties) {
	
				/*
				 * Type of property, for reference the following data could be used:
				 * type.toString()      IOR:000000000000002649444C[...]
				 * type.id()            IDL:alma/ACS/ROlong:1.0
				 * type.name()          ROlong
				 * type.type().toString alma::ACS::ROlong
				 */
				Object idef = p.property_ref._get_interface_def();
				InterfaceDef type = InterfaceDefHelper.narrow(idef);
	
				m_logger.log(AcsLogLevel.DEBUG,"MonitorComponent.addAllProperties " + p.name + " " + type.name()
						+ " ");
	
				/*
				 * TODO in C++ ACS::TimeInterval, is
				 * there an equivalent in Java? I'll use an long here.
				 */
	
				long monitoringInterval = propertyArchivingInterval(p);
				if (monitoringInterval != 0) {
					//addProperty(p.name, type.name(), p.property_ref, monitoringInterval);
					ty[monitored] =p.name;
					na[monitored] =type.name();
					pro[monitored] = p.property_ref;
					archInt[monitored]= monitoringInterval;
					monitored++;
				}
			}
			m_logger.log(AcsLogLevel.DEBUG,"The following monitorPoint has been added");
			
			monitorPoints_m = new HashMap<String, MonitorPointHelper>(monitored);
			monitorDataBlock_m.monitorBlobs = new MonitorBlob[monitored];
			for (int i=0; i<monitored; i++)
				addProperty(ty[i], na[i], pro[i], archInt[i]);
			
			for (String m : monitorPoints_m.keySet()) {
				m_logger.log(AcsLogLevel.DEBUG,"MonitorPoint:"+m);
	}

	private long propertyArchivingInterval(PropertyDesc p) {

		Property property = p.property_ref;

		Any anyCharacteristic;
		String strCharacteristic;

		try {
			anyCharacteristic = property
					.get_characteristic_by_name("archive_mechanism");
			strCharacteristic = anyCharacteristic.extract_string();

			if (strCharacteristic.equals("monitor_collector")) {
				
				anyCharacteristic = property
						.get_characteristic_by_name("default_timer_trig");
				strCharacteristic = anyCharacteristic.extract_string();

				double deftrig = Double.parseDouble(strCharacteristic);
				if (deftrig<1.)
					return 0;

				// reading archive_max_int property
				anyCharacteristic = property
						.get_characteristic_by_name("archive_max_int");
				strCharacteristic = anyCharacteristic.extract_string();

				double archiveMaxInt = Double.parseDouble(strCharacteristic);
				archiveMaxInt *= 10000000.0; // we have to convert to 100s nsec.

				// reading min_timer_trig property
				anyCharacteristic = property
						.get_characteristic_by_name("min_timer_trig");
				strCharacteristic = anyCharacteristic.extract_string();

				double minTimerTrigger = Double.parseDouble(strCharacteristic);
				minTimerTrigger *= 10000000.0; // we have to convert to 100s nsec.

				if (archiveMaxInt < minTimerTrigger) {
					// we can not get values faster than minTimmerTrigger
					/*
					 * TODO log as in C++: ACS_LOG(LM_FULL_INFO
					 * ,"MonitorComponent::propertyArchivingInterval",
					 * (LM_WARNING,
					 * "Because archive_max_int (%f) is smaller than min_timer_trig(%f), the values of property %s (%s) will be collected with time trigger: %f ."
					 * , archiveMaxInt, minTimerTrigger,
					 * propertyDesc->name.in(), property->_repository_id(),
					 * minTimerTrigger ));
					 */

					return (long) minTimerTrigger;
				} else {
					return (long) archiveMaxInt;
				}

			} else {
				/*
				 * TODO log as in C++: ACS_LOG(LM_FULL_INFO
				 * ,"MonitorComponent::propertyArchivingInterval", (LM_DEBUG,
				 * "Values from property %s (%s) will NOT be collected, because archive_mechanism is NOT set to 'monitor_collector', but to: %s."
				 * ,
				 */

				// archive_mechanism is NOT monitor_collector
				return 0;
			}

		} catch (NoSuchCharacteristic e) {
			// TODO Log?
//			e.printStackTrace();
			return 0;
		}
	}

	private void addProperty(String propertyName, String propertyType,
			alma.ACS.Property propertyRef, long archivingInterval) {

		// Adding the index property on monitorBlocksIndex_m
		int index = monitorBlocksIndex_m.size();
		monitorBlocksIndex_m.put(propertyName, index);
		monitorDataBlock_m.monitorBlobs[index]=null;
		m_logger.log(AcsLogLevel.DEBUG,"Adding prop index:"+index+"-->Name:"+propertyName);
		/*
		 * A note from the C++ implementation:
		 * Here we have to check for the type.
		 * We could do using _is_a(..), but it is a remote call, ... or put to
		 * an any and get type out.
		 * Here we use if but could be something else
		 */
		if (propertyType.endsWith("double")) {
			//m_logger.info("--->      double                  "+propertyName+", "+propertyType+", "+propertyRef+", "+archivingInterval);
			if (propertyType.startsWith("RO")) {
				monitorDataBlock_m.monitorBlobs[index] = new MonitorBlob();
				MPdouble mpd = new MPdouble(m_logger,propertyName,archivingInterval,propertyRef,monitorDataBlock_m.monitorBlobs[index]);
				mpd.activate(containerServices_m);
				monitorPoints_m.put(propertyName, mpd);
				m_logger.log(AcsLogLevel.DEBUG,"Added ROdouble:"+propertyName);
		}else if (propertyType.endsWith("long")) {
			//m_logger.info("Added ROLong:"+propertyName+", "+propertyType+", "+propertyRef+", "+archivingInterval);
			if (propertyType.startsWith("RO")) {
				monitorDataBlock_m.monitorBlobs[index] = new MonitorBlob();
				MPlong mpl = new MPlong(m_logger,propertyName,archivingInterval,propertyRef,monitorDataBlock_m.monitorBlobs[index]);
				mpl.activate(containerServices_m);
				monitorPoints_m.put(propertyName, mpl);
				m_logger.log(AcsLogLevel.DEBUG,"Added ROLong:"+propertyName);		}
		}else if (propertyType.endsWith("boolean")) {
			//m_logger.info("Added ROboolean:"+propertyName+", "+propertyType+", "+propertyRef+", "+archivingInterval);
			if (propertyType.startsWith("RO")) {
				monitorDataBlock_m.monitorBlobs[index] = new MonitorBlob();
				MPboolean mpb = new MPboolean(m_logger,propertyName,archivingInterval,propertyRef,monitorDataBlock_m.monitorBlobs[index]);
				mpb.activate(containerServices_m);
				monitorPoints_m.put(propertyName, mpb);
				m_logger.log(AcsLogLevel.DEBUG,"Added ROboolean:"+propertyName);
Gino Tosti's avatar
Gino Tosti committed
		}else if (propertyType.endsWith("longLong")) {
			//m_logger.info("Added ROboolean:"+propertyName+", "+propertyType+", "+propertyRef+", "+archivingInterval);
			if (propertyType.startsWith("RO")) {
				monitorDataBlock_m.monitorBlobs[index] = new MonitorBlob();
				MPlongLong mpll = new MPlongLong(m_logger,propertyName,archivingInterval,propertyRef,monitorDataBlock_m.monitorBlobs[index]);
				mpll.activate(containerServices_m);
				monitorPoints_m.put(propertyName, mpll);
				m_logger.log(AcsLogLevel.DEBUG,"Added ROlongLong:"+propertyName);
			}
		}else if (propertyType.endsWith("string")) {
			//m_logger.info("Added ROboolean:"+propertyName+", "+propertyType+", "+propertyRef+", "+archivingInterval);
			if (propertyType.startsWith("RO")) {
				monitorDataBlock_m.monitorBlobs[index] = new MonitorBlob();
Gino Tosti's avatar
Gino Tosti committed
				MPstring mps = new MPstring(m_logger,propertyName,archivingInterval,propertyRef,monitorDataBlock_m.monitorBlobs[index]);
				mps.activate(containerServices_m);
				monitorPoints_m.put(propertyName, mps);
				m_logger.log(AcsLogLevel.DEBUG,"Added ROstring:"+propertyName);
		}else {
			m_logger.info("UNIMPLEMENTED Porperty Type:"+propertyType);
		}
		//m_logger.info("---> MonitorComponent.startMonitoring");
		//m_logger.info("---> # monitor points: "+monitorPoints_m.size());
		for (String propName : monitorPoints_m.keySet()) {
			m_logger.log(AcsLogLevel.DEBUG,"startMonitoring:"+propName);
			//m_logger.info("----> "+monitorPoints_m.get(propName).toString());
			monitorPoints_m.get(propName).startMonitoring(containerServices_m);
		}
		// set monitoring state
		monitoring_m = true;

		m_monitoringStartTime = TimeHelper.getTimeStamp();

		// In C++ implementation a second getTimeStamp() is called, here I'll reuse m_monitoringStartTime.
		// bogdan: here we set start and stop time to the same value so that can later use stopTime to set startTime in fillSeq
		monitorDataBlock_m.startTime = m_monitoringStartTime.value;
		monitorDataBlock_m.stopTime  = m_monitoringStartTime.value;
	}

	public void stopMonitoring() {

		m_logger.log(AcsLogLevel.DEBUG,"MonitorComponent.stopMonitoring");
		if (monitoring_m) {
			for (String propName : monitorPoints_m.keySet()) {
				monitorPoints_m.get(propName).stopMonitoring();
			}
			// set monitoring state
			monitoring_m = false;
			// set proper start and stop time
			// TODO: as in C++ implementation, but why re-set again startTime?
			monitorDataBlock_m.startTime = m_monitoringStartTime.value;
			monitorDataBlock_m.stopTime  = TimeHelper.getTimeStamp().value;
		}
	}

	public MonitorDataBlock getMonitorDataBlock() {
		return monitorDataBlock_m;
	}

	public void set_archiving_interval(String propertyName, long time) {

		String prop = component_m.name()+":"+propertyName;

		m_logger.log(AcsLogLevel.DEBUG,"MonitorComponent.set_archiving_interval "+prop);

		for (String propName : monitorPoints_m.keySet()) {
			if (monitorPoints_m.get(propName).getPropertyName().equals(prop))
				monitorPoints_m.get(propName).set_archiving_interval(time);
		}
	}

	public void suppress_archiving(String propertyName) {

		String prop = component_m.name()+":"+propertyName;

		m_logger.info("---> MonitorComponent.suppress_archiving "+prop);

		for (String propName : monitorPoints_m.keySet()) {
			if (monitorPoints_m.get(propName).getPropertyName().equals(prop))
				monitorPoints_m.get(propName).suppress_archiving();
		}

	}

	public synchronized void setDeviceSerialNumber(String serialNumber) {

		m_logger.log(AcsLogLevel.DEBUG,"MonitorComponent.setDeviceSerialNumber");

		monitorDataBlock_m.deviceSerialNumber = serialNumber;
	}

	public synchronized void setPropertySerialNumber(String propertyName,
			String[] serialNumbers) {

		m_logger.log(AcsLogLevel.DEBUG,"MonitorComponent.setPropertySerialNumber");

		for (String propName : monitorPoints_m.keySet()) {

			// TODO: equals or contains?
			if (monitorPoints_m.get(propName).getPropertyName().equals(propertyName)) {

				monitorPoints_m.get(propName).setPropertySerialNumber(serialNumbers);
			}
		}

	}

	public synchronized void fillSeq() {

		m_logger.log(AcsLogLevel.DEBUG,"MonitorComponent.fillSeq");

		if (monitoring_m) {
			// TODO: really it could be undefined here?
			monitorDataBlock_m.startTime = m_monitoringStartTime.value;
			m_monitoringStartTime = TimeHelper.getTimeStamp();
Gino Tosti's avatar
Gino Tosti committed
			for (String propName : monitorPoints_m.keySet()) {
				if (propName!="") {
					m_logger.info("MonitorComponent: filling:"+propName);
					monitorPoints_m.get(propName).fillSeq();
				}
			monitorDataBlock_m.stopTime = TimeHelper.getTimeStamp().value;
		}
	}
}