Skip to content
MonitorComponent.java 12.3 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 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.time.TimeHelper;
import alma.acstime.Epoch;
import alma.TMCDB.MonitorCollectorImpl.MonitorPoint;

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

	ContainerServices containerServices_m;
	CharacteristicComponent component_m;
	CharacteristicComponentDesc compDesc_m;
	int numOfProp_m=0;
	Logger m_logger;
	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
	 */
	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
	 */
	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.
	 */
	Map<String, Integer> monitorBlocksIndex_m = new HashMap<String, Integer>();

	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 = 0;
		monitorDataBlock_m.stopTime = 0;
		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);
		}
	}

	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.info("---> MonitorComponent.addAllProperties");

		// TODO: what implementation of List/Collection for monitorPoints_m?
		monitorPoints_m = new HashMap<String, MonitorPointHelper>(numOfProp_m);
		monitorDataBlock_m.monitorBlobs = new MonitorBlob[numOfProp_m];

		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.info("---> 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);
			}
		}
	}

	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")) {

				// 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);

		/*
		 * 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();
				//doubleBlobData[] list = new doubleBlobData[100];
				//MonitorPoint<CBdoublePOA, doubleBlobData> mp = new MonitorPoint<CBdoublePOA, doubleBlobData>(propertyName, propertyRef, propertyType, alma.TMCDB.doubleValueType.value, archivingInterval, monitorDataBlock_m.monitorBlobs[index]);
				MPdouble mp1 = new MPdouble(m_logger,propertyName,archivingInterval,propertyRef,monitorDataBlock_m.monitorBlobs[index]);
				//org.omg.CORBA.Object ob= CallbackHelper.narrow(mp);
				//CBdoublePOA ser =new CBdoublePOATie(mp1);
				//mp1.setMonitorServant(ser);
				//mp.setLogger(m_logger);
				mp1.activate(containerServices_m);
				monitorPoints_m.put(propertyName, mp1);
				m_logger.info("---> MonitorComponent added Property "+propertyName);

			}
//				else {
//
//				mp = new Monitorable(TPROP, propertyName, archivingInterval, property, typeOfData, mb);
//			}

		}else if (propertyType.endsWith("long")) {

			m_logger.info("--->      double                  "+propertyName+", "+propertyType+", "+propertyRef+", "+archivingInterval);

			if (propertyType.startsWith("RO")) {
				monitorDataBlock_m.monitorBlobs[index] = new MonitorBlob();
				MonitorPoint<CBlongPOA, longBlobData> mp = new MonitorPoint<CBlongPOA, longBlobData>(propertyName, propertyRef, propertyType, alma.TMCDB.longValueType.value, archivingInterval, monitorDataBlock_m.monitorBlobs[index]);
				//monitorPoints_m.put(propertyName, mp);
				m_logger.info("---> MonitorComponent added Property "+propertyName);
		}else {
			m_logger.info("UNIMPLEMENTED Porperty Type:"+propertyType);
		}
		
		m_logger.info("---> the following monitorPoint has been added");
		for (String m : monitorPoints_m.keySet()) {
			m_logger.info("---> "+m);
		m_logger.info("---> MonitorComponent.startMonitoring");
		m_logger.info("---> # monitor points: "+monitorPoints_m.size());
		for (String propName : monitorPoints_m.keySet()) {
			m_logger.info("----> "+propName);
			m_logger.info("----> "+monitorPoints_m.get(propName).toString());
		}


		for (String propName : monitorPoints_m.keySet()) {
			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.info("---> 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.info("---> 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.info("---> MonitorComponent.setDeviceSerialNumber");

		monitorDataBlock_m.deviceSerialNumber = serialNumber;
	}

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

		m_logger.info("---> 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.info("---> MonitorComponent.fillSeq");

		if (monitoring_m) {
			// TODO: really it could be undefined here?
			monitorDataBlock_m.startTime = m_monitoringStartTime.value;
			m_monitoringStartTime = TimeHelper.getTimeStamp();
		}

		for (String propName : monitorPoints_m.keySet()) {
			monitorPoints_m.get(propName).fillSeq();
		}

		if (monitoring_m) {
			monitorDataBlock_m.stopTime = TimeHelper.getTimeStamp().value;
		}

	}
}