package org.opendaylight.openflowplugin.openflow.md.core.sal;
import java.math.BigInteger;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.openflowplugin.openflow.md.ModelDrivenSwitch;
-import org.opendaylight.openflowplugin.openflow.md.SwitchInventory;
-import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
import org.opendaylight.openflowplugin.openflow.md.core.session.SessionListener;
import org.opendaylight.openflowplugin.openflow.md.core.session.SessionManager;
+import org.opendaylight.openflowplugin.openflow.md.core.session.SwitchSessionKeyOF;
+import org.opendaylight.openflowplugin.openflow.md.lldp.LLDPSpeaker;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdatedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
+import org.opendaylight.yangtools.concepts.CompositeObjectRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
import org.slf4j.Logger;
/**
* session and inventory listener implementation
*/
-public class SalRegistrationManager implements SessionListener, SwitchInventory {
+public class SalRegistrationManager implements SessionListener, AutoCloseable {
private final static Logger LOG = LoggerFactory.getLogger(SalRegistrationManager.class);
- Map<InstanceIdentifier<Node>, ModelDrivenSwitch> salSwitches = new ConcurrentHashMap<>();
-
private ProviderContext providerContext;
private NotificationProviderService publishService;
+ private DataBroker dataService;
+
+ private SwitchFeaturesUtil swFeaturesUtil;
+
+ public SalRegistrationManager() {
+ swFeaturesUtil = SwitchFeaturesUtil.getInstance();
+ }
+
public NotificationProviderService getPublishService() {
return publishService;
}
}
public void onSessionInitiated(ProviderContext session) {
+ LOG.debug("onSessionInitiated");
this.providerContext = session;
this.publishService = session.getSALService(NotificationProviderService.class);
-
+ this.dataService = session.getSALService(DataBroker.class);
// We register as listener for Session Manager
getSessionManager().registerSessionListener(this);
- LOG.info("SalRegistrationManager initialized");
-
+ getSessionManager().setNotificationProviderService(publishService);
+ getSessionManager().setDataBroker(dataService);
+ LOG.debug("SalRegistrationManager initialized");
}
@Override
- public void onSessionAdded(SwitchConnectionDistinguisher sessionKey, SessionContext context) {
+ public void onSessionAdded(SwitchSessionKeyOF sessionKey, SessionContext context) {
GetFeaturesOutput features = context.getFeatures();
BigInteger datapathId = features.getDatapathId();
InstanceIdentifier<Node> identifier = identifierFromDatapathId(datapathId);
NodeRef nodeRef = new NodeRef(identifier);
NodeId nodeId = nodeIdFromDatapathId(datapathId);
ModelDrivenSwitchImpl ofSwitch = new ModelDrivenSwitchImpl(nodeId, identifier, context);
- salSwitches.put(identifier, ofSwitch);
- ofSwitch.register(providerContext);
+ LLDPSpeaker.getInstance().addModelDrivenSwitch(identifier, ofSwitch);
+ CompositeObjectRegistration<ModelDrivenSwitch> registration = ofSwitch.register(providerContext);
+ context.setProviderRegistration(registration);
- LOG.info("ModelDrivenSwitch for {} registered to MD-SAL.", datapathId.toString());
+ LOG.debug("ModelDrivenSwitch for {} registered to MD-SAL.", datapathId.toString());
- publishService.publish(nodeAdded(ofSwitch, features,nodeRef));
+ publishService.publish(nodeAdded(ofSwitch, features, nodeRef));
}
@Override
InstanceIdentifier<Node> identifier = identifierFromDatapathId(datapathId);
NodeRef nodeRef = new NodeRef(identifier);
NodeRemoved nodeRemoved = nodeRemoved(nodeRef);
+ LLDPSpeaker.getInstance().removeModelDrivenSwitch(identifier);
+ if (context.isValid()) {
+ CompositeObjectRegistration<ModelDrivenSwitch> registration = context.getProviderRegistration();
+ registration.close();
+ }
- LOG.info("ModelDrivenSwitch for {} unregistred from MD-SAL.", datapathId.toString());
+ LOG.debug("ModelDrivenSwitch for {} unregistered from MD-SAL.", datapathId.toString());
publishService.publish(nodeRemoved);
}
NodeUpdatedBuilder builder = new NodeUpdatedBuilder();
builder.setId(sw.getNodeId());
builder.setNodeRef(nodeRef);
+
+ FlowCapableNodeUpdatedBuilder builder2 = new FlowCapableNodeUpdatedBuilder();
+ builder2.setIpAddress(getIpAddressOf(sw));
+ builder2.setSwitchFeatures(swFeaturesUtil.buildSwitchFeatures(features));
+ builder.addAugmentation(FlowCapableNodeUpdated.class, builder2.build());
+
return builder.build();
}
+ private IpAddress getIpAddressOf(ModelDrivenSwitch sw) {
+ SessionContext sessionContext = sw.getSessionContext();
+ if (!sessionContext.isValid()) {
+ LOG.warn("IP address of the node {} cannot be obtained. Session is not valid.", sw.getNodeId());
+ return null;
+ }
+ InetSocketAddress remoteAddress = sessionContext.getPrimaryConductor().getConnectionAdapter()
+ .getRemoteAddress();
+ if (remoteAddress == null) {
+ LOG.warn("IP address of the node {} cannot be obtained. No connection with switch.", sw.getNodeId());
+ return null;
+ }
+ return resolveIpAddress(remoteAddress.getAddress());
+ }
+
+ private static IpAddress resolveIpAddress(InetAddress address) {
+ String hostAddress = address.getHostAddress();
+ if (address instanceof Inet4Address) {
+ return new IpAddress(new Ipv4Address(hostAddress));
+ }
+ if (address instanceof Inet6Address) {
+ return new IpAddress(new Ipv6Address(hostAddress));
+ }
+ throw new IllegalArgumentException("Unsupported IP address type!");
+ }
+
private NodeRemoved nodeRemoved(NodeRef nodeRef) {
NodeRemovedBuilder builder = new NodeRemovedBuilder();
builder.setNodeRef(nodeRef);
return builder.build();
}
- @Override
- public ModelDrivenSwitch getSwitch(NodeRef node) {
- return salSwitches.get(node.getValue());
- }
-
public static InstanceIdentifier<Node> identifierFromDatapathId(BigInteger datapathId) {
- InstanceIdentifierBuilder<?> builder = InstanceIdentifier.builder().node(Nodes.class);
-
NodeKey nodeKey = nodeKeyFromDatapathId(datapathId);
- return builder.node(Node.class, nodeKey).toInstance();
+ InstanceIdentifierBuilder<Node> builder = InstanceIdentifier.builder(Nodes.class).child(Node.class, nodeKey);
+ return builder.toInstance();
}
public static NodeKey nodeKeyFromDatapathId(BigInteger datapathId) {
public SessionManager getSessionManager() {
return OFSessionUtil.getSessionManager();
}
+
+ @Override
+ public void close() {
+ LOG.debug("close");
+ dataService = null;
+ providerContext = null;
+ publishService = null;
+ }
}