dcb64734cf30ea70b2d9066f7da572cda44df96e
[openflowplugin.git] / applications / statistics-manager / src / main / java / org / opendaylight / openflowplugin / applications / statistics / manager / impl / StatAbstractNotifyCommit.java
1 /**
2  * Copyright (c) 2014 Cisco Systems, Inc. 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
9 package org.opendaylight.openflowplugin.applications.statistics.manager.impl;
10
11 import java.util.concurrent.ExecutionException;
12 import java.util.concurrent.TimeUnit;
13 import java.util.concurrent.TimeoutException;
14
15 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
16 import org.opendaylight.openflowplugin.applications.statistics.manager.StatNodeRegistration;
17 import org.opendaylight.openflowplugin.applications.statistics.manager.StatNotifyCommiter;
18 import org.opendaylight.openflowplugin.applications.statistics.manager.StatRpcMsgManager.TransactionCacheContainer;
19 import org.opendaylight.openflowplugin.applications.statistics.manager.StatisticsManager;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
23 import org.opendaylight.yangtools.concepts.ListenerRegistration;
24 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
25 import org.opendaylight.yangtools.yang.binding.NotificationListener;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 import com.google.common.base.Optional;
30 import com.google.common.base.Preconditions;
31
32 /**
33  * statistics-manager
34  * org.opendaylight.openflowplugin.applications.statistics.manager.impl
35  *
36  * StatAbstratNotifiCommiter
37  * Class is abstract implementation for all no Configuration/DataStore DataObjects
38  * and represent common functionality for all DataObject Statistics Commiters.
39  * Class defines contract between DataObject and relevant Statistics NotificationListener.
40  *
41  */
42 public abstract class StatAbstractNotifyCommit<N extends NotificationListener> implements StatNotifyCommiter<N> {
43
44     private static final Logger LOG = LoggerFactory.getLogger(StatAbstractNotifyCommit.class);
45
46     private static final long MAX_WAIT_TIME = 10;
47
48     protected final StatisticsManager manager;
49     private ListenerRegistration<NotificationListener> notifyListenerRegistration;
50     protected final StatNodeRegistration nodeRegistrationManager;
51
52
53     public StatAbstractNotifyCommit(final StatisticsManager manager,
54             final NotificationProviderService nps,
55                                     final StatNodeRegistration nodeRegistrationManager) {
56         Preconditions.checkArgument(nps != null, "NotificationProviderService can not be null!");
57         this.manager = Preconditions.checkNotNull(manager, "StatisticManager can not be null!");
58         notifyListenerRegistration = nps.registerNotificationListener(getStatNotificationListener());
59         this.nodeRegistrationManager = nodeRegistrationManager;
60     }
61
62     @Override
63     public void close() {
64         if (notifyListenerRegistration != null) {
65             try {
66                 notifyListenerRegistration.close();
67             }
68             catch (final Exception e) {
69                 LOG.error("Error by stop {} StatNotificationListener. Exception {}",
70                         this.getClass().getSimpleName(), e);
71             }
72             notifyListenerRegistration = null;
73         }
74     }
75
76     /**
77      * Method returns Statistics Notification Listener for relevant DataObject implementation,
78      * which is declared for {@link StatNotifyCommiter} interface.
79      *
80      * @return
81      */
82     protected abstract N getStatNotificationListener();
83
84     /**
85      * PreConfigurationCheck - Node identified by input InstanceIdentifier&lt;Node&gt;
86      * has to be registered in {@link org.opendaylight.openflowplugin.applications.statistics.manager.StatPermCollector}
87      *
88      * @param nodeIdent
89      */
90     protected boolean preConfigurationCheck(final InstanceIdentifier<Node> nodeIdent) {
91         Preconditions.checkNotNull(nodeIdent, "FlowCapableNode ident can not be null!");
92         return manager.isProvidedFlowNodeActive(nodeIdent);
93     }
94
95     protected void notifyToCollectNextStatistics(final InstanceIdentifier<Node> nodeIdent, final TransactionId xid) {
96         Preconditions.checkNotNull(nodeIdent, "FlowCapableNode ident can not be null!");
97         manager.collectNextStatistics(nodeIdent, xid);
98     }
99
100     /**
101      * Wrapping Future object call for {@link org.opendaylight.openflowplugin.applications.statistics.manager.StatRpcMsgManager}
102      * getTransactionCacheContainer with 10sec TimeOut.
103      * Method has returned {@link Optional} which could contains a {@link TransactionCacheContainer}
104      *
105      * @param transId
106      * @param nodeId
107      * @return
108      */
109     protected Optional<TransactionCacheContainer<?>> getTransactionCacheContainer(final TransactionId transId, final NodeId nodeId) {
110         Optional<TransactionCacheContainer<?>> txContainer;
111         try {
112             txContainer = manager.getRpcMsgManager().getTransactionCacheContainer(transId, nodeId).get(MAX_WAIT_TIME, TimeUnit.SECONDS);
113         }
114         catch (InterruptedException | ExecutionException | TimeoutException e) {
115             LOG.warn("Get TransactionCacheContainer fail!", e);
116             txContainer = Optional.absent();
117         }
118         return txContainer;
119     }
120
121     /**
122      * Method validate TransactionCacheContainer. It needs to call before every txCacheContainer processing.
123      *
124      * @param txCacheContainer
125      * @return
126      */
127     protected boolean isTransactionCacheContainerValid(final Optional<TransactionCacheContainer<?>> txCacheContainer) {
128         if ( ! txCacheContainer.isPresent()) {
129             LOG.debug("Transaction Cache Container is not presented!");
130             return false;
131         }
132         if (txCacheContainer.get().getNodeId() == null) {
133             LOG.debug("Transaction Cache Container {} don't have Node ID!", txCacheContainer.get().getId());
134             return false;
135         }
136         if (txCacheContainer.get().getNotifications() == null) {
137             LOG.debug("Transaction Cache Container {} for {} node don't have Notifications!",
138                     txCacheContainer.get().getId(), txCacheContainer.get().getNodeId());
139             return false;
140         }
141         return true;
142     }
143
144     /**
145      * Wrapping Future object call to {@link org.opendaylight.openflowplugin.applications.statistics.manager.StatRpcMsgManager}
146      * isExpectedStatistics with 10sec TimeOut.
147      * Method has checked registration for provided {@link TransactionId} and {@link NodeId}
148      *
149      * @param transId - Transaction identification
150      * @param nodeId - Node identification
151      * @return boolean
152      */
153     protected boolean isExpectedStatistics(final TransactionId transId, final NodeId nodeId) {
154         Boolean isExpectedStat = Boolean.FALSE;
155         try {
156             isExpectedStat = manager.getRpcMsgManager().isExpectedStatistics(transId, nodeId).get(MAX_WAIT_TIME, TimeUnit.SECONDS);
157         }
158         catch (InterruptedException | ExecutionException | TimeoutException e) {
159             LOG.warn("Check Transaction registraion {} fail!", transId, e);
160             return false;
161         }
162         return isExpectedStat.booleanValue();
163     }
164 }
165