X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=openflowplugin-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fopenflowplugin%2Fimpl%2Fdevice%2FDeviceManagerImpl.java;h=36769ce0c207ef0f07fe009b8eaca623c310e9bb;hb=8c2f31bda2054be736edfdbb569b0583a00ef781;hp=447d37761a3c5f3449190cd5b6a7f431463ae041;hpb=f25d407a7212156895fc72899e4c247a185436b0;p=openflowplugin.git diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java index 447d37761a..36769ce0c2 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java @@ -21,13 +21,15 @@ import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService; +import org.opendaylight.controller.md.sal.binding.api.NotificationService; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.sal.binding.api.NotificationProviderService; import org.opendaylight.openflowplugin.api.OFConstants; import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext; import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; @@ -41,13 +43,16 @@ import org.opendaylight.openflowplugin.api.openflow.device.Xid; import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler; import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector; import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey; +import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency; import org.opendaylight.openflowplugin.impl.common.MultipartRequestInputFactory; import org.opendaylight.openflowplugin.impl.common.NodeStaticReplyTranslatorUtil; import org.opendaylight.openflowplugin.impl.device.listener.OpenflowProtocolListenerFullImpl; import org.opendaylight.openflowplugin.impl.rpc.RequestContextImpl; import org.opendaylight.openflowplugin.impl.services.OFJResult2RequestCtxFuture; +import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.MessageIntelligenceAgencyImpl; import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder; @@ -96,15 +101,19 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(DeviceManagerImpl.class); private static final long TICK_DURATION = 500; // 0.5 sec. + private ScheduledThreadPoolExecutor spyPool; + private int spyRate = 10; private final DataBroker dataBroker; private final HashedWheelTimer hashedWheelTimer; - private RequestContextStack dummyRequestContextStack; + private RequestContextStack emptyRequestContextStack; private TranslatorLibrary translatorLibrary; private DeviceInitializationPhaseHandler deviceInitPhaseHandler; - private NotificationProviderService notificationService; - private final List synchronizedDeviceContextsList = Collections - .synchronizedList(new ArrayList()); + private NotificationService notificationService; + private NotificationPublishService notificationPublishService; + + private final List synchronizedDeviceContextsList = new ArrayList(); + private final MessageIntelligenceAgency messageIntelligenceAgency = new MessageIntelligenceAgencyImpl(); public DeviceManagerImpl(@Nonnull final DataBroker dataBroker) { this.dataBroker = Preconditions.checkNotNull(dataBroker); @@ -114,7 +123,7 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { tx.merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class), new NodesBuilder().build()); tx.submit(); - dummyRequestContextStack = new RequestContextStack() { + emptyRequestContextStack = new RequestContextStack() { @Override public void forgetRequestContext(final RequestContext requestContext) { //NOOP @@ -130,6 +139,8 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { return new RequestContextImpl<>(this); } }; + spyPool = new ScheduledThreadPoolExecutor(1); + spyPool.scheduleAtFixedRate(messageIntelligenceAgency, spyRate, spyRate, TimeUnit.SECONDS); } @Override @@ -151,12 +162,15 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { final DeviceState deviceState = new DeviceStateImpl(connectionContext.getFeatures(), connectionContext.getNodeId()); - final DeviceContextImpl deviceContext = new DeviceContextImpl(connectionContext, deviceState, dataBroker, hashedWheelTimer); + final DeviceContext deviceContext = new DeviceContextImpl(connectionContext, deviceState, dataBroker, hashedWheelTimer, messageIntelligenceAgency); deviceContext.setNotificationService(notificationService); + deviceContext.setNotificationPublishService(notificationPublishService); deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, deviceState.getNodeInstanceIdentifier(), new NodeBuilder().setId(deviceState.getNodeId()).build()); + connectionContext.setDeviceDisconnectedHandler(deviceContext); deviceContext.setTranslatorLibrary(translatorLibrary); + deviceContext.addDeviceContextClosedHandler(this); final OpenflowProtocolListenerFullImpl messageListener = new OpenflowProtocolListenerFullImpl( connectionContext.getConnectionAdapter(), deviceContext); @@ -170,7 +184,9 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { DeviceStateUtil.setDeviceStateBasedOnV10Capabilities(deviceState, capabilitiesV10); - deviceFeaturesFuture = Futures.immediateFuture(null);//createDeviceFeaturesForOF10(messageListener, deviceContext, deviceState); + deviceFeaturesFuture = createDeviceFeaturesForOF10(messageListener, deviceContext, deviceState); + // create empty tables after device description is processed + chainTableTrunkWriteOF10(deviceContext, deviceFeaturesFuture); for (final PortGrouping port : connectionContext.getFeatures().getPhyPort()) { final short ofVersion = deviceContext.getDeviceState().getVersion(); @@ -186,7 +202,6 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { final NodeConnector connector = ncBuilder.build(); final InstanceIdentifier connectorII = deviceState.getNodeInstanceIdentifier().child(NodeConnector.class, connector.getKey()); deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, connectorII, connector); - //FlowCapableNodeConnectorBuilder } } else if (connectionContext.getFeatures().getVersion() == OFConstants.OFP_VERSION_1_3) { final Capabilities capabilities = connectionContext.getFeatures().getCapabilities(); @@ -197,19 +212,46 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { Futures.addCallback(deviceFeaturesFuture, new FutureCallback>>>() { @Override public void onSuccess(final List>> result) { + deviceContext.getDeviceState().setValid(true); deviceInitPhaseHandler.onDeviceContextLevelUp(deviceContext); } @Override public void onFailure(final Throwable t) { // FIXME : remove session + LOG.trace("Device capabilities gathering future failed."); + LOG.trace("more info in exploration failure..", t); + } + }); + } + + private void chainTableTrunkWriteOF10(final DeviceContext deviceContext, ListenableFuture>>> deviceFeaturesFuture) { + Futures.addCallback(deviceFeaturesFuture, new FutureCallback>>>() { + @Override + public void onSuccess(List>> results) { + boolean allSucceeded = true; + for (RpcResult> rpcResult : results) { + allSucceeded &= rpcResult.isSuccessful(); + } + if (allSucceeded) { + synchronized (deviceContext) { + createEmptyFlowCapableNodeInDs(deviceContext); + makeEmptyTables(deviceContext, deviceContext.getDeviceState().getNodeInstanceIdentifier(), + deviceContext.getDeviceState().getFeatures().getTables()); + } + } + } + + @Override + public void onFailure(Throwable t) { + //NOOP } }); } private ListenableFuture>> processReplyDesc(OpenflowProtocolListenerFullImpl messageListener, - DeviceContextImpl deviceContext, + DeviceContext deviceContext, DeviceState deviceState) { final ListenableFuture>> replyDesc = getNodeStaticInfo(messageListener, MultipartType.OFPMPDESC, deviceContext, deviceState.getNodeInstanceIdentifier(), deviceState.getVersion()); @@ -217,13 +259,13 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { } private ListenableFuture>>> createDeviceFeaturesForOF10(OpenflowProtocolListenerFullImpl messageListener, - DeviceContextImpl deviceContext, + DeviceContext deviceContext, DeviceState deviceState) { return Futures.allAsList(Arrays.asList(processReplyDesc(messageListener, deviceContext, deviceState))); } private ListenableFuture>>> createDeviceFeaturesForOF13(OpenflowProtocolListenerFullImpl messageListener, - final DeviceContextImpl deviceContext, + final DeviceContext deviceContext, final DeviceState deviceState) { final ListenableFuture>> replyDesc = processReplyDesc(messageListener, deviceContext, deviceState); @@ -239,21 +281,12 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { final ListenableFuture>> replyPortDescription = getNodeStaticInfo(messageListener, MultipartType.OFPMPPORTDESC, deviceContext, deviceState.getNodeInstanceIdentifier(), deviceState.getVersion()); - final ListenableFuture>>> deviceFeaturesFuture = - Futures.allAsList(Arrays.asList(replyDesc, replyMeterFeature, replyGroupFeatures, replyTableFeatures, replyPortDescription)); - - Futures.addCallback(deviceFeaturesFuture, new FutureCallback>>>() { - @Override - public void onSuccess(final List>> result) { - deviceInitPhaseHandler.onDeviceContextLevelUp(deviceContext); - } + return Futures.allAsList(Arrays.asList(replyDesc, + replyMeterFeature, + replyGroupFeatures, +// replyTableFeatures, + replyPortDescription)); - @Override - public void onFailure(final Throwable t) { - // FIXME : remove session - } - }); - return Futures.allAsList(Arrays.asList(replyDesc, replyMeterFeature, replyGroupFeatures, replyTableFeatures, replyPortDescription)); } @Override @@ -270,8 +303,13 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { final InstanceIdentifier nodeII, final short version) { final Xid xid = deviceContext.getNextXid(); - final RequestContext> requestContext = dummyRequestContextStack.createRequestContext(); + final RequestContext> requestContext = emptyRequestContextStack.createRequestContext(); requestContext.setXid(xid); + + LOG.trace("Hooking xid {} to device context - precaution.", requestContext.getXid().getValue()); + deviceContext.hookRequestCtx(requestContext.getXid(), requestContext); + + multiMsgCollector.registerMultipartXid(xid.getValue()); Futures.addCallback(requestContext.getFuture(), new FutureCallback>>() { @Override @@ -310,6 +348,7 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { // FIXME : remove after ovs tableFeatures fix private static void makeEmptyTables(final DeviceContext dContext, final InstanceIdentifier nodeII, final Short nrOfTables) { + LOG.debug("About to create {} empty tables.", nrOfTables); for (int i = 0; i < nrOfTables; i++) { final short tId = (short) i; final InstanceIdentifier tableII = nodeII.augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tId)); @@ -392,14 +431,30 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { } @Override - public void setNotificationService(final NotificationProviderService notificationServiceParam) { + public void setNotificationService(final NotificationService notificationServiceParam) { notificationService = notificationServiceParam; } + @Override + public void setNotificationPublishService(final NotificationPublishService notificationService) { + this.notificationPublishService = notificationService; + } + @Override public void close() throws Exception { for (DeviceContext deviceContext : synchronizedDeviceContextsList) { deviceContext.close(); } } + + private static void createEmptyFlowCapableNodeInDs(final DeviceContext deviceContext) { + FlowCapableNodeBuilder flowCapableNodeBuilder = new FlowCapableNodeBuilder(); + final InstanceIdentifier fNodeII = deviceContext.getDeviceState().getNodeInstanceIdentifier().augmentation(FlowCapableNode.class); + deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, fNodeII, flowCapableNodeBuilder.build()); + } + + @Override + public void onDeviceContextClosed(final DeviceContext deviceContext) { + synchronizedDeviceContextsList.remove(deviceContext); + } }