Bug 8163: Use async DTCL verification in MdSalUtilTest
[genius.git] / mdsalutil / mdsalutil-impl / src / test / java / org / opendaylight / genius / test / MockFlowForwarder.java
1 /*
2  * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.genius.test;
9
10 import static java.util.concurrent.TimeUnit.MILLISECONDS;
11
12 import java.util.Collection;
13 import java.util.concurrent.TimeUnit;
14 import java.util.concurrent.atomic.AtomicInteger;
15 import org.awaitility.Awaitility;
16 import org.hamcrest.Matchers;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
19 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
20 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
27 import org.opendaylight.yangtools.concepts.ListenerRegistration;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 public class MockFlowForwarder extends AbstractMockForwardingRulesManager<Flow> {
33     private static final Logger LOG = LoggerFactory.getLogger(MockFlowForwarder.class);
34
35     private final AtomicInteger flowCount = new AtomicInteger(0);
36
37     private ListenerRegistration<MockFlowForwarder> listenerRegistration;
38
39     public MockFlowForwarder(final DataBroker db) {
40         super();
41         registerListener(db);
42     }
43
44     private void registerListener(final DataBroker db) {
45         final DataTreeIdentifier<Flow> treeId = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
46                 getWildCardPath());
47         listenerRegistration = db.registerDataTreeChangeListener(treeId, MockFlowForwarder.this);
48     }
49
50     private InstanceIdentifier<Flow> getWildCardPath() {
51         return InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class)
52                 .child(Table.class).child(Flow.class);
53     }
54
55     @Override
56     public void onDataTreeChanged(Collection<DataTreeModification<Flow>> changes) {
57         for (DataTreeModification<Flow> change : changes) {
58             final InstanceIdentifier<Flow> key = change.getRootPath().getRootIdentifier();
59             final DataObjectModification<Flow> mod = change.getRootNode();
60
61             switch (mod.getModificationType()) {
62                 case DELETE:
63                     flowCount.decrementAndGet();
64                     break;
65                 case SUBTREE_MODIFIED:
66                     // CHECK IF RQD
67                     break;
68                 case WRITE:
69                     if (mod.getDataBefore() == null) {
70                         flowCount.incrementAndGet();
71                     } else {
72                         // UPDATE COUNT UNCHANGED
73                     }
74                     break;
75                 default:
76                     throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
77             }
78         }
79     }
80
81     public void awaitDataChangeCount(int expCount) {
82         Awaitility.await("MockFlowForwarder").atMost(5, TimeUnit.SECONDS).pollDelay(0, MILLISECONDS)
83             .conditionEvaluationListener(condition -> LOG.info(
84                 "awaitDataChangeCount: Elapsed time {}s, remaining time {}s; flowCount: {}",
85                     condition.getElapsedTimeInMS() / 1000, condition.getRemainingTimeInMS() / 1000,
86                     condition.getValue()))
87             .untilAtomic(flowCount, Matchers.equalTo(expCount));
88     }
89 }