Rework ClusterSingletonServiceGroupImpl locking
[mdsal.git] / singleton-service / mdsal-singleton-dom-impl / src / main / java / org / opendaylight / mdsal / singleton / dom / impl / ClusterSingletonServiceGroup.java
1 /*
2  * Copyright (c) 2016 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.mdsal.singleton.dom.impl;
9
10 import com.google.common.util.concurrent.ListenableFuture;
11 import org.eclipse.jdt.annotation.Nullable;
12 import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
13 import org.opendaylight.mdsal.eos.common.api.GenericEntity;
14 import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipChange;
15 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
16 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
17 import org.opendaylight.yangtools.concepts.Identifiable;
18 import org.opendaylight.yangtools.concepts.Path;
19
20 /**
21  * {@link ClusterSingletonServiceGroup} maintains a group of {@link ClusterSingletonService} instances.
22  * All EntityOwnershipChange notifications have to applied to all registered services at the same time in the same
23  * manner. All registered services have only one instantiated service instance in a cluster at one time on same
24  * Cluster Node. This is realized via a double candidate approach where a service group instance maintains a candidate
25  * registration for ownership of the service entity in the cluster and also a registration that acts as a guard to
26  * ensure a service group instance has fully closed prior to relinquishing service ownership. To achieve ownership
27  * of the service group, a service group candidate must hold ownership of both these entities.
28  *
29  * @param <P> the instance identifier path type
30  * @param <E> the GenericEntity type
31  * @param <C> the GenericEntityOwnershipChange type
32  */
33 abstract class ClusterSingletonServiceGroup<P extends Path<P>, E extends GenericEntity<P>,
34                                        C extends GenericEntityOwnershipChange<P, E>> implements Identifiable<String> {
35
36     /**
37      * This method must be called once on startup to initialize this group and
38      * register the relevant group entity candidate. It means create relevant
39      * Group Entity Candidate Registration.
40      */
41     abstract void initialize() throws CandidateAlreadyRegisteredException;
42
43     /**
44      * This method registers a service instance for this service group. If the local node has
45      * ownership of the service group, the {@link ClusterSingletonService#instantiateServiceInstance()}
46      * method is called. Otherwise, the method is called once the local node gains ownership.
47      *
48      * @param service instance
49      */
50     abstract void registerService(ClusterSingletonServiceRegistration reg);
51
52     /**
53      * Method provides possibility to restart some service from group without change
54      * leadership for whole group. {@link ClusterSingletonServiceRegistration#close()}
55      * implementation has to call this service.
56      * Candidates are signed for group, so unregistration for group with one service
57      * has to trigger new election only otherwise we can see same behavior as on server
58      * without clustering.
59      *
60      * @param service instance
61      * @return Future which completes when this instance is shutdown if this was the last registration, null otherwise
62      */
63     abstract @Nullable ListenableFuture<?> unregisterService(ClusterSingletonServiceRegistration reg);
64
65     /**
66      * Method implementation has to apply ownershipChange for all registered services.
67      *
68      * @param ownershipChange change role for ClusterSingletonServiceGroup
69      */
70     abstract void ownershipChanged(C ownershipChange);
71
72     /**
73      * Closes this service group. All registered service providers are also closed. Please be careful
74      * and use this method without active EOS listener only.
75      *
76      * @return {@link ListenableFuture} in list for all Future from closing {@link ClusterSingletonService}
77      */
78     abstract ListenableFuture<?> closeClusterSingletonGroup();
79 }
80