lower log level when stats come before flow is written to deviceflowregistry
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / statistics / StatisticsGatheringUtils.java
index e482a7f792b3428133d55150dad39d3536eda852..06d496161cf8d429f88da099e9c5cae978c9cee8 100644 (file)
@@ -21,15 +21,18 @@ import java.text.SimpleDateFormat;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
+import java.util.Objects;
 import javax.annotation.Nullable;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainClosedException;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry;
 import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
 import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
+import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor;
 import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
 import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
 import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry;
@@ -37,7 +40,7 @@ import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.Event
 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.StatisticsGatherer;
 import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
 import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.DateAndTime;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableStatisticsGatheringStatus;
@@ -119,7 +122,6 @@ public final class StatisticsGatheringUtils {
     private static String DATE_AND_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
 
     private static final Logger LOG = LoggerFactory.getLogger(StatisticsGatheringUtils.class);
-    private static final SinglePurposeMultipartReplyTranslator MULTIPART_REPLY_TRANSLATOR = new SinglePurposeMultipartReplyTranslator();
     private static final String QUEUE2_REQCTX = "QUEUE2REQCTX-";
 
     private StatisticsGatheringUtils() {
@@ -132,7 +134,8 @@ public final class StatisticsGatheringUtils {
                                                       final MultipartType type,
                                                       final TxFacade txFacade,
                                                       final DeviceRegistry registry,
-                                                      final Boolean initial) {
+                                                      final Boolean initial,
+                                                      final SinglePurposeMultipartReplyTranslator multipartReplyTranslator) {
         EventIdentifier wholeProcessEventIdentifier = null;
         if (MultipartType.OFPMPFLOW.equals(type)) {
             wholeProcessEventIdentifier = new EventIdentifier(type.toString(), deviceInfo.getNodeId().getValue());
@@ -142,7 +145,7 @@ public final class StatisticsGatheringUtils {
         final ListenableFuture<RpcResult<List<MultipartReply>>> statisticsDataInFuture =
                 JdkFutureAdapters.listenInPoolThread(statisticsGatheringService.getStatisticsOfType(
                         ofpQueuToRequestContextEventIdentifier, type));
-        return transformAndStoreStatisticsData(statisticsDataInFuture, deviceInfo, wholeProcessEventIdentifier, type, txFacade, registry, initial);
+        return transformAndStoreStatisticsData(statisticsDataInFuture, deviceInfo, wholeProcessEventIdentifier, type, txFacade, registry, initial, multipartReplyTranslator);
     }
 
     private static ListenableFuture<Boolean> transformAndStoreStatisticsData(final ListenableFuture<RpcResult<List<MultipartReply>>> statisticsDataInFuture,
@@ -151,7 +154,8 @@ public final class StatisticsGatheringUtils {
                                                                              final MultipartType type,
                                                                              final TxFacade txFacade,
                                                                              final DeviceRegistry registry,
-                                                                             final boolean initial) {
+                                                                             final boolean initial,
+                                                                             final SinglePurposeMultipartReplyTranslator multipartReplyTranslator) {
         return Futures.transform(statisticsDataInFuture, new AsyncFunction<RpcResult<List<MultipartReply>>, Boolean>() {
             @Nullable
             @Override
@@ -169,7 +173,7 @@ public final class StatisticsGatheringUtils {
 
                         try {
                             for (final MultipartReply singleReply : rpcResult.getResult()) {
-                                final List<? extends DataObject> multipartDataList = MULTIPART_REPLY_TRANSLATOR.translate(
+                                final List<? extends DataObject> multipartDataList = multipartReplyTranslator.translate(
                                         deviceInfo.getDatapathId(),
                                         deviceInfo.getVersion(), singleReply);
                                 multipartData = multipartDataList.get(0);
@@ -281,13 +285,18 @@ public final class StatisticsGatheringUtils {
 
                     final short tableId = flowStat.getTableId();
                     final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(flowBuilder.build());
-                    final FlowId flowId = registry.storeIfNecessary(flowRegistryKey);
-
-                    final FlowKey flowKey = new FlowKey(flowId);
-                    flowBuilder.setKey(flowKey);
-                    final TableKey tableKey = new TableKey(tableId);
-                    final InstanceIdentifier<Flow> flowIdent = fNodeIdent.child(Table.class, tableKey).child(Flow.class, flowKey);
-                    txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, flowIdent, flowBuilder.build());
+                    final FlowDescriptor flowDescriptor = registry.retrieveIdForFlow(flowRegistryKey);
+
+                    if(Objects.nonNull(flowDescriptor)) {
+                        final FlowId flowId = flowDescriptor.getFlowId();
+                        final FlowKey flowKey = new FlowKey(flowId);
+                        flowBuilder.setKey(flowKey);
+                        final TableKey tableKey = new TableKey(tableId);
+                        final InstanceIdentifier<Flow> flowIdent = fNodeIdent.child(Table.class, tableKey).child(Flow.class, flowKey);
+                        txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, flowIdent, flowBuilder.build());
+                    } else {
+                        LOG.debug("Skip write statistics. Flow hash: {} not present in DeviceFlowRegistry", flowRegistryKey.hashCode());
+                    }
                 }
             }
         } catch (Exception e) {
@@ -339,7 +348,6 @@ public final class StatisticsGatheringUtils {
                         txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToTable, table);
                     }
                 }
-                registry.removeMarked();
                 readTx.close();
                 return Futures.immediateFuture(null);
             }
@@ -500,8 +508,9 @@ public final class StatisticsGatheringUtils {
                 .build();
         try {
             deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, statusPath, gatheringStatus);
-        } catch (final Exception e) {
-            LOG.warn("Can't write to transaction: {}", e);
+        } catch (final TransactionChainClosedException e) {
+            LOG.warn("Can't write to transaction, transaction chain probably closed.");
+            LOG.trace("Write to transaction exception: ", e);
         }
 
         deviceContext.submitTransaction();
@@ -525,8 +534,9 @@ public final class StatisticsGatheringUtils {
                 .build();
         try {
             deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, statusEndPath, gatheringStatus);
-        } catch (Exception e) {
-            LOG.warn("Can't write to transaction: {}", e);
+        } catch (TransactionChainClosedException e) {
+            LOG.warn("Can't write to transaction, transaction chain probably closed.");
+            LOG.trace("Write to transaction exception: ", e);
         }
 
         deviceContext.submitTransaction();