- //TODO: Not a good way to do it, need to figure out better way.
- //TODO: major issue in any alternate approach is that flow key is incrementally assigned
- //to the flows stored in data store.
- // Augment same statistics to all the matching masked flow
- Table table= (Table)trans.readConfigurationData(tableRef);
- if(table != null){
- for(Flow existingFlow : table.getFlow()){
- logger.debug("Existing flow in data store : {}",existingFlow.toString());
- if(FlowComparator.flowEquals(flowRule,existingFlow)){
- InstanceIdentifier<Flow> flowRef = getNodeIdentifierBuilder()
- .augmentation(FlowCapableNode.class)
- .child(Table.class, new TableKey(tableId))
- .child(Flow.class,existingFlow.getKey()).toInstance();
- flowBuilder.setKey(existingFlow.getKey());
- flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
- logger.debug("Found matching flow in the datastore, augmenting statistics");
- // Update entry with timestamp of latest response
- flow.setKey(existingFlow.getKey());
- FlowStatsEntry flowStatsEntry = new FlowStatsEntry(tableId,flow.build());
- trans.putOperationalData(flowRef, flowBuilder.build());
- return flowStatsEntry;
- }
+ final FlowCookie flowCookie = flowRule.getCookie() != null
+ ? flowRule.getCookie() : new FlowCookie(BigInteger.ZERO);
+ final InstanceIdentifier<FlowCookieMap> flowCookieRef = tableRef
+ .augmentation(FlowCookieMapping.class)
+ .child(FlowCookieMap.class, new FlowCookieMapKey(flowCookie));
+
+ FlowCookieMap cookieMap = (FlowCookieMap) trans.readOperationalData(flowCookieRef);
+
+ /* find flowKey in FlowCookieMap from DataStore/OPERATIONAL */
+ Optional<FlowKey> flowKey = this.getExistFlowKey(flowRule, tableRef, trans, cookieMap);
+ if ( ! flowKey.isPresent()) {
+ /* DataStore/CONFIG For every first statistic needs to be created */
+ flowKey = this.getFlowKeyFromExistFlow(flowRule, tableRef, trans);
+ if ( ! flowKey.isPresent()) {
+ /* Alien flow */
+ flowKey = this.makeAlienFlowKey(flowRule);
+ }
+ cookieMap = applyNewFlowKey(cookieMap, flowKey, flowCookie);
+ trans.putOperationalData(flowCookieRef, cookieMap);
+ }
+
+ InstanceIdentifier<Flow> flowRef = getNodeIdentifierBuilder()
+ .augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey(tableId))
+ .child(Flow.class, flowKey.get()).toInstance();
+ flowBuilder.setKey(flowKey.get());
+ flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
+
+ // Update entry with timestamp of latest response
+ flowBuilder.setKey(flowKey.get());
+ FlowStatsEntry flowStatsEntry = new FlowStatsEntry(tableId, flowBuilder.build());
+ trans.putOperationalData(flowRef, flowBuilder.build());
+ return flowStatsEntry;
+ }
+
+ @Override
+ protected InstanceIdentifier<?> listenPath() {
+ return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Table.class).child(Flow.class).build();
+ }
+
+ @Override
+ protected String statName() {
+ return "Flow";
+ }
+
+ @Override
+ public void request() {
+ // FIXME: it does not make sense to trigger this before sendAllFlowTablesStatisticsRequest()
+ // comes back -- we do not have any tables anyway.
+ final Collection<TableKey> tables = flowTableStats.getTables();
+ LOG.debug("Node {} supports {} table(s)", this.getNodeRef(), tables.size());
+ for (final TableKey key : tables) {
+ LOG.debug("Send aggregate stats request for flow table {} to node {}", key.getId(), this.getNodeRef());
+ this.requestAggregateFlows(key);
+ }
+
+ this.requestAllFlowsAllTables();
+
+ }
+ public void requestAllFlowsAllTables() {
+ if (flowStatsService != null) {
+ final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
+ input.setNode(getNodeRef());
+
+ requestHelper(flowStatsService.getAllFlowsStatisticsFromAllFlowTables(input.build()));
+ }
+ }
+
+ public void requestAggregateFlows(final TableKey key) {
+ if (flowStatsService != null) {
+ GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input =
+ new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder();
+
+ input.setNode(getNodeRef());
+ input.setTableId(new org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId(key.getId()));
+ requestHelper(flowStatsService.getAggregateFlowStatisticsFromFlowTableForAllFlows(input.build()));
+ }
+ }
+
+ public void requestFlow(final Flow flow) {
+ if (flowStatsService != null) {
+ final GetFlowStatisticsFromFlowTableInputBuilder input =
+ new GetFlowStatisticsFromFlowTableInputBuilder(flow);
+ input.setNode(getNodeRef());
+
+ requestHelper(flowStatsService.getFlowStatisticsFromFlowTable(input.build()));
+ }
+ }
+
+ @Override
+ public void onDataChanged(final DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ for (Entry<InstanceIdentifier<?>, DataObject> e : change.getCreatedConfigurationData().entrySet()) {
+ if (Flow.class.equals(e.getKey().getTargetType())) {
+ final Flow flow = (Flow) e.getValue();
+ LOG.debug("Key {} triggered request for flow {}", e.getKey(), flow);
+ requestFlow(flow);
+ } else {
+ LOG.debug("Ignoring key {}", e.getKey());