/** * 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 Gera Goft * @author Konstantin Pozdeev * @version 0.1 */ package org.opendaylight.defense4all.core.impl; import java.net.InetAddress; import java.util.ArrayList; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import org.opendaylight.defense4all.core.DFAppRoot; import org.opendaylight.defense4all.core.DFAppRoot.HealthStatus; import org.opendaylight.defense4all.core.MitigationMgr; import org.opendaylight.defense4all.core.MitigationDriver; import org.opendaylight.defense4all.core.Mitigation.Status; import org.opendaylight.defense4all.core.ProtocolPort.DFProtocol; import org.opendaylight.defense4all.core.Attack; import org.opendaylight.defense4all.core.Mitigation; import org.opendaylight.defense4all.core.PN; import org.opendaylight.defense4all.core.PN.MitigationScope; import org.opendaylight.defense4all.core.PN.OperationalStatus; import org.opendaylight.defense4all.core.ProtocolPort; import org.opendaylight.defense4all.framework.core.ExceptionControlApp; import org.opendaylight.defense4all.framework.core.HealthTracker; import org.opendaylight.defense4all.framework.core.FrameworkMain.ResetLevel; public class MitigationMgrImpl extends DFAppCoreModule implements MitigationMgr { protected class MitigationInfo { String mitigationKey; MitigationDriver driver; MitigationInfo(String mitigationKey, MitigationDriver driver) { this.mitigationKey = mitigationKey; this.driver = driver; } } /** * Decoupled actions for ActionSwitcher */ protected static final int ACTION_INVALID = -1; // Already defined in Module. Brought here for brevity protected static final int ACTION_RESERVED = 0; // Already defined in Module. Brought here for brevity protected static final int ACTION_ADD_PN = 1; protected static final int ACTION_REMOVE_PN = 2; protected static final int ACTION_MITIGATE = 3; protected static final int ACTION_END_MITIGATION = 4; protected static final int ACTION_RETRY_MITIGATION = 5; protected long retryIntervalInSecs = 60; // Period to check all Vexs and vbrs health, if not set anywhere else /* Constructor for Spring */ public MitigationMgrImpl() { super(); } /** Post-constructor initialization */ public void init() throws ExceptionControlApp { super.init(); log.info( "MitigationMgr is starting."); addPeriodicExecution(ACTION_RETRY_MITIGATION, null, retryIntervalInSecs); } /** Pre-shutdown cleanup */ public void finit() { log.info( "MitigationMgr is stopping."); for(MitigationDriver mitigationDriver : dfAppRootFullImpl.mitigationDrivers) { mitigationDriver.finit(); } super.finit(); } /** Reset * @throws ExceptionControlApp */ public synchronized void reset(ResetLevel resetLevel) throws ExceptionControlApp { log.info( "MitigationMgr is resetting to level " + resetLevel); super.reset(resetLevel); for(MitigationDriver mitigationDriver : dfAppRootFullImpl.mitigationDrivers) { try { mitigationDriver.reset(resetLevel); } catch (Throwable e) { log.error("Excepted in reset mitigationDriver :"+mitigationDriver.getLabel(), e ); continue; } } try { dfAppRootFullImpl.mitigationsRepo.truncate(); } catch (Throwable e) { log.error("Failed to reset mitigationsRepo", e ); } } public ArrayList<MitigationDriver> getMitigationDrivers() {return dfAppRootFullImpl.mitigationDrivers;} /** * #### method description #### * @param param_name param description * @return return description * @throws ExceptionControlApp * @throws exception_type circumstances description */ public void addPN(String pnKey) throws ExceptionControlApp { try { invokeDecoupledSerially(ACTION_ADD_PN, pnKey); } catch (ExceptionControlApp e) { log.error("Excepted trying to invokeDecoupledSerialiy " + ACTION_ADD_PN + " " + pnKey, e); throw e; } } /** * #### method description #### * @param param_name param description * @return return description * @throws exception_type circumstances description */ protected synchronized void decoupledAddPN(String pnKey) { for(MitigationDriver mitigationDriver : dfAppRootFullImpl.mitigationDrivers) { try { mitigationDriver.addPN(pnKey); } catch (Throwable e) { log.error("Excepted in adding PN to mitigationDriver :"+mitigationDriver.getLabel()+" PN "+pnKey, e ); try { dfAppRootFullImpl.pNsRepo.setCell(pnKey, PN.OPERATIONAL_STATUS, PN.OperationalStatus.FAILED.name()); } catch (Throwable e1) {}; // ignore continue; } } } /** * #### method description #### * @param param_name param description * @return return description * @throws ExceptionControlApp * @throws exception_type circumstances description */ public void removePN(String pnKey) throws ExceptionControlApp { try { invokeDecoupledSerially(ACTION_REMOVE_PN, pnKey); } catch (ExceptionControlApp e) { log.error("Excepted trying to invokeDecoupledSerialiy " + ACTION_REMOVE_PN + " " + pnKey, e); throw e; } } /** * #### method description #### * @param param_name param description * @return return description * @throws exception_type circumstances description */ protected synchronized void decoupledRemovePN(String pnKey) { for(MitigationDriver mitigationDriver : dfAppRootFullImpl.mitigationDrivers) { try { mitigationDriver.removePN(pnKey); } catch (Throwable e) { log.error("Excepted in removing PN from mitigationDriver :"+mitigationDriver.getLabel()+" PN "+pnKey, e ); continue; } } } public synchronized void addNetNode(String netNodeKey) { for(MitigationDriver mitigationDriver : dfAppRootFullImpl.mitigationDrivers) { try { mitigationDriver.addNetNode(netNodeKey); } catch (Throwable e) { log.error("Excepted in addNetNode processing in mitigationDriver :"+mitigationDriver.getLabel(), e); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); continue; } } } /** * #### method description #### * @param param_name param description * @return return description * @throws ExceptionControlApp * @throws Throwable * @throws exception_type circumstances description */ @Override public synchronized void mitigate(String attackKey) { fr.logRecord(DFAppRoot.FR_DF_SECURITY, "DefenseFlow starting mitigation for attack " + Attack.getPrintableAttackTarget(attackKey)); Hashtable<String, Object> attackRow; try { attackRow = dfAppRootFullImpl.attacksRepo.getRow(attackKey); } catch (Throwable e) { log.error("Failed to get attack row from attacksRepo : "+attackKey, e); fr.logRecord(DFAppRoot.FR_DF_FAILURE, "DefenseFlow failed to process mitigation for attack on " + Attack.getPrintableAttackTarget(attackKey)); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); return; } if(attackRow == null) { fr.logRecord(DFAppRoot.FR_DF_FAILURE, "DefenseFlow failed to process mitigation for attack on " + Attack.getPrintableAttackTarget(attackKey)); return; } String pnKey = (String) attackRow.get(Attack.PNKEY); ProtocolPort attackedProtocolPort; try { attackedProtocolPort = new ProtocolPort((String) attackRow.get(Attack.PROTOCOL_PORT)); } catch (Throwable e1) { log.error("Failed to construct ProtocolPort from attackRow cell "+(String) attackRow.get(Attack.PROTOCOL_PORT),e1); fr.logRecord(DFAppRoot.FR_DF_FAILURE, "DefenseFlow failed to process mitigation for attack on " + Attack.getPrintableAttackTarget(attackKey)); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); return; } /* Check if the PN is failed or canceled */ try { Object obj = dfAppRootFullImpl.pNsRepo.getCellValue(pnKey, PN.OPERATIONAL_STATUS); OperationalStatus operationalStatus = OperationalStatus.INVALID; if(obj != null) operationalStatus = OperationalStatus.valueOf((String) obj); if(operationalStatus == OperationalStatus.CANCELED || operationalStatus == OperationalStatus.FAILED) return; } catch (Throwable e) { log.error("Failed to retrieve operational status value for " + pnKey, e); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); return; } /* Create diversion object and record it in diversions repo */ String mitigationKey = Mitigation.generateKey(attackKey); InetAddress dstAddr; int dstAddrPrefixLen; try { dstAddr = InetAddress.getByName((String) dfAppRootFullImpl.pNsRepo.getCellValue(pnKey, PN.DST_ADDR)); dstAddrPrefixLen = (Integer) dfAppRootFullImpl.pNsRepo.getCellValue(pnKey, PN.DST_ADDR_PREFIX_LEN); } catch (Throwable e2) { log.error("Failed to construct dstAddr and/or dstAddrPrefixLen from pNsRepo cell "+pnKey, e2); fr.logRecord(DFAppRoot.FR_DF_FAILURE, "DefenseFlow failed to process mitigation for attack on " + Attack.getPrintableAttackTarget(attackKey)); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); return; } /* Determine the traffic to divert according to PN configuration - all or only the attacked protocol-port */ ProtocolPort protocolPort; try { protocolPort = determineTrafficToDivert(pnKey, attackedProtocolPort); } catch (ExceptionControlApp e1) { fr.logRecord(DFAppRoot.FR_DF_FAILURE, "DefenseFlow failed to process mitigation for attack on " + Attack.getPrintableAttackTarget(attackKey)); return; } boolean collectStats = true; String mitigationDriverLabel = ""; boolean setMitigation = false; Mitigation mitigation = new Mitigation(mitigationKey, attackKey, pnKey, null, dstAddr, dstAddrPrefixLen, protocolPort, Mitigation.Status.NO_RESOURCES, collectStats, mitigationDriverLabel, null); try { Hashtable<String,Object> existingMitigation = dfAppRootFullImpl.mitigationsRepo.getRow(mitigationKey); if(existingMitigation != null) return; // We already have a mitigation for this key. Called twice for same attack? dfAppRootFullImpl.mitigationsRepo.setRow(mitigationKey, mitigation.toRow()); setMitigation = true; dfAppRootFullImpl.attacksRepo.setCell(attackKey, Attack.MITIGATION_KEY, mitigationKey); } catch (Throwable e4) { log.error("Failed to update mitigationsRepo and/or attacksRepo "+mitigationKey + " attack key "+attackKey, e4); fr.logRecord(DFAppRoot.FR_DF_FAILURE, "DefenseFlow failed to process mitigation for attack on " + Attack.getPrintableAttackTarget(attackKey)); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); if ( setMitigation == true ) { try { dfAppRootFullImpl.mitigationsRepo.deleteRow(mitigationKey); } catch ( Throwable e ) {}; } return; } /* Start requesting mitigation drivers to handle this mitigation. */ startMitigationByDrivers(mitigationKey); } protected synchronized void startMitigationByDrivers(String mitigationKey) { try { if(dfAppRootFullImpl.mitigationDrivers == null || dfAppRootFullImpl.mitigationDrivers.size() == 0) { fr.logRecord(DFAppRoot.FR_DF_SECURITY, "DefenseFlow cannot start mitigation for " +Mitigation.getPrintableMitigationTarget( mitigationKey ) + " because there are no mitigation drivers installed."); return; // No mitigation drivers installed } MitigationDriver mitigationDriver = dfAppRootFullImpl.mitigationDrivers.get(0); tryMitigationByDriver(mitigationKey, mitigationDriver); } catch (ExceptionControlApp e) {/* Ignore */} } public List<String> getMitigationTrafficFloorKeys(String attackKey) throws ExceptionControlApp { List<String> mitigationTrafficFloorKeys = new ArrayList<String>(); try { Hashtable<String,Hashtable<String,Object>> mitigationsTable = dfAppRootFullImpl.mitigationsRepo.getTable(); Iterator<Map.Entry<String,Hashtable<String,Object>>> iter = mitigationsTable.entrySet().iterator(); Hashtable<String,Object> mitigationRow; Mitigation mitigation; while(iter.hasNext()) { mitigationRow = iter.next().getValue(); mitigation = new Mitigation(mitigationRow); if(mitigation.attackKey.equals(attackKey)) { mitigationTrafficFloorKeys.addAll(mitigation.trafficFloorKeys); return mitigationTrafficFloorKeys; } } } catch (Throwable e) { String msg = "Failed to getMitigationTrafficFloorKeys " + " attack key "+attackKey; log.error(msg, e); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); throw new ExceptionControlApp(msg + e.getMessage()); } return null; } protected ProtocolPort determineTrafficToDivert(String pnKey, ProtocolPort attackedProtocolPort) throws ExceptionControlApp { try { String mitigationScopeStr = (String) dfAppRoot.pNsRepo.getCellValue(pnKey, PN.MITIGATION_SCOPE); MitigationScope mitigationScope = MitigationScope.valueOf(mitigationScopeStr); ProtocolPort protocolPort; if(mitigationScope == MitigationScope.ATTACKED) protocolPort = attackedProtocolPort; else protocolPort = new ProtocolPort(DFProtocol.IP, 0); return protocolPort; } catch (Throwable e) { String msg = "Failed to construct protocolPort from pNsRepo cell "+pnKey; log.error(msg, e); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); throw new ExceptionControlApp(msg + ". " + e.getMessage()); } } /* Try the first MitigationDriver plugin to mitigate the attack. It will respond with a callback about * whether it handled the mitigation (or whether the next mitigation plugin should be attempted). */ protected void tryMitigationByDriver(String mitigationKey,MitigationDriver mitigationDriver) throws ExceptionControlApp { log.info( "DF is trying to mitigate " + mitigationKey + " using mitigation driver " + mitigationDriver.getLabel()); try { dfAppRoot.mitigationsRepo.setCell(mitigationKey, Mitigation.MITIGATION_DRIVER, mitigationDriver.getLabel()); } catch (Throwable e) { log.error("Failed to update mitigationsRepo "+mitigationKey, e); fr.logRecord(DFAppRoot.FR_DF_FAILURE, "DefenseFlow failed to process mitigation off " + Mitigation.getPrintableMitigationTarget(mitigationKey)); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); throw new ExceptionControlApp("Failed to update mitigationsRepo "+mitigationKey, e); } MitigationInfo mitigationInfo = new MitigationInfo(mitigationKey, mitigationDriver); try { invokeDecoupledSerially(ACTION_MITIGATE, mitigationInfo); } catch (ExceptionControlApp e1) { try { dfAppRoot.mitigationsRepo.setCell(mitigationKey, Mitigation.MITIGATION_DRIVER, ""); //Unset mitigation driver } catch (Throwable e) {/* Ignore */} log.error("Excepted trying to invokeDecoupledSerialiy " + ACTION_MITIGATE + mitigationKey, e1); throw e1; } } protected synchronized void decoupledMitigate(MitigationInfo mitigationInfo) { /* mitigate is decoupled in the mitigation driver. * Retry and recovery should be handled by mitigation driver. * Mitigation manager can handle status of invocation only */ try { mitigationInfo.driver.mitigate(mitigationInfo.mitigationKey); } catch (Throwable e) { log.error("Excepted trying to invoke mitigate of mitigation driver " + mitigationInfo.driver.getLabel(), e); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); } } /** * #### method description #### * @param param_name param description * @return return description * @throws exception_type circumstances description */ @Override public synchronized void handleMitigationResponse (String mitigationKey, boolean mitigating) { String currentMitigationDriverLabel = ""; try { currentMitigationDriverLabel = (String) dfAppRoot.mitigationsRepo.getCellValue(mitigationKey, Mitigation.MITIGATION_DRIVER); } catch (ExceptionControlApp e) { log.error("Failed to get MITIGATION_DRIVER from mitigationsRepo "+mitigationKey, e); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); } if(currentMitigationDriverLabel == null || currentMitigationDriverLabel.isEmpty()) return; if(mitigating) { try { dfAppRootFullImpl.mitigationsRepo.setCell(mitigationKey, Mitigation.STATUS, Mitigation.Status.ACTIVE.name()); } catch (Throwable e) { log.error("Failed to update mitigationsRepo with active mitigation status "+mitigationKey, e); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); } log.info(currentMitigationDriverLabel+" is driving mitigation of "+mitigationKey); return; } /* The current in line mitigation driver is not mitigating this attack. Find and try the next one. */ try { dfAppRootFullImpl.mitigationsRepo.setCell(mitigationKey, Mitigation.MITIGATION_DRIVER, ""); } catch (Throwable e) { }; log.info(currentMitigationDriverLabel+" is not driving mitigation of "+mitigationKey); int numofMitigationDrivers = dfAppRootFullImpl.mitigationDrivers.size(); String mitigationDriverLabel; int i; for(i=1;i<numofMitigationDrivers;i++) { mitigationDriverLabel = dfAppRootFullImpl.mitigationDrivers.get(i).getLabel(); if(mitigationDriverLabel.equals(currentMitigationDriverLabel)) break; } if(i >= numofMitigationDrivers-1) { try { dfAppRootFullImpl.mitigationsRepo.setCell(mitigationKey, Mitigation.STATUS, Mitigation.Status.NO_RESOURCES.name()); } catch (Throwable e) { log.error("Failed to update mitigationsRepo with active mitigation status "+mitigationKey, e); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); } log.info("No more mitigation drivers to try driving mitigation of "+mitigationKey); return; // Either not found current mitigating driver (could have been removed in this app lifecycle) or // this was the last one installed } /* Try the next mitigation driver */ try { MitigationDriver mitigationDriver = dfAppRootFullImpl.mitigationDrivers.get(i+1); tryMitigationByDriver(mitigationKey, mitigationDriver); } catch (ExceptionControlApp e) {/* Ignore */} } /** * #### method description #### * @param param_name param description * @return return description * @throws ExceptionControlApp * @throws exception_type circumstances description */ public synchronized void endMitigation(String attackKey) { // take care about some clean-up in case first running fails String mitigationKey = null; String mitigationStatusStr; try { mitigationKey = (String) dfAppRootFullImpl.attacksRepo.getCellValue(attackKey, Attack.MITIGATION_KEY); mitigationStatusStr = (String) dfAppRootFullImpl.mitigationsRepo.getCellValue(mitigationKey, Mitigation.STATUS); } catch (Throwable e) { log.error("Failed to get mitigation status from mitigationsRepo and/or attacksRepo : "+mitigationKey, e); fr.logRecord(DFAppRoot.FR_DF_FAILURE, "DefenseFlow failed to end mitigation of attack on " + Attack.getPrintableAttackTarget(attackKey)); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); return; } if(mitigationStatusStr.equals(Mitigation.Status.ENDED.name())) return; fr.logRecord(DFAppRoot.FR_DF_SECURITY, "DefenseFlow ending mitigation of attack on " + Attack.getPrintableAttackTarget(attackKey)); try { invokeDecoupledSerially(ACTION_END_MITIGATION, mitigationKey); } catch (ExceptionControlApp e1) { log.error("Excepted trying to invokeDecoupledSerialiy " + ACTION_END_MITIGATION +" " + mitigationKey, e1); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); } } public synchronized void decoupledRetryMitigations() { if(!fMain.isOpenForBusiness()) return; // Go over all mitigations and look on NO_RESOURCES try { Hashtable<String,Hashtable<String,Object>> mitigationsTable = dfAppRootFullImpl.mitigationsRepo.getTable(); Iterator<Map.Entry<String,Hashtable<String,Object>>> iter = mitigationsTable.entrySet().iterator(); Hashtable<String,Object> mitigationRow; Mitigation mitigation; Attack.Status attackStatus; String attackStatusStr; while(iter.hasNext()) { mitigationRow = iter.next().getValue(); mitigation = new Mitigation(mitigationRow); if ( mitigation.status != Mitigation.Status.NO_RESOURCES || ! mitigation.mitigationDriverLabel.isEmpty() ) continue; // check status of attack attackStatusStr = (String ) dfAppRootFullImpl.attacksRepo.getCellValue(mitigation.attackKey, Attack.STATUS); if(attackStatusStr == null || attackStatusStr.isEmpty()) continue; // TODO: log error attackStatus = Attack.Status.valueOf( (String ) attackStatusStr); if ( attackStatus != Attack.Status.DECLARED ) continue; // Start to look available driver again startMitigationByDrivers(mitigation.key); } } catch (Throwable e) { log.error("Failed to retryMitigations ", e); //fMain.getFR().logRecord(DFAppRoot.FR_AMS_OPERATIONAL, "Failed to retryMitigations" ); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); } } protected synchronized void decoupledEndMitigation(String mitigationKey) { boolean isError = false; /* Notify all mitigationDrivers to end mitigating. There can be more than one driver mitigating * as some drivers may prefer not to consume the mitigation (respond with not "mitigating"). */ for(MitigationDriver mitigationDriver : dfAppRootFullImpl.mitigationDrivers) { /* End mitigation is decoupled in the mitigation driver. * Retry and recovery should be handled by mitigation driver. * Mitigation manager can handle status of invocation only */ try { mitigationDriver.endMitigation(mitigationKey); } catch (Throwable e) { log.error("Excepted in invocation of endMitigation for mitigationDriver :"+mitigationDriver.getLabel(), e); fr.logRecord(DFAppRoot.FR_DF_FAILURE, "DefenseFlow failed to end mitigation of " + Mitigation.getPrintableMitigationTarget(mitigationKey)); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); isError = true; continue; } } // Don't update status of attack if one of mitigationDrivers has an issue if ( isError == true ) return; try { dfAppRootFullImpl.mitigationsRepo.setCell(mitigationKey, Mitigation.STATUS, Mitigation.Status.ENDED.name()); String attackKey = (String) dfAppRootFullImpl.mitigationsRepo.getCellValue(mitigationKey, Mitigation.ATTACK_KEY); dfAppRootFullImpl.attacksRepo.setCell(attackKey, Attack.STATUS, Attack.Status.ENDED.name()); } catch (ExceptionControlApp e) { log.error("Failed to update mitigationsRepo and/or attacksRepo about end mitigation :"+mitigationKey, e); fr.logRecord(DFAppRoot.FR_DF_FAILURE, "DefenseFlow failed to end mitigation of " + Mitigation.getPrintableMitigationTarget(mitigationKey)); fr.logRecord(DFAppRoot.FR_DF_FAILURE, "DF failed to properly end mitigation " + mitigationKey); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); } // check if any mitigations waiting for resources decoupledRetryMitigations(); } @Override public List<Mitigation> getAllPNMitigations(String pnkey) { List<Mitigation> mitigations = new ArrayList<Mitigation>(); String currentPNKey; Hashtable<String, Object> mitigationRow; Mitigation mitigation; try { List<String> mitigationKeys = dfAppRootFullImpl.mitigationsRepo.getKeys(); for ( String mitigationKey : mitigationKeys) { try { currentPNKey = (String) dfAppRootFullImpl.mitigationsRepo.getCellValue(mitigationKey, Mitigation.PNKEY); if ( currentPNKey.equals(pnkey)) { mitigationRow = dfAppRootFullImpl.mitigationsRepo.getRow(mitigationKey); mitigation = new Mitigation(mitigationRow); mitigations.add(mitigation); } } catch (Throwable e) { log.error("Failed to get mitigation from mitigationsRepo :"+mitigationKey, e); fr.logRecord(DFAppRoot.FR_DF_FAILURE, "DF Failed to get mitigation from mitigationsRepo : " + mitigationKey); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); } } } catch( Throwable e1) { log.error("Failed to get mitigations for PN :"+pnkey, e1); //fr.logRecord(DFAppRoot.FR_DF_FAILURE, "DF Failed to get mitigations for PN: " + pnkey); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); } return mitigations; } public void netNodeStatusChanged(String logicalNetNodeLabel, HealthStatus healthStatus) { if(healthStatus == HealthStatus.UP) { try { invokeDecoupledSerially(ACTION_RETRY_MITIGATION, null ); } catch (Throwable e) { log.error("Failed to invoke handling of status change UP of netNode " + logicalNetNodeLabel, e); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); } } else { for(MitigationDriver mitigationDriver : dfAppRootFullImpl.mitigationDrivers) { mitigationDriver.netNodeStatusDowned(logicalNetNodeLabel, healthStatus); } } } @Override public void notifyFailedAMSs(List<String> failedAMSs) { for(MitigationDriver mitigationDriver : dfAppRootFullImpl.mitigationDrivers) { mitigationDriver.handleFailedAMSs(failedAMSs); } } public boolean removeAMS(String amsLabel) { // Check if there are any active mitigations try { List<String> mitigationKeys = dfAppRootFullImpl.mitigationsRepo.getKeys(); Mitigation.Status mitigationStatus; String mitigationStatusStr; for(String mitigationKey : mitigationKeys) { mitigationStatusStr = (String) dfAppRootFullImpl.mitigationsRepo.getCellValue(mitigationKey, Mitigation.STATUS); mitigationStatus = Status.valueOf((String) mitigationStatusStr); if(mitigationStatus == Mitigation.Status.ACTIVE) return false; // TODO: check if the mitigation involves this AMS } return true; } catch (Throwable e) { log.error("Failed to check if there are active mitigations", e); //fMain.getFR().logRecord(DFAppRoot.FR_DF_FAILURE, "Failed to check if there are active mitigations" ); fMain.getHealthTracker().reportHealthIssue(HealthTracker.MINOR_HEALTH_ISSUE); return false; } } @Override protected void actionSwitcher(int actionCode, Object param) { switch(actionCode) { case ACTION_RESERVED: break; case ACTION_ADD_PN: decoupledAddPN((String) param); break; case ACTION_REMOVE_PN: decoupledRemovePN((String) param); break; case ACTION_MITIGATE: decoupledMitigate((MitigationInfo) param); break; case ACTION_END_MITIGATION: decoupledEndMitigation((String) param); break; case ACTION_RETRY_MITIGATION: decoupledRetryMitigations(); default: break; } } }