imeplementation of MessageIntelligenceAgency
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / statistics / ofpspecific / MessageIntelligenceAgencyImpl.java
1 /*
2  * Copyright (c) 2015 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.impl.statistics.ofpspecific;
10
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Map.Entry;
15 import java.util.concurrent.ConcurrentHashMap;
16 import java.util.concurrent.ConcurrentMap;
17 import java.util.concurrent.atomic.AtomicLongFieldUpdater;
18 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency;
19 import org.opendaylight.yangtools.yang.binding.DataContainer;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 /**
24  * Implementation of {@link org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency}.
25  * Class counts message of {@link org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy.STATISTIC_GROUP} type
26  * and provides info as debug log.
27  */
28 public class MessageIntelligenceAgencyImpl implements MessageIntelligenceAgency<DataContainer> {
29
30     private static final Logger LOG = LoggerFactory.getLogger(MessageIntelligenceAgencyImpl.class);
31
32     private static final class MessageCounters {
33         private static final AtomicLongFieldUpdater<MessageCounters> UPDATER = AtomicLongFieldUpdater.newUpdater(MessageCounters.class, "current");
34         private volatile long current;
35         private long cumulative;
36
37         public synchronized long accumulate() {
38             final long inc = UPDATER.getAndSet(this, 0);
39             cumulative += inc;
40             return inc;
41         }
42
43         public synchronized long getCumulative() {
44             return cumulative;
45         }
46
47         public long increment() {
48             return UPDATER.incrementAndGet(this);
49         }
50     }
51
52     private final ConcurrentMap<STATISTIC_GROUP, ConcurrentMap<Class<? extends DataContainer>, MessageCounters>> inputStats = new ConcurrentHashMap<>();
53
54     @Override
55     public void spyIn(final DataContainer message) {
56         getCounters(message, STATISTIC_GROUP.FROM_SWITCH_TRANSLATE_IN_SUCCESS).increment();
57     }
58
59     @Override
60     public void spyOut(final DataContainer message) {
61         getCounters(message, STATISTIC_GROUP.FROM_SWITCH_TRANSLATE_OUT_SUCCESS).increment();
62     }
63
64     @Override
65     public void spyMessage(final DataContainer message, final STATISTIC_GROUP statGroup) {
66         getCounters(message, statGroup).increment();
67     }
68
69     /**
70      * @param message
71      * @param statGroup TODO
72      * @return
73      */
74     private MessageCounters getCounters(final DataContainer message, final STATISTIC_GROUP statGroup) {
75         Class<? extends DataContainer> msgType = message.getImplementedInterface();
76         ConcurrentMap<Class<? extends DataContainer>, MessageCounters> groupData = getOrCreateGroupData(statGroup);
77         MessageCounters counters = getOrCreateCountersPair(msgType, groupData);
78         return counters;
79     }
80
81     private static MessageCounters getOrCreateCountersPair(final Class<? extends DataContainer> msgType, final ConcurrentMap<Class<? extends DataContainer>,MessageCounters> groupData) {
82         final MessageCounters lookup = groupData.get(msgType);
83         if (lookup != null) {
84             return lookup;
85         }
86
87         final MessageCounters newCounters = new MessageCounters();
88         final MessageCounters check = groupData.putIfAbsent(msgType, newCounters);
89         return check == null ? newCounters : check;
90
91     }
92
93     private ConcurrentMap<Class<? extends DataContainer>, MessageCounters> getOrCreateGroupData(final STATISTIC_GROUP statGroup) {
94         final ConcurrentMap<Class<? extends DataContainer>, MessageCounters> lookup = inputStats.get(statGroup);
95         if (lookup != null) {
96             return lookup;
97         }
98
99         final ConcurrentMap<Class<? extends DataContainer>, MessageCounters> newmap = new ConcurrentHashMap<>();
100         final ConcurrentMap<Class<? extends DataContainer>, MessageCounters> check = inputStats.putIfAbsent(statGroup, newmap);
101
102         return check == null ? newmap : check;
103     }
104
105     @Override
106     public void run() {
107         // log current counters and cleans it
108         if (LOG.isDebugEnabled()) {
109             for (String counterItem : provideIntelligence()) {
110                 LOG.debug(counterItem);
111             }
112         }
113     }
114
115     @Override
116     public List<String> provideIntelligence() {
117         List<String> dump = new ArrayList<>();
118
119         for (STATISTIC_GROUP statGroup : STATISTIC_GROUP.values()) {
120             Map<Class<? extends DataContainer>, MessageCounters> groupData = inputStats.get(statGroup);
121             if (groupData != null) {
122                 for (Entry<Class<? extends DataContainer>, MessageCounters> statEntry : groupData.entrySet()) {
123                     long amountPerInterval = statEntry.getValue().accumulate();
124                     long cumulativeAmount = statEntry.getValue().getCumulative();
125                     dump.add(String.format("%s: MSG[%s] -> +%d | %d",
126                             statGroup,
127                             statEntry.getKey().getSimpleName(),
128                             amountPerInterval, cumulativeAmount));
129                 }
130             } else {
131                 dump.add(String.format("%s: no activity detected", statGroup));
132             }
133         }
134         return dump;
135     }
136 }