package org.opennaas.extensions.quantum.network.builder; import java.io.IOException; import java.util.List; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.joda.time.DateTime; import org.opennaas.core.resources.ActivatorException; import org.opennaas.core.resources.IResource; import org.opennaas.core.resources.ResourceException; import org.opennaas.core.resources.configurationadmin.ConfigurationAdminUtil; import org.opennaas.core.resources.protocol.ProtocolException; import org.opennaas.extensions.bod.autobahn.model.AutobahnLink; import org.opennaas.extensions.bod.capability.l2bod.BoDLink; import org.opennaas.extensions.bod.capability.l2bod.IL2BoDCapability; import org.opennaas.extensions.bod.capability.l2bod.RequestConnectionParameters; import org.opennaas.extensions.network.model.NetworkModelHelper; import org.opennaas.extensions.network.model.topology.Interface; import org.opennaas.extensions.network.model.topology.NetworkElement; import org.opennaas.extensions.quantum.Activator; import org.opennaas.extensions.quantum.QuantumException; import org.opennaas.extensions.quantum.model.AutobahnElement; import org.opennaas.extensions.quantum.model.Network; import org.opennaas.extensions.quantum.model.NetworkModel; import org.opennaas.extensions.quantum.model.QuantumModel; import org.opennaas.extensions.quantum.model.Resource; import org.opennaas.extensions.quantum.model.ResourceElement; /** * * @author Adrian Rosello (i2CAT) * */ public class AutobahnBuilder implements NetworkBuilder { private Log log = LogFactory.getLog(AutobahnBuilder.class); private static final String PROPERTIES_PATH = "org.opennaas.extensions.quantum.autobahn"; /** * Set link capacity to 100 MB/s */ private static final long CAPACITY = 100 * 1000000L; @Override public NetworkModel buildNetwork(Network network) throws QuantumException { log.info("Building Autobahn network"); RequestConnectionParameters requestParams; try { Properties props = loadAutobahnProperties(); IResource autobahnResource = NetworkBuilderHelper.getResourceByTypeAndName(props.getProperty(AutobahnPropertiesConstants.RESOURCE_NAME), "bod"); requestParams = createL2BoDCreateConnectionRequest(props); IL2BoDCapability capability = (IL2BoDCapability) autobahnResource.getCapabilityByInterface(IL2BoDCapability.class); capability.requestConnection(requestParams); NetworkBuilderHelper.executeResourceQueue(autobahnResource); org.opennaas.extensions.network.model.NetworkModel model = (org.opennaas.extensions.network.model.NetworkModel) autobahnResource .getModel(); BoDLink link = getBoDLinkByRequestConnection(model, requestParams); if (link == null) throw new QuantumException("There's no link in Autobahn model with the requested parameters."); NetworkModel builtModel = createBuiltModel(network.getId(), autobahnResource.getResourceIdentifier().getId(), link); log.info("Autobahn network built"); return builtModel; } catch (Exception e) { log.error("Error building Autobahn Network : " + e.getMessage()); throw new QuantumException(e); } } @Override public void destroyNetwork(IResource quantumResource, Network network) throws QuantumException { log.info("Destroying Autobahn network"); IResource autobahnResource; try { String netId = network.getId(); QuantumModel model = (QuantumModel) quantumResource.getModel(); NetworkModel netModel = NetworkBuilderHelper.getNetworkModelFromQuantumNetworkId(model.getNetworksModel(), netId); if (netModel == null) throw new QuantumException("There's no resource referenced by Quantum network " + network.getName()); for (Resource resource : netModel.getResources()) { String resourceId = resource.getResourceId(); autobahnResource = NetworkBuilderHelper.getResourceById(resourceId); for (ResourceElement element : resource.getResourceElement()) if (element instanceof AutobahnElement) removeAutobahnLinks(autobahnResource, (AutobahnElement) element); } } catch (Exception e) { log.error("Error destroying Autobahn Network : " + e.getMessage()); throw new QuantumException(e); } } private void removeAutobahnLinks(IResource autobahnResource, AutobahnElement autobahnElem) throws ResourceException, ProtocolException { for (BoDLink link : autobahnElem.getLinks()) { IL2BoDCapability capability = (IL2BoDCapability) autobahnResource.getCapabilityByInterface(IL2BoDCapability.class); capability.shutDownConnection(link); } NetworkBuilderHelper.executeResourceQueue(autobahnResource); } private BoDLink getBoDLinkByRequestConnection(org.opennaas.extensions.network.model.NetworkModel model, RequestConnectionParameters requestParams) { List<NetworkElement> links = NetworkModelHelper.getNetworkElementsByClassName(AutobahnLink.class, model.getNetworkElements()); for (NetworkElement link : links) { AutobahnLink bodLink = (AutobahnLink) link; if (compareRequestParameters(bodLink.getRequestParameters(), requestParams)) return bodLink; } return null; } /** * Loads Autobahn properties from configuration file, and asserts all expected attributes are set. * * @return * @throws IOException * @throws QuantumException */ private Properties loadAutobahnProperties() throws IOException, QuantumException { log.debug("Loading autobahn properties from config file " + PROPERTIES_PATH); Properties props = loadProperties(); if (props.get(AutobahnPropertiesConstants.RESOURCE_NAME) == null) throw new QuantumException("Autobahn configuration file does not contain any property with name \"autobahn.resource.name\""); if (props.get(AutobahnPropertiesConstants.PORT_SRC) == null) throw new QuantumException("Autobahn configuration file does not contain any property with name \"autobahn.port.src\""); if (props.get(AutobahnPropertiesConstants.PORT_DST) == null) throw new QuantumException("Autobahn configuration file does not contain any property with name \"autobahn.port.dst\""); if (props.get(AutobahnPropertiesConstants.VLAN_SRC) == null) throw new QuantumException("Autobahn configuration file does not contain any property with name \"autobahn.vlan.src\""); if (props.get(AutobahnPropertiesConstants.VLAN_DST) == null) throw new QuantumException("Autobahn configuration file does not contain any property with name \"autobahn.vlan.dst\""); log.debug("Autobahn properties loaded."); return props; } private RequestConnectionParameters createL2BoDCreateConnectionRequest(Properties props) throws ActivatorException, ResourceException { log.debug("Building Autobahn request to create a new connection"); IResource autobahnResource = NetworkBuilderHelper.getResourceByTypeAndName(props.getProperty(AutobahnPropertiesConstants.RESOURCE_NAME), "bod"); org.opennaas.extensions.network.model.NetworkModel autobahNModel = (org.opennaas.extensions.network.model.NetworkModel) autobahnResource .getModel(); Interface srcInt = NetworkBuilderHelper.getInterfaceByName(autobahNModel.getNetworkElements(), props.getProperty(AutobahnPropertiesConstants.PORT_SRC)); Interface srcDst = NetworkBuilderHelper.getInterfaceByName(autobahNModel.getNetworkElements(), props.getProperty(AutobahnPropertiesConstants.PORT_DST)); DateTime startDate = DateTime.now(); DateTime expirationDate = startDate.plusYears(1); int srcVlan = Integer.parseInt(props.getProperty(AutobahnPropertiesConstants.VLAN_SRC)); int dstVlan = Integer.parseInt(props.getProperty(AutobahnPropertiesConstants.VLAN_DST)); RequestConnectionParameters parameters = new RequestConnectionParameters(srcInt, srcDst, CAPACITY, srcVlan, dstVlan, startDate, expirationDate); log.debug("Autobahn request built."); return parameters; } private NetworkModel createBuiltModel(String networkId, String resourceId, BoDLink link) { AutobahnElement autobahnElement = new AutobahnElement(); autobahnElement.addLink(link); Resource resource = new Resource(); resource.setResourceId(resourceId); resource.addResourceElement(autobahnElement); NetworkModel builtModel = new NetworkModel(); builtModel.setQuantumNetworkId(networkId); builtModel.addResource(resource); return builtModel; } private Properties loadProperties() throws IOException { Properties props = ConfigurationAdminUtil.getProperties(Activator.getContext(), PROPERTIES_PATH); if (props == null) throw new IOException("Failed to load physicalInfrastructure configuration file " + PROPERTIES_PATH); return props; } private boolean compareRequestParameters(RequestConnectionParameters requestParams1, RequestConnectionParameters requestParams2) { if (requestParams1.capacity != requestParams2.capacity) return false; if (requestParams1.interface1 == null) { if (requestParams2.interface1 != null) return false; } if (requestParams1.interface2 == null) { if (requestParams2.interface2 != null) return false; } if (requestParams1.vlanid1 != requestParams2.vlanid1) return false; if (requestParams1.vlanid2 != requestParams2.vlanid2) return false; return true; } }