Merge "Make applications/pom.xml an aggregator"
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / mastership / MastershipChangeServiceManagerImpl.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.mastership;
9
10 import static org.opendaylight.infrautils.utils.concurrent.LoggingFutures.addErrorLogging;
11
12 import com.google.common.annotations.VisibleForTesting;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import java.util.List;
15 import java.util.concurrent.CopyOnWriteArrayList;
16 import javax.inject.Singleton;
17 import org.apache.aries.blueprint.annotation.service.Service;
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
20 import org.opendaylight.openflowplugin.api.openflow.lifecycle.MasterChecker;
21 import org.opendaylight.openflowplugin.api.openflow.mastership.MastershipChangeException;
22 import org.opendaylight.openflowplugin.api.openflow.mastership.MastershipChangeRegistration;
23 import org.opendaylight.openflowplugin.api.openflow.mastership.MastershipChangeService;
24 import org.opendaylight.openflowplugin.api.openflow.mastership.MastershipChangeServiceManager;
25 import org.opendaylight.openflowplugin.api.openflow.mastership.ReconciliationFrameworkEvent;
26 import org.opendaylight.openflowplugin.api.openflow.mastership.ReconciliationFrameworkRegistration;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.rf.state.rev170713.ResultState;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 @Singleton
32 @Service(classes = MastershipChangeServiceManager.class)
33 public final class MastershipChangeServiceManagerImpl implements MastershipChangeServiceManager {
34
35     private static final Logger LOG = LoggerFactory.getLogger(MastershipChangeServiceManagerImpl.class);
36
37     private final List<MastershipChangeService> serviceGroup = new CopyOnWriteArrayList<>();
38     private ReconciliationFrameworkEvent rfService = null;
39     private MasterChecker masterChecker;
40
41     @NonNull
42     @Override
43     public MastershipChangeRegistration register(@NonNull MastershipChangeService service) {
44         final MastershipServiceDelegate registration =
45                 new MastershipServiceDelegate(service, () -> serviceGroup.remove(service));
46         serviceGroup.add(service);
47         if (masterChecker != null && masterChecker.isAnyDeviceMastered()) {
48             masterChecker.listOfMasteredDevices().forEach(service::onBecomeOwner);
49         }
50         return registration;
51     }
52
53     @Override
54     public ReconciliationFrameworkRegistration reconciliationFrameworkRegistration(
55             @NonNull ReconciliationFrameworkEvent reconciliationFrameworkEvent) throws MastershipChangeException {
56         if (rfService != null) {
57             throw new MastershipChangeException("Reconciliation framework already registered.");
58         } else {
59             rfService = reconciliationFrameworkEvent;
60             return new ReconciliationFrameworkServiceDelegate(reconciliationFrameworkEvent, () -> rfService = null);
61         }
62     }
63
64     @Override
65     public void close() {
66         serviceGroup.clear();
67     }
68
69     @Override
70     public void becomeMaster(@NonNull final DeviceInfo deviceInfo) {
71         serviceGroup.forEach(mastershipChangeService -> mastershipChangeService.onBecomeOwner(deviceInfo));
72     }
73
74     @Override
75     public void becomeSlaveOrDisconnect(@NonNull final DeviceInfo deviceInfo) {
76         if (rfService != null) {
77             ListenableFuture<Void> future = rfService.onDeviceDisconnected(deviceInfo);
78             // TODO This null future check here should ideally not be required, but some tests currently rely on it
79             if (future != null) {
80                 addErrorLogging(future, LOG, "onDeviceDisconnected() failed");
81             }
82         }
83         serviceGroup.forEach(mastershipChangeService -> mastershipChangeService.onLoseOwnership(deviceInfo));
84     }
85
86     @Override
87     public ListenableFuture<ResultState> becomeMasterBeforeSubmittedDS(@NonNull DeviceInfo deviceInfo) {
88         return rfService == null ? null : rfService.onDevicePrepared(deviceInfo);
89     }
90
91     @Override
92     public void setMasterChecker(@NonNull final MasterChecker masterChecker) {
93         this.masterChecker = masterChecker;
94     }
95
96     @Override
97     public boolean isReconciliationFrameworkRegistered() {
98         return rfService != null;
99     }
100
101     @VisibleForTesting
102     int serviceGroupListSize() {
103         return serviceGroup.size();
104     }
105 }