Bump upstreams
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / statistics / StatisticsManagerImpl.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 package org.opendaylight.openflowplugin.impl.statistics;
9
10 import com.google.common.annotations.VisibleForTesting;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import java.util.concurrent.ConcurrentHashMap;
13 import java.util.concurrent.ConcurrentMap;
14 import java.util.concurrent.Executor;
15 import java.util.concurrent.Semaphore;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.opendaylight.mdsal.binding.api.RpcProviderService;
18 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
19 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
20 import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
21 import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsManager;
22 import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
23 import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory;
24 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.provider.config.rev160510.OpenflowProviderConfig;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.ChangeStatisticsWorkMode;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.ChangeStatisticsWorkModeInput;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.ChangeStatisticsWorkModeOutput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.GetStatisticsWorkMode;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.GetStatisticsWorkModeInput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.GetStatisticsWorkModeOutput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.GetStatisticsWorkModeOutputBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.StatisticsWorkMode;
34 import org.opendaylight.yangtools.concepts.Registration;
35 import org.opendaylight.yangtools.yang.common.ErrorType;
36 import org.opendaylight.yangtools.yang.common.RpcResult;
37 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 public final class StatisticsManagerImpl implements StatisticsManager {
42     private static final Logger LOG = LoggerFactory.getLogger(StatisticsManagerImpl.class);
43
44     @VisibleForTesting
45     final ConcurrentMap<DeviceInfo, StatisticsContext> contexts = new ConcurrentHashMap<>();
46
47     private final OpenflowProviderConfig config;
48     private final ConvertorExecutor converterExecutor;
49     private final Executor executor;
50     private final Semaphore workModeGuard = new Semaphore(1, true);
51     private final Registration controlServiceRegistration;
52     private final StatisticsWorkMode workMode = StatisticsWorkMode.COLLECTALL;
53     private boolean isStatisticsFullyDisabled;
54
55     public StatisticsManagerImpl(@NonNull final OpenflowProviderConfig config,
56                                  @NonNull final RpcProviderService rpcProviderRegistry,
57                                  final ConvertorExecutor convertorExecutor,
58                                  @NonNull final Executor executor) {
59         this.config = config;
60         this.executor = executor;
61         converterExecutor = convertorExecutor;
62         controlServiceRegistration = rpcProviderRegistry.registerRpcImplementations(
63             (GetStatisticsWorkMode) this::getStatisticsWorkMode,
64             (ChangeStatisticsWorkMode) this::changeStatisticsWorkMode);
65     }
66
67     @VisibleForTesting
68     ListenableFuture<RpcResult<GetStatisticsWorkModeOutput>> getStatisticsWorkMode(
69             final GetStatisticsWorkModeInput input) {
70         return RpcResultBuilder.success(new GetStatisticsWorkModeOutputBuilder()
71                 .setMode(workMode)
72                 .build()).buildFuture();
73     }
74
75     @VisibleForTesting
76     ListenableFuture<RpcResult<ChangeStatisticsWorkModeOutput>> changeStatisticsWorkMode(
77             final ChangeStatisticsWorkModeInput input) {
78         if (workModeGuard.tryAcquire()) {
79             final StatisticsWorkMode targetWorkMode = input.getMode();
80             isStatisticsFullyDisabled = StatisticsWorkMode.FULLYDISABLED.equals(targetWorkMode);
81
82             contexts.values().forEach(context -> {
83                 switch (targetWorkMode) {
84                     case COLLECTALL:
85                         context.enableGathering();
86                         break;
87                     case FULLYDISABLED:
88                         context.disableGathering();
89                         break;
90                     default:
91                         LOG.warn("Statistics work mode not supported: {}", targetWorkMode);
92                 }
93             });
94
95             workModeGuard.release();
96             return RpcResultBuilder.<ChangeStatisticsWorkModeOutput>success().buildFuture();
97         }
98
99         return RpcResultBuilder.<ChangeStatisticsWorkModeOutput>failed()
100                 .withError(ErrorType.APPLICATION, "Statistics work mode change is already in progress")
101                 .buildFuture();
102     }
103
104     @Override
105     public StatisticsContext createContext(@NonNull final DeviceContext deviceContext,
106                                            final boolean useReconciliationFramework) {
107         final MultipartWriterProvider statisticsWriterProvider = MultipartWriterProviderFactory
108                 .createDefaultProvider(deviceContext);
109
110         final StatisticsContext statisticsContext = new StatisticsContextImpl<>(
111                 deviceContext,
112                 converterExecutor,
113                 statisticsWriterProvider,
114                 executor,
115                 config,
116                 !isStatisticsFullyDisabled && config.getIsStatisticsPollingOn(),
117                 useReconciliationFramework);
118
119         contexts.put(deviceContext.getDeviceInfo(), statisticsContext);
120         return statisticsContext;
121     }
122
123     @Override
124     public void onDeviceRemoved(final DeviceInfo deviceInfo) {
125         contexts.remove(deviceInfo);
126         LOG.debug("Statistics context removed for node {}", deviceInfo);
127     }
128
129     @Override
130     public void close() {
131         isStatisticsFullyDisabled = true;
132         controlServiceRegistration.close();
133
134         for (StatisticsContext context : contexts.values()) {
135             context.close();
136         }
137
138         contexts.clear();
139     }
140 }