Bug 4957 No empty transaction for every connection fix
[openflowplugin.git] / applications / statistics-manager / src / main / java / org / opendaylight / openflowplugin / applications / statistics / manager / StatisticsManager.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;
10
11 import java.util.List;
12 import java.util.UUID;
13 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
14 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
15 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
16 import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
17 import org.opendaylight.openflowplugin.applications.statistics.manager.StatPermCollector.StatCapabTypes;
18 import org.opendaylight.openflowplugin.applications.statistics.manager.impl.StatisticsManagerConfig;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsListener;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsListener;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsListener;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35
36 /**
37  * statistics-manager
38  * org.opendaylight.openflowplugin.applications.statistics.manager
39  *
40  * StatisticsManager
41  * It represent a central point for whole module. Implementation
42  * StatisticsManager registers all Operation/DS {@link StatNotifyCommiter} and
43  * Config/DS {@link StatListeningCommiter}, as well as {@link StatPermCollector}
44  * for statistic collecting and {@link StatRpcMsgManager} as Device RPCs provider.
45  * In next, StatisticsManager provides all DS contact Transaction services.
46  *
47  * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
48  *
49  * Created: Aug 27, 2014
50  */
51 public interface StatisticsManager extends AutoCloseable, TransactionChainListener {
52
53     /**
54      * StatDataStoreOperation
55      * Interface represent functionality to submit changes to DataStore.
56      * Internal {@link TransactionChainListener} joining all DS commits
57      * to Set of chained changes for prevent often DataStore touches.
58      */
59     abstract class StatDataStoreOperation {
60         public enum StatsManagerOperationType {
61             /**
62              * Operation will carry out work related to new node addition /
63              * update
64              */
65             NODE_UPDATE,
66             /**
67              * Operation will carry out work related to node removal
68              */
69             NODE_REMOVAL,
70             /**
71              * Operation will commit data to the operational data store
72              */
73             DATA_COMMIT_OPER_DS
74         }
75
76         private NodeId nodeId;
77         private StatsManagerOperationType operationType = StatsManagerOperationType.DATA_COMMIT_OPER_DS;
78         private UUID nodeUUID;
79
80         public StatDataStoreOperation(final StatsManagerOperationType operType, final NodeId id){
81             if(operType != null){
82                 operationType = operType;
83             }
84             nodeId = id;
85             nodeUUID = generatedUUIDForNode();
86         }
87
88         public final StatsManagerOperationType getType() {
89             return operationType;
90         }
91
92         public final NodeId getNodeId(){
93             return nodeId;
94         }
95
96         public UUID getNodeUUID() {
97             return nodeUUID;
98         }
99
100         /**
101          * Apply all read / write (put|merge) operation for DataStore
102          *
103          * @param tx {@link ReadWriteTransaction}
104          */
105         public abstract void applyOperation(ReadWriteTransaction tx);
106
107         protected abstract UUID generatedUUIDForNode();
108
109         public InstanceIdentifier<Node> getNodeIdentifier() {
110             final InstanceIdentifier<Node> nodeIdent = InstanceIdentifier.create(Nodes.class)
111                     .child(Node.class, new NodeKey(nodeId));
112             return nodeIdent;
113         }
114
115     }
116
117
118     class Pair<L,R> {
119
120         private final L left;
121         private final R right;
122
123         public Pair(L left, R right) {
124             this.left = left;
125             this.right = right;
126         }
127
128         public L getLeft() { return left; }
129         public R getRight() { return right; }
130
131         @Override
132         public int hashCode() { return left.hashCode() ^ right.hashCode(); }
133
134         @Override
135         public boolean equals(Object o) {
136             if (!(o instanceof Pair)) return false;
137             Pair pairo = (Pair) o;
138             return this.left.equals(pairo.getLeft()) &&
139                     this.right.equals(pairo.getRight());
140         }
141
142     }
143
144     /**
145      * Method starts whole StatisticManager functionality
146      *
147      * @param notifService
148      * @param rpcRegistry
149      */
150     void start(final NotificationProviderService notifService,
151             final RpcConsumerRegistry rpcRegistry);
152
153     /**
154      * Method provides read/write DataStore functionality cross applyOperation
155      * defined in {@link StatDataStoreOperation}
156      *
157      * @param inventoryOper - operation for DataStore
158      */
159     void enqueue(final StatDataStoreOperation inventoryOper);
160
161     /**
162      * Method wraps {@link StatisticsManager#isProvidedFlowNodeActive(InstanceIdentifier)} method
163      * to provide parallel statCollection process for Set of Nodes. So it has to
164      * identify correct Node Set by NodeIdentifier
165      *
166      * @param nodeIdent
167      */
168      boolean isProvidedFlowNodeActive(InstanceIdentifier<Node> nodeIdent);
169
170      /**
171       * Method wraps {@link StatPermCollector}.collectNextStatistics to provide
172       * parallel statCollection process for Set of Nodes. So it has to
173       * identify correct Node Set by NodeIdentifier.
174       *
175       * @param nodeIdent
176       */
177      void collectNextStatistics(InstanceIdentifier<Node> nodeIdent, TransactionId xid);
178
179      /**
180       * Method wraps {@link StatPermCollector}.connectedNodeRegistration to provide
181       * parallel statCollection process for Set of Nodes. So it has to
182       * connect node to new or not full Node statCollector Set.
183       *
184       * @param nodeIdent
185       * @param statTypes
186       * @param nrOfSwitchTables
187       */
188      void connectedNodeRegistration(InstanceIdentifier<Node> nodeIdent,
189              List<StatCapabTypes> statTypes, Short nrOfSwitchTables);
190
191      /**
192       * Method wraps {@link StatPermCollector}.disconnectedNodeUnregistration to provide
193       * parallel statCollection process for Set of Nodes. So it has to identify
194       * correct collector for disconnect node.
195       *
196       * @param nodeIdent
197       */
198      void disconnectedNodeUnregistration(InstanceIdentifier<Node> nodeIdent);
199
200      /**
201       * Method wraps {@link StatPermCollector}.registerAdditionalNodeFeature to provide
202       * possibility to register additional Node Feature {@link StatCapabTypes} for
203       * statistics collecting.
204       *
205       * @param nodeIdent
206       * @param statCapab
207       */
208      void registerAdditionalNodeFeature(InstanceIdentifier<Node> nodeIdent, StatCapabTypes statCapab);
209
210     /**
211      * Method provides access to Device RPC methods by wrapped
212      * internal method. In next {@link StatRpcMsgManager} is registered all
213      * Multipart device msg response and joining all to be able run all
214      * collected statistics in one time (easy identification Data for delete)
215      *
216      * @return {@link StatRpcMsgManager}
217      */
218     StatRpcMsgManager getRpcMsgManager();
219
220     /**
221      * Define Method : {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode}
222      * Operational/DS data change listener -&gt; impl. target -&gt; register FlowCapableNode to Statistic Collecting process
223      * @return {@link StatNodeRegistration}
224      */
225     StatNodeRegistration getNodeRegistrator();
226
227     /**
228      * Define Method : Flow Config/DS data change listener -&gt; impl. target -&gt;
229      * -&gt; make pair between Config/DS FlowId and Device Flow response Hash
230      * @return
231      */
232     StatListeningCommiter<Flow, OpendaylightFlowStatisticsListener> getFlowListenComit();
233
234     /**
235      * Define Method : Meter Config/DS data change listener and Operation/DS notify commit
236      * functionality
237      * @return
238      */
239     StatListeningCommiter<Meter, OpendaylightMeterStatisticsListener> getMeterListenCommit();
240
241     /**
242      * Define Method : Group Config/DS data change listener and Operation/DS notify commit
243      * functionality
244      * @return
245      */
246     StatListeningCommiter<Group, OpendaylightGroupStatisticsListener> getGroupListenCommit();
247
248     /**
249      * Define Method : Queue Config/DS change listener and Operation/DS notify commit functionality
250      * @return
251      */
252     StatListeningCommiter<Queue, OpendaylightQueueStatisticsListener> getQueueNotifyCommit();
253
254     /**
255      * Define Method : Table Operation/DS notify commit functionality
256      * @return
257      */
258     StatNotifyCommiter<OpendaylightFlowTableStatisticsListener> getTableNotifCommit();
259
260     /**
261      * Define Method : Port Operation/DS notify commit functionality
262      * @return
263      */
264     StatNotifyCommiter<OpendaylightPortStatisticsListener> getPortNotifyCommit();
265
266     StatisticsManagerConfig getConfiguration();
267
268     /**
269      * A unique UUID is generated with each node added by the statistics manager implementation in order to uniquely
270      * identify a session.
271      * @param nodeInstanceIdentifier
272      */
273     UUID getGeneratedUUIDForNode(InstanceIdentifier<Node> nodeInstanceIdentifier);
274
275 }
276