package org.opennaas.extensions.router.junos.commandsets.digester; import java.io.IOException; import java.util.HashMap; import org.apache.commons.digester.Digester; import org.apache.commons.digester.RuleSetBase; import org.opennaas.extensions.router.model.EnabledLogicalElement.EnabledState; import org.opennaas.extensions.router.model.NetworkPort; import org.opennaas.extensions.router.model.OSPFArea; import org.opennaas.extensions.router.model.OSPFAreaConfiguration; import org.opennaas.extensions.router.model.OSPFProtocolEndpoint; import org.opennaas.extensions.router.model.OSPFService; import org.opennaas.extensions.router.model.RouteCalculationService.AlgorithmType; import org.opennaas.extensions.router.model.System; import org.opennaas.extensions.router.model.utils.IPUtilsHelper; import org.opennaas.extensions.router.model.utils.ModelHelper; public class ProtocolsParser extends DigesterEngine { private System model; private boolean serviceDisabledFlag = false; private OSPFService ospfService; private OSPFService ospfv3Service; class ParserRuleSet extends RuleSetBase { private String prefix = ""; protected ParserRuleSet() { } protected ParserRuleSet(String prefix) { this.prefix = prefix; } @Override public void addRuleInstances(Digester arg0) { addOSPFRuleInstances(arg0); addOSPFv3RuleInstances(arg0); // TODO add other protocol rules (e.g. bgp) } private void addOSPFRuleInstances(Digester digester) { // FIXME the path pattern can't be global , must distinguish between // routers addMyRule("*/protocols/ospf/disable", "setDisabledFlag", 0); addObjectCreate("*/protocols/ospf/area", OSPFArea.class); addMyRule("*/protocols/ospf/area/name", "transformAndSetAreaID", 0); // AreaID required a format transformation addObjectCreate("*/protocols/ospf/area/interface", OSPFProtocolEndpoint.class); addMyRule("*/protocols/ospf/area/interface/name", "configureOSPFProtocolEndpoint", 0); addMyRule("*/protocols/ospf/area/interface/disable", "disableOSPFProtocolEndpoint", 0); addSetNext("*/protocols/ospf/area/interface", "addEndpointInArea"); addSetNext("*/protocols/ospf/area/", "addOSPFArea", OSPFArea.class.getName()); // OSPFService should be created also when addOSPFArea has not been called addMyRule("*/protocols/ospf", "obtainOSPFService", -1); // -1 specifies we want no parameters } private void addOSPFv3RuleInstances(Digester arg0) { // FIXME the path pattern can't be global , must distinguish between // routers addMyRule("*/protocols/ospf3/disable", "setDisabledFlag", 0); addObjectCreate("*/protocols/ospf3/area", OSPFArea.class); addMyRule("*/protocols/ospf3/area/name", "transformAndSetAreaID", 0); // AreaID required a format transformation addObjectCreate("*/protocols/ospf3/area/interface", OSPFProtocolEndpoint.class); addMyRule("*/protocols/ospf3/area/interface/name", "configureOSPFProtocolEndpoint", 0); addMyRule("*/protocols/ospf3/area/interface/disable", "disableOSPFProtocolEndpoint", 0); addSetNext("*/protocols/ospf3/area/interface", "addEndpointInArea"); addSetNext("*/protocols/ospf3/area/", "addOSPFv3Area", OSPFArea.class.getName()); // OSPFService should be created also when addOSPFArea has not been called addMyRule("*/protocols/ospf3", "obtainOSPFv3Service", -1); // -1 specifies we want no parameters } } public ProtocolsParser(System routerModel) { ruleSet = new ParserRuleSet(); setModel(routerModel); } public ProtocolsParser(String prefix, System routerModel) { ruleSet = new ParserRuleSet(prefix); setModel(routerModel); } public System getModel() { return model; } public void setModel(System model) { this.model = model; } @Override public void init() { push(this); // bottom of the stack mapElements = new HashMap<String, Object>(); } public void enableOSPFService() { Object obj = peek(0); assert (obj instanceof OSPFService); ((OSPFService) obj).setEnabledState(EnabledState.ENABLED); } public void disableOSPFService() { Object obj = peek(0); assert (obj instanceof OSPFService); ((OSPFService) obj).setEnabledState(EnabledState.DISABLED); } public void configureOSPFProtocolEndpoint(String interfaceNameShort) { enableOSPFProtocolEndpoint("enable"); Object obj = peek(0); assert (obj instanceof OSPFProtocolEndpoint); OSPFProtocolEndpoint ospfEndpoint = (OSPFProtocolEndpoint) obj; ospfEndpoint.setName(interfaceNameShort); // get interface with given name from model NetworkPort matchingInterface = null; boolean isSubInterface = interfaceNameShort.contains("."); if (isSubInterface) { String ifaceName = interfaceNameShort.split("\\.")[0]; int ifacePortNumber = Integer.parseInt(interfaceNameShort.split("\\.")[1]); for (NetworkPort iface : ModelHelper.getInterfaces(this.getModel())) { if (iface.getName().equals(ifaceName) && iface.getPortNumber() == ifacePortNumber) { matchingInterface = iface; break; } } } else { for (NetworkPort iface : ModelHelper.getInterfaces(this.getModel())) { if (iface.getName().equals(interfaceNameShort)) { matchingInterface = iface; break; } } } if (matchingInterface != null) { matchingInterface.addProtocolEndpoint(ospfEndpoint); } // FIXME cannot get what IPProtocolEndpoints is ospfEndpoint bindedTo. // should we use all IPProtocolEndpoints in matchingInterface??? // I guess not. That would cause a multiple dependency // and we want to say that ospf depends on an IPProtocolEndpoint in that interface // (any of them, but at least one). } public void enableOSPFProtocolEndpoint(String enable) { Object obj = peek(0); assert (obj instanceof OSPFProtocolEndpoint); ((OSPFProtocolEndpoint) obj).setEnabledState(EnabledState.ENABLED); } public void disableOSPFProtocolEndpoint(String disable) { Object obj = peek(0); assert (obj instanceof OSPFProtocolEndpoint); ((OSPFProtocolEndpoint) obj).setEnabledState(EnabledState.DISABLED); } /** * * @param dottedAreaId * @throws IOException */ public void transformAndSetAreaID(String dottedAreaId) throws IOException { assert (dottedAreaId != null); long areaId = IPUtilsHelper.ipv4StringToLong(dottedAreaId); // setAreaId Object obj = peek(0); assert (obj instanceof OSPFArea); ((OSPFArea) obj).setAreaID(areaId); } public void setDisabledFlag(String disabled) { this.serviceDisabledFlag = true; } /** * Creates required structure in model to store OSPFArea. * * @param ospfArea */ public void addOSPFArea(OSPFArea ospfArea) { OSPFService ospfService = obtainOSPFService(); OSPFAreaConfiguration areaConfig = new OSPFAreaConfiguration(); areaConfig.setOSPFArea(ospfArea); ospfService.addOSPFAreaConfiguration(areaConfig); } /** * Get ospfService or creates it if necessary. * * Created OSPFService has its state setted up, and has already been included in model. * * @return */ public OSPFService obtainOSPFService() { if (ospfService != null) return ospfService; ospfService = new OSPFService(); if (serviceDisabledFlag) ospfService.setEnabledState(EnabledState.DISABLED); else ospfService.setEnabledState(EnabledState.ENABLED); ospfService.setAlgorithmType(AlgorithmType.OSPFV2); model.addHostedService(ospfService); return ospfService; } /** * Get ospfv3Service or creates it if necessary. * * Created OSPFService has its state setted up, and has already been included in model. * * @return */ public OSPFService obtainOSPFv3Service() { if (ospfv3Service != null) return ospfv3Service; ospfv3Service = new OSPFService(); if (serviceDisabledFlag) ospfv3Service.setEnabledState(EnabledState.DISABLED); else ospfv3Service.setEnabledState(EnabledState.ENABLED); ospfv3Service.setAlgorithmType(AlgorithmType.OSPFV3); model.addHostedService(ospfv3Service); return ospfv3Service; } /** * Creates required structure in model to store OSPFArea. * * @param ospfArea */ public void addOSPFv3Area(OSPFArea ospfArea) { OSPFService ospfService = obtainOSPFv3Service(); OSPFAreaConfiguration areaConfig = new OSPFAreaConfiguration(); areaConfig.setOSPFArea(ospfArea); ospfService.addOSPFAreaConfiguration(areaConfig); } }