1 /*
\r * Copyright (c) 2015 Huawei, Inc. and others. All rights reserved.
\r *
\r * This program and the accompanying materials are made available under the
\r * terms of the Eclipse Public License v1.0 which accompanies this distribution,
\r * and is available at http://www.eclipse.org/legal/epl-v10.html
\r */
\r\rpackage org.opendaylight.nemo.renderer.openflow;
\r\rimport org.opendaylight.controller.md.sal.binding.api.DataBroker;
\rimport org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
\rimport org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
\rimport org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
\rimport org.slf4j.Logger;
\rimport org.slf4j.LoggerFactory;
\r\rimport com.google.common.util.concurrent.FutureCallback;
\rimport com.google.common.util.concurrent.Futures;
\r\rimport com.google.common.collect.HashBasedTable;
\rimport com.google.common.collect.Table;
\r\rimport java.util.*;
\rimport java.util.concurrent.Executors;
\rimport java.util.concurrent.ScheduledExecutorService;
\rimport com.google.common.util.concurrent.CheckedFuture;
\r\rimport org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
\rimport org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
\r\r\rimport com.fasterxml.jackson.core.JsonProcessingException;
\rimport com.fasterxml.jackson.databind.JsonNode;
\rimport com.fasterxml.jackson.databind.ObjectMapper;
\r\r\rimport java.io.BufferedReader;
\rimport java.io.FileInputStream;
\rimport java.io.IOException;
\rimport java.io.InputStreamReader;
\rimport java.lang.*;
\r\rimport org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
\rimport org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
\rimport org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
\r\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNetworkBuilder;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNetwork;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalNodeInstance;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.PhysicalPortInstance;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.attribute.instance.AttributeValue;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.attribute.instance.AttributeValueBuilder;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.nodes.PhysicalNode;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.nodes.PhysicalNodeBuilder;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.nodes.PhysicalNodeKey;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLink;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLinkBuilder;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.links.PhysicalLinkKey;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.PhysicalPort;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.PhysicalPortBuilder;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.PhysicalPortKey;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.port.instance.Attribute;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.port.instance.AttributeBuilder;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.port.instance.AttributeKey;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.AttributeName;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalNodeId;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalPortId;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalLinkId;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalHostId;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nemo.engine.common.rev151010.PhysicalHostName;
\r\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.hosts.PhysicalHostBuilder;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.hosts.PhysicalHostKey;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.physical.hosts.PhysicalHost;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.host.instance.IpAddresses;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.host.instance.IpAddressesBuilder;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalNodes;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalLinks;
\rimport org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.network.PhysicalHosts;
\r\r\rimport org.opendaylight.nemo.renderer.openflow.entity.ResourceBean;
\r\rpublic class ResourceManager implements AutoCloseable {
\r \r private static final Logger LOG = LoggerFactory.getLogger(ResourceManager.class);
\r\r public final static String PROPERTY_FILE_PATH = "etc/nemo/nemo-openflow-renderer-resource.json";
\r\r final private DataBroker dataProvider;
\r\r private ObjectMapper objectMapper = null;
\r\r private Table<PhysicalNodeId, PhysicalPortId, MacAddress> externalNetworkMacTable;
\r\r public ResourceManager(DataBroker dataProvider){
\r \r this.dataProvider = dataProvider;
\r\r this.objectMapper = new ObjectMapper();
\r\r this.externalNetworkMacTable = HashBasedTable.create();
\r\r String resourceInfo = ReadFile(PROPERTY_FILE_PATH);
\r\r buildPhysicalNetworkFromConfig(resourceInfo);
\r\r LOG.info("nemo:Initialized resource manager for Openflow renderer.");
\r }
\r\r public Table<PhysicalNodeId, PhysicalPortId, MacAddress> getExternalNetworkMacTable(){
\r\r return this.externalNetworkMacTable;
\r }
\r\r private void buildPhysicalNetworkFromConfig(String resource) {
\r try {
\r\r PhysicalNetworkBuilder phyNetwrokBuilder= new PhysicalNetworkBuilder();
\r PhysicalNodeBuilder phyNodeBuilder = new PhysicalNodeBuilder();
\r\r JsonNode rootNode = objectMapper.readTree(resource);
\r\r JsonNode pn = rootNode.path("physicalnetwork");
\r\r JsonNode nodes = pn.path("node");
\r JsonNode links = pn.path("link");
\r JsonNode hosts = pn.path("host");
\r\r\r LOG.debug("Import physical nodes into DataStore.");
\r for(int i = 0; i< nodes.size(); i++){
\r LOG.debug("build physical node execution body");
\r\r //JsonNode node = nodeIt.next();
\r JsonNode node = nodes.get(i);
\r JsonNode ports = node.path("port");
\r\r PhysicalNodeBuilder nodeBuilder = new PhysicalNodeBuilder();
\r nodeBuilder.setNodeId(new PhysicalNodeId(node.get("node-id").asText()));
\r PhysicalNodeKey key = new PhysicalNodeKey(nodeBuilder.getNodeId());
\r nodeBuilder.setKey(key);
\r\r String nodetype = node.get("node-type").asText();
\r\r if((!(nodetype.equals("switch"))) && (!(nodetype.equals("router")))){
\r\r continue;
\r }
\r if(nodetype.equals("switch"))
\r {
\r nodeBuilder.setNodeType(PhysicalNodeInstance.NodeType.Switch);
\r\r }else if(nodetype.equals("router")){
\r\r nodeBuilder.setNodeType(PhysicalNodeInstance.NodeType.Router);
\r }
\r\r List<PhysicalPort> phyPortList = new ArrayList<PhysicalPort>();
\r\r //for (Iterator<JsonNode> portIt = ports.elements(); portIt.hasNext(); ) {
\r for(int j =0; j < ports.size(); j++){
\r\r LOG.debug("build physical port execution body");
\r\r //JsonNode port = portIt.next();
\r JsonNode port = ports.get(j);
\r\r PhysicalPortBuilder phyPortbuilder = new PhysicalPortBuilder();
\r\r phyPortbuilder.setPortId(new PhysicalPortId(port.get("port-id").asText()));
\r\r if((port.get("port-type").asText()).equals("external")) {
\r\r phyPortbuilder.setPortType(PhysicalPortInstance.PortType.External);
\r }
\r else {
\r\r phyPortbuilder.setPortType(PhysicalPortInstance.PortType.Internal);
\r }
\r\r //add mac-address for each port
\r LOG.info("nemo:j=" + j);
\r MacAddress mac = new MacAddress(port.get("port-mac-address").asText());
\r phyPortbuilder.setMacAddress(mac);
\r\r\r phyPortbuilder.setBandwidth((long) (port.get("bandwidth").asInt()));
\r\r JsonNode attrs = port.path("attribute");
\r\r List<Attribute> AttrList = new ArrayList<Attribute>();
\r\r for(int r = 0; r < attrs.size(); r++){
\r LOG.debug("build physical port attribute execution body.");
\r JsonNode portattr = attrs.get(r);
\r AttributeBuilder attrbuilder = new AttributeBuilder();
\r attrbuilder.setAttributeName(new AttributeName(portattr.path("name").asText()));
\r AttributeValueBuilder avbd = new AttributeValueBuilder();
\r avbd.setStringValue(portattr.path("value").asText());
\r attrbuilder.setKey(new AttributeKey(attrbuilder.getAttributeName()));
\r attrbuilder.setAttributeValue(avbd.build());
\r Attribute attr_instance = attrbuilder.build();
\r AttrList.add(attr_instance);
\r }
\r\r /*
\r Iterator<String> keys = attrs.fieldNames();
\r while(keys.hasNext()) {
\r\r LOG.info("build physical port attribute execution body.");
\r String fieldName = keys.next();
\r\r\r attrbuilder.setAttributeName(new AttributeName(fieldName));
\r AttributeValueBuilder avbd = new AttributeValueBuilder();
\r avbd.setStringValue(attrs.path(fieldName).asText());
\r attrbuilder.setKey(new AttributeKey(attrbuilder.getAttributeName()));
\r attrbuilder.setAttributeValue(avbd.build());
\r Attribute attr_instance = attrbuilder.build();
\r AttrList.add(attr_instance);
\r }
\r */
\r\r phyPortbuilder.setAttribute(AttrList);
\r phyPortList.add(phyPortbuilder.build());
\r }
\r nodeBuilder.setPhysicalPort(phyPortList);
\r\r /*node attribute list*/
\r JsonNode node_attrs = node.path("attribute");
\r List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.Attribute>
\r node_AttrList = new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.Attribute>();
\r for(int t = 0; t < node_attrs.size(); t++){
\r LOG.debug("build physical node attribute execution body.");
\r JsonNode node_attr = node_attrs.get(t);
\r org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.AttributeBuilder
\r attrbuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.AttributeBuilder();
\r attrbuilder.setAttributeName(new AttributeName(node_attr.path("name").asText()));
\r AttributeValueBuilder avbd = new AttributeValueBuilder();
\r avbd.setStringValue(node_attr.path("value").asText());
\r attrbuilder.setKey(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.AttributeKey(attrbuilder.getAttributeName()));
\r attrbuilder.setAttributeValue(avbd.build());
\r org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.Attribute node_attr_instance = attrbuilder.build();
\r node_AttrList.add(node_attr_instance);
\r }
\r nodeBuilder.setAttribute((List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.generic.physical.network.rev151010.physical.node.instance.Attribute>) node_AttrList);
\r\r PhysicalNode phyNode = nodeBuilder.build();
\r //phyNodeList.add(phyNode);
\r\r LOG.debug("Ready to write node to data store.");
\r try {
\r WriteTransaction t = dataProvider.newWriteOnlyTransaction();
\r InstanceIdentifier<PhysicalNode> phynode_iid = InstanceIdentifier
\r .builder(PhysicalNetwork.class)
\r .child(PhysicalNodes.class)
\r .child(PhysicalNode.class, key)
\r .build();
\r t.put(LogicalDatastoreType.OPERATIONAL, phynode_iid, phyNode, true);
\r\r CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();
\r Futures.addCallback(f, new FutureCallback<Void>() {
\r @Override
\r public void onFailure(Throwable t) {
\r System.out.println("write transaction onFailure.");
\r LOG.error("Could not write PhysicalNode", t);
\r }
\r\r @Override
\r public void onSuccess(Void result) {
\r //System.out.println("write transaction onSuccess.");
\r LOG.debug("write transaction onSuccess.");
\r }
\r });
\r\r } catch (Exception e) {
\r e.printStackTrace();
\r }
\r }
\r\r LOG.debug("Import physical links into DataStore.");
\r for(int m = 0; m< links.size(); m++){
\r\r LOG.debug("build physical link execution body");
\r JsonNode link = links.get(m);
\r\r String strLeftNodeId = link.get("left-node-id").asText();
\r String strRightNodeId = link.get("right-node-id").asText();
\r\r if(strLeftNodeId.contains("external")||strRightNodeId.contains("external")){
\r String strExternalNodeId = "";
\r PhysicalNodeId accessNodeId = null;
\r PhysicalPortId accessPortId = null;
\r if(strLeftNodeId.contains("external")){
\r strExternalNodeId = strLeftNodeId;
\r accessNodeId = new PhysicalNodeId(link.get("right-node-id").asText());
\r accessPortId = new PhysicalPortId(link.get("right-port-id").asText());
\r }else{
\r strExternalNodeId = strRightNodeId;
\r accessNodeId = new PhysicalNodeId(link.get("left-node-id").asText());
\r accessPortId = new PhysicalPortId(link.get("left-port-id").asText());
\r }
\r\r for(int b = 0; b < nodes.size(); b++){
\r\r JsonNode pnode = nodes.get(b);
\r if(strExternalNodeId.equals(pnode.get("node-id").asText())){
\r\r MacAddress macAddress = new MacAddress(pnode.get("mac-address").asText());
\r this.externalNetworkMacTable.put(accessNodeId, accessPortId, macAddress);
\r break;
\r }
\r }
\r\r continue;
\r }
\r\r PhysicalLinkBuilder linkBuilder = new PhysicalLinkBuilder();
\r\r PhysicalLinkId phylinkid = new PhysicalLinkId(link.get("link-id").asText());
\r linkBuilder.setLinkId(phylinkid);
\r linkBuilder.setSrcNodeId(new PhysicalNodeId(link.get("left-node-id").asText()));
\r linkBuilder.setSrcPortId(new PhysicalPortId(link.get("left-port-id").asText()));
\r linkBuilder.setDestNodeId(new PhysicalNodeId(link.get("right-node-id").asText()));
\r linkBuilder.setDestPortId(new PhysicalPortId(link.get("right-port-id").asText()));
\r\r linkBuilder.setBandwidth((long) (link.get("link-bandwidth").asLong()));
\r linkBuilder.setDelay((long) (link.get("delay").asLong()));
\r linkBuilder.setMetric((long) (link.get("metric").asLong()));
\r linkBuilder.setLossRate((short) (link.get("delay").asInt()));
\r\r PhysicalLink phyLink = linkBuilder.build();
\r\r LOG.debug("Ready to write link to data store.");
\r try {
\r WriteTransaction t = dataProvider.newWriteOnlyTransaction();
\r InstanceIdentifier<PhysicalLink> phylink_iid = InstanceIdentifier
\r .builder(PhysicalNetwork.class)
\r .child(PhysicalLinks.class)
\r .child(PhysicalLink.class, new PhysicalLinkKey(linkBuilder.getLinkId()))
\r .build();
\r t.put(LogicalDatastoreType.OPERATIONAL, phylink_iid, phyLink, true);
\r\r CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();
\r Futures.addCallback(f, new FutureCallback<Void>() {
\r @Override
\r public void onFailure(Throwable t) {
\r System.out.println("write transaction onFailure.");
\r LOG.error("Could not write PhysicalLink", t);
\r }
\r\r @Override
\r public void onSuccess(Void result) {
\r //System.out.println("write transaction onSuccess.");
\r LOG.debug("write transaction onSuccess.");
\r }
\r });
\r\r } catch (Exception e) {
\r e.printStackTrace();
\r }
\r }
\r\r LOG.debug("Import hosts into DataStore.");
\r for(int n = 0; n< hosts.size(); n++){
\r\r LOG.debug("build host execution body");
\r JsonNode host = hosts.get(n);
\r\r PhysicalHostBuilder hostBuilder = new PhysicalHostBuilder();
\r hostBuilder.setHostId(new PhysicalHostId(host.get("id").asText()));
\r hostBuilder.setKey(new PhysicalHostKey(hostBuilder.getHostId()));
\r hostBuilder.setHostName(new PhysicalHostName(host.get("name").asText()));
\r\r IpAddressesBuilder IpAddrBuilder = new IpAddressesBuilder();
\r List<IpAddress> ipList = new ArrayList<IpAddress>();
\r\r JsonNode ipaddrs = host.path("ip-addresses");
\r for(int p = 0 ; p < ipaddrs.size(); p++){
\r JsonNode ipaddr = ipaddrs.get(p);
\r IpAddress ip = new IpAddress(new Ipv4Address(ipaddr.get("ip-address").asText()));
\r ipList.add(ip);
\r }
\r\r IpAddrBuilder.setIpAddress(ipList);
\r hostBuilder.setIpAddresses(IpAddrBuilder.build());
\r MacAddress mac = new MacAddress(host.get("mac-address").asText());
\r hostBuilder.setMacAddress(mac);
\r hostBuilder.setNodeId(new PhysicalNodeId(host.get("node-id").asText()));
\r hostBuilder.setPortId(new PhysicalPortId(host.get("connector-id").asText()));
\r\r PhysicalHost phyHost = hostBuilder.build();
\r LOG.debug("Ready to write host to data store.");
\r try {
\r WriteTransaction t = dataProvider.newWriteOnlyTransaction();
\r InstanceIdentifier<PhysicalHost> phyhost_iid = InstanceIdentifier
\r .builder(PhysicalNetwork.class)
\r .child(PhysicalHosts.class)
\r .child(PhysicalHost.class, new PhysicalHostKey(hostBuilder.getHostId()))
\r .build();
\r t.put(LogicalDatastoreType.OPERATIONAL, phyhost_iid, phyHost, true);
\r\r CheckedFuture<Void, TransactionCommitFailedException> f = t.submit();
\r Futures.addCallback(f, new FutureCallback<Void>() {
\r @Override
\r public void onFailure(Throwable t) {
\r System.out.println("write transaction onFailure.");
\r LOG.error("Could not write PhysicalHost", t);
\r }
\r\r @Override
\r public void onSuccess(Void result) {
\r //System.out.println("write transaction onSuccess.");
\r LOG.debug("write transaction onSuccess.");
\r }
\r });
\r\r } catch (Exception e) {
\r e.printStackTrace();
\r }
\r\r }
\r\r\r } catch (JsonProcessingException e) {
\r e.printStackTrace();
\r } catch(IOException e){
\r e.printStackTrace();
\r }
\r\r LOG.debug("buildPhysicalNetworkFromConfig end.");
\r System.out.print("Loading physical network configuration has been completed.");
\r }
\r\r private String ReadFile(String Path){
\r BufferedReader reader = null;
\r String laststr = "";
\r try{
\r FileInputStream fileInputStream = new FileInputStream(Path);
\r InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
\r reader = new BufferedReader(inputStreamReader);
\r String tempString = null;
\r while((tempString = reader.readLine()) != null){
\r laststr += tempString;
\r }
\r reader.close();
\r }catch(IOException e){
\r e.printStackTrace();
\r }finally{
\r if(reader != null){
\r try {
\r reader.close();
\r } catch (IOException e) {
\r e.printStackTrace();
\r }
\r }
\r }
\r return laststr;
\r }
\r\r @Override
\r public void close() throws Exception {
\r\r }
\r\r\r\r}
\r