/**
* Copyright (c) <2013> <Radware Ltd.> and others. All rights reserved.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License
* v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
* @author Konstantin Pozdeev
* @version 0.1
*/
package org.opendaylight.defense4all.core.impl;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.opendaylight.defense4all.core.DFAppRoot;
import org.opendaylight.defense4all.core.DFDetector;
import org.opendaylight.defense4all.core.DetectorMgr;
import org.opendaylight.defense4all.core.Detector;
import org.opendaylight.defense4all.core.DetectorInfo;
import org.opendaylight.defense4all.core.PN;
import org.opendaylight.defense4all.core.interactionstructures.EndDetectionNotification;
import org.opendaylight.defense4all.core.interactionstructures.StatReport;
import org.opendaylight.defense4all.framework.core.ExceptionControlApp;
import org.opendaylight.defense4all.framework.core.HealthTracker;
import org.opendaylight.defense4all.framework.core.FrameworkMain.ResetLevel;
public class DetectorMgrImpl extends DFAppCoreModule implements DetectorMgr {
protected Detector detector0 = null;
protected Detector detector1 = null;
protected Detector detector2 = null;
protected Detector detector3 = null;
protected Detector detector4 = null;
protected Detector detector5 = null;
public Hashtable<String, DFDetector> detectors = null;
public void setDetector0(Detector detector0) {this.detector0 = detector0;}
public void setDetector1(Detector detector1) {this.detector1 = detector1;}
public void setDetector2(Detector detector2) {this.detector2 = detector2;}
public void setDetector3(Detector detector3) {this.detector3 = detector3;}
public void setDetector4(Detector detector4) {this.detector4 = detector4;}
public void setDetector5(Detector detector5) {this.detector5 = detector5;}
static private Properties defaultProperties = null;
public DetectorMgrImpl() {
super();
detectors = new Hashtable<String,DFDetector>();
}
/** Post-constructor initialization */
public void init() throws ExceptionControlApp {
super.init();
log.info("DetectorMgr is starting");
// Create and registry all detectors from repo
Hashtable<String, Hashtable<String, Object>> detectorTable;
detectorTable = dfAppRoot.detectorsRepo.getTable();
if ( detectorTable == null) {
log.error("Failed to get detectorsRepo table in DetectorMgr. " );
log.error("DetectorMgr failed to properly start");
fMain.getHealthTracker().reportHealthIssue(HealthTracker.MODERATE_HEALTH_ISSUE);
throw new ExceptionControlApp("Failed to get detectorsRepo table in DetectorMgr. ");
}
Iterator<Map.Entry<String,Hashtable<String,Object>>> iter = detectorTable.entrySet().iterator();
Map.Entry<String,Hashtable<String,Object>> entry; DetectorInfo detectorInfo = null; Detector detector;
while(iter.hasNext()) {
try {
entry = iter.next();
detectorInfo = new DetectorInfo(entry.getValue());
if(!detectorInfo.getOfBasedDetector()) continue;
detector = instrumentDetector(detectorInfo.getLabel() );
if (detector == null || ! (detector instanceof DFDetector)) continue;
detector.fromRow(entry.getValue());
detector.init();
addDetector ( detector );
} catch (Throwable e) {
String msg = detectorInfo != null ? detectorInfo.label:"";
log.error("Failed to inflate detector from detectorsRepo row. " + msg );
fr.logRecord(DFAppRoot.FR_DF_FAILURE, msg +" failed to initialize");
fMain.getHealthTracker().reportHealthIssue(HealthTracker.MODERATE_HEALTH_ISSUE);
continue;
}
}
if(detectors.size() > 0 ) return; // Not first time init - no need to take from properties file
/* First time repo initialization - add Detector if one set through properties file. Next time it will be in repo. */
for (Detector dt : instrumentDetectors() ) {
if (dt == null || !(dt instanceof DFDetector)) continue;
// read properties file
try {
Hashtable<String, Object> detectorRow = getProperties ( dt);
dt.fromRow(detectorRow);
dt.init();
addDetector ( dt );
} catch (Exception e) {
String msg = detectorInfo != null ? detectorInfo.label:"";
log.error("Failed to inflate detector from properties file. " + msg , e);
fr.logRecord(DFAppRoot.FR_DF_FAILURE, msg +" failed to initialize");
fMain.getHealthTracker().reportHealthIssue(HealthTracker.MODERATE_HEALTH_ISSUE);
continue;
}
}
}
/** Pre-shutdown cleanup */
public void finit() {
log.info("DetectorMgr is stopping");
super.finit();
// loop over all detectors in detectors repo
for ( Detector dt : detectors.values() ) {
dt.finit();
}
}
/** Reset
* @throws ExceptionControlApp */
public void reset(ResetLevel resetLevel) throws ExceptionControlApp {
log.info("DetectorMgr is resetting to level " + resetLevel);
super.reset(resetLevel);
// loop over all detectors in detectors repo
for ( Detector dt : detectors.values() ) {
dt.reset(resetLevel);
}
detectors.clear();
}
/**
* Instrument an Detector constructed from spring context
* by the label parameters
*
*/
protected Detector instrumentDetector (String label) {
for (Detector detector:instrumentDetectors() ) {
if ( detector != null) {
if ( detector.getDetectorInfo().getLabel().equals(label) )
return detector;
}
}
return null;
}
protected Detector[] instrumentDetectors() {
Detector allDetectors[] = {detector0, detector1, detector2, detector3, detector4, detector5 };
return allDetectors;
}
/**
* Read properties file for pre-created detector
* @param param_name param description
* @return return description
* @throws ExceptionControlApp
* @throws exception_type circumstances description
*/
private Hashtable<String, Object> getProperties(Detector detector) throws ExceptionControlApp {
// Read properties file with default attributes
if ( defaultProperties == null ) {
defaultProperties=new Properties();
InputStream is=DFMgmtPointImpl.class.getClassLoader().getResourceAsStream("detectors.properties");
try {
defaultProperties.load(is);
} catch(IOException ioExc) {
log.error("Failed to load config properties file detectors.properties", ioExc);
try {
is.close();
} catch (IOException e) {/* Ignore */}
throw new ExceptionControlApp("Failed to load config properties file detectors.properties", ioExc);
}
try {
is.close();
} catch (IOException e) {/* Ignore */}
}
// Get default map of attributes
Hashtable<String, Object> detectorRow;
try {
detectorRow = detector.toRow();
// get list of attributes and replace values from properties file
for ( String key : detectorRow.keySet() ) {
String propertyName = "Detector."+detector.getDetectorInfo().getLabel()+"."+key;
if ( defaultProperties.containsKey(propertyName) && defaultProperties.get(propertyName) != null) {
detectorRow.put( key , defaultProperties.get(propertyName));
}
}
} catch (Throwable e) {
log.error("Failed to process config properties file detectors.properties", e);
throw new ExceptionControlApp("Failed to process config properties file detectors.properties", e);
}
return detectorRow;
}
/**
* Add an Detector constructed from parameters on init
* @param param_name param description
* @return return description
* @throws ExceptionControlApp
* @throws exception_type circumstances description
*/
public void addDetector(Detector detector) throws ExceptionControlApp {
String detectorLabel = detector.getDetectorInfo().getLabel();
// insert or update repository row
try {
dfAppRootFullImpl.detectorsRepo.setRow(detectorLabel,detector.toRow());
} catch (Throwable e) {
log.error("Failed to persist detector in detectorsRepo. Detector label: "+detectorLabel, e );
fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE);
throw new ExceptionControlApp("Failed to persist detector in detectorsRepo. Detector label: "+detectorLabel, e);
}
if (detector.getDetectorInfo().getOfBasedDetector() && detector instanceof DFDetector )
detectors.put(detector.getDetectorInfo().getLabel(), (DFDetector)detector);
}
public void setDetectorProperties(String detectorLabel, String detectorAttr, String value) throws ExceptionControlApp {
Detector detector = detectors.get(detectorLabel);
if ( detector == null ) return;
Hashtable<String, Object> detectorRow;
try {
detectorRow = detector.toRow();
if ( detectorRow.get(detectorAttr) != null ) {
detectorRow.put(detectorAttr, value);
detector.fromRow(detectorRow);
detector.init();
removeDetector(detectorLabel);
addDetector ( detector );
} else {
throw new ExceptionControlApp("Invalid detector property : "+detectorLabel+":"+detectorAttr );
}
} catch (Throwable e ) {
log.error("Failed to update properties for detector "+detectorLabel, e);
throw new ExceptionControlApp("Failed to update properties for detector "+detectorLabel, e);
}
}
/**
* Return an initialized Detector from hash
* @param param_name param description
* @return return description
* @throws exception_type circumstances description
*/
public DFDetector getDetector(String label) {
if(label == null || label.isEmpty()) return null;
return detectors.get(label);
}
/**
* Delete an initialized Detector from hash
* @param param_name param description
* @return return description
* @throws ExceptionControlApp
* @throws exception_type circumstances description
*/
public void removeDetector(String detectorLabel) throws ExceptionControlApp {
Detector detector = detectors.get(detectorLabel);
if ( detector != null ) {
detector.finit();
detectors.remove(detector);
}
// remove from repository also
try {
dfAppRootFullImpl.detectorsRepo.deleteRow(detectorLabel);
} catch (ExceptionControlApp e) {
log.error("Failed to delete detector from detectorsRepo. Detector label: "+detectorLabel, e );
fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE);
throw new ExceptionControlApp("Failed to persist detector in detectorsRepo. Detector label: "+detectorLabel, e);
}
}
/**
* Loop over registered in PN detectors and pass stat report
* @param param_name param description
* @return return description
* @throws exception_type circumstances description
*/
public void handleStatReport(Hashtable<String,Object> pnRow, StatReport statReport) {
try {
String label = (String) pnRow.get(PN.DETECTOR_LABEL);
if ( detectors.containsKey(label)) {
if ( detectors.get(label).getDetectorInfo().getOfBasedDetector()) {
detectors.get(label).handleStatReport( statReport );
}
}
} catch (Throwable e) {
log.error("Excepted handling statReport.", e);
fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE);
}
}
/**
* Notify all relevant detectors
* @param param_name param description
* @return return description
* @throws ExceptionControlApp
* @throws exception_type circumstances description
*/
public void notifyEndDetection(EndDetectionNotification endDetectionNotification) {
DFDetector detector = getDetector(endDetectionNotification.detection.detector);
try {
if ( detector != null && detector.getDetectorInfo().getOfBasedDetector() )
detector.notifyEndDetection(endDetectionNotification);
} catch (Throwable e) {
log.error("Failed to notify datector about end detection Detection key: "+endDetectionNotification.detection.key, e );
return;
}
}
public void cleanup() {
for (DFDetector detector : detectors.values() ) {
try {
detector.cleanup();
} catch (Throwable e) {/* Ignore */}
}
}
@Override
protected void actionSwitcher(int actionCode, Object param) {
switch(actionCode) {
default:
break;
}
}
public List<Detector> getDetectors() {
List<Detector> detectors = new ArrayList<Detector>();
if(detector0 != null) detectors.add(detector0);
if(detector1 != null) detectors.add(detector1);
if(detector2 != null) detectors.add(detector2);
if(detector3 != null) detectors.add(detector3);
if(detector4 != null) detectors.add(detector4);
if(detector5 != null) detectors.add(detector5);
return detectors;
}
}