package org.epics.archiverappliance.mgmt.policy; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import org.apache.log4j.Logger; import org.epics.archiverappliance.config.ConfigService; import org.epics.archiverappliance.config.StoragePluginURLParser; import org.epics.archiverappliance.mgmt.policy.PolicyConfig.SamplingMethod; import org.python.core.PyDictionary; import org.python.core.PyList; import org.python.core.PySystemState; import org.python.util.PythonInterpreter; /** * Given the information computed by the engine about the PV, compute the archiving policy using policies.py * Information to the policies.py is passed in as a dictionary with these keys * <ol> * <li><code>dbrtype</code> -- The ArchDBRType of the PV</li> * <li><code>eventRate</code> -- The sampled event rate in events per second.</li> * <li><code>storageRate</code> -- The sampled storage in bytes per seconds.</li> * <li><code>aliasName</code> -- The value of the .NAME field for aliases</li> * <li><code>policyName</code> -- If the user has overridden the policy when requesting archiving, this is the name of the policy</li> * </ol> * All the {@link ConfigService#getExtraFields() extra fields} are use the fieldName as the key (for example, ADEL comes in as .ADEL). * The result of policy execution is a another dictionary with these keys * <ol> * <li><code>samplingPeriod</code> -- The sampling period to use for this PV.</li> * <li><code>samplingMethod</code> -- The {@link SamplingMethod sampling method} to use for this PV.</li> * <li><code>policyName</code> -- The name of the policy that was used for this PV.</li> * <li><code>controlPV</code> -- Another PV that can be used to conditionally archive this PV.</li> * <li><code>dataStores</code> -- An array of StoragePlugin URL's that can be parsed by {@link StoragePluginURLParser StoragePluginURLParser}. These form the stages of data storage for this PV.</li> * <li><code>archiveFields</code> -- A optional array of fields that will be archived as part of archiving the .VAL field for this PV.</li> * <li><code>appliance</code> -- Optional; assign this PV to this appliance. This is a string and is the identity of the appliance you want to assign this PV to.</li> * </ol> * @author mshankar * */ public class ExecutePolicy implements AutoCloseable { private static Logger logger = Logger.getLogger(ExecutePolicy.class.getName()); private PythonInterpreter interp; public ExecutePolicy(ConfigService configService) throws IOException { interp = new PythonInterpreter(null, new PySystemState()); // Load the policies.py into the interpreter. try(InputStream is = configService.getPolicyText()) { interp.execfile(is); } } @Override public void close() { this.interp.cleanup(); } /** * Compute the policy for a PV * @param pvName The name of PV. * @param pvInfo HashMap * @return PolicyConfig   * @throws IOException   */ public PolicyConfig computePolicyForPV(String pvName, HashMap<String, Object> pvInfo) throws IOException { PyDictionary pvInfoDict = new PyDictionary(); pvInfoDict.put("pvName", pvName); pvInfoDict.putAll(pvInfo); interp.set("pvInfo", pvInfoDict); interp.exec("pvPolicy = determinePolicy(pvInfo)"); PyDictionary policy = (PyDictionary) interp.get("pvPolicy"); PolicyConfig policyConfig = new PolicyConfig(); Double samplingPeriod = (Double) policy.get("samplingPeriod"); policyConfig.setSamplingPeriod(samplingPeriod.floatValue()); String samplingMethod = (String) policy.get("samplingMethod"); policyConfig.setSamplingMethod(SamplingMethod.valueOf(samplingMethod)); String policyName = (String) policy.get("policyName"); policyConfig.setPolicyName(policyName); if(policy.containsKey("controlPV")) { policyConfig.setControlPV((String)policy.get("controlPV")); logger.debug("Conditionally archiving PV using " + policyConfig.getControlPV()); } LinkedList<String> dataStores = new LinkedList<String>(); for(Object dataStore : (PyList) policy.get("dataStores")) { dataStores.add((String)dataStore); } policyConfig.setDataStores(dataStores.toArray(new String[0])); LinkedList<String> archiveFields = new LinkedList<String>(); if(policy.containsKey("archiveFields")) { for(Object archiveField : (PyList) policy.get("archiveFields")) { archiveFields.add((String)archiveField); } } else { logger.debug("No additional fields will be archived for PV " + pvName); } policyConfig.setArchiveFields(archiveFields.toArray(new String[0])); if(policy.containsKey("appliance")) { policyConfig.setAppliance((String) policy.get("appliance")); } if(logger.isDebugEnabled()) logger.debug("For pv" + pvName + "using policy " + policyConfig.generateStringRepresentation()); return policyConfig; } public HashMap<String, String> getPolicyList() throws IOException { logger.debug("Getting the list of policies."); interp.exec("pvPolicies = getPolicyList()"); PyDictionary policies = (PyDictionary) interp.get("pvPolicies"); @SuppressWarnings("unchecked") HashMap<String, String> ret = new HashMap<String, String>(policies); return ret; } public List<String> getFieldsArchivedAsPartOfStream() throws IOException { logger.debug("Getting the list of standard fields."); interp.exec("pvStandardFields = getFieldsArchivedAsPartOfStream()"); PyList stdFields = (PyList) interp.get("pvStandardFields"); @SuppressWarnings("unchecked") LinkedList<String> ret = new LinkedList<String>(stdFields); return ret; } }