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