Use plain @Nullable
[genius.git] / mdsalutil / mdsalutil-api / src / main / java / org / opendaylight / genius / utils / clustering / EntityOwnershipUtils.java
1 /*
2  * Copyright (c) 2017 Inocybe Technologies 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.genius.utils.clustering;
9
10 import com.google.common.base.Optional;
11 import com.google.common.util.concurrent.Futures;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.Objects;
16 import java.util.concurrent.Callable;
17 import javax.inject.Inject;
18 import org.opendaylight.genius.utils.SystemPropertyReader;
19 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
20 import org.opendaylight.mdsal.eos.binding.api.Entity;
21 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
22 import org.opendaylight.mdsal.eos.common.api.EntityOwnershipState;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 /**
27  * EntityOwnershipService utilities.
28  *
29  * @author Thomas Pantelis
30  */
31 public class EntityOwnershipUtils {
32     private static final Logger LOG = LoggerFactory.getLogger(EntityOwnershipUtils.class);
33
34     private final EntityOwnershipService entityOwnershipService;
35
36     @Inject
37     public EntityOwnershipUtils(EntityOwnershipService entityOwnershipService) {
38         this.entityOwnershipService = Objects.requireNonNull(entityOwnershipService);
39     }
40
41     public EntityOwnershipService getEntityOwnershipService() {
42         return entityOwnershipService;
43     }
44
45     /**
46      * Checks if the local node is the owner of an entity.
47      *
48      * @param entityType the entity type
49      * @param entityName the entity name
50      * @return true is the owner, false otherwise
51      */
52     public boolean isEntityOwner(String entityType, String entityName) {
53         return isEntityOwner(new Entity(entityType, entityName));
54     }
55
56     /**
57      * Checks if the local node is the owner of an entity.
58      *
59      * @param entity the entity
60      * @return true is the owner, false otherwise
61      */
62     public boolean isEntityOwner(Entity entity) {
63         return isEntityOwner(entity, SystemPropertyReader.Cluster.getSleepTimeBetweenRetries(),
64                 SystemPropertyReader.Cluster.getMaxRetries());
65     }
66
67     /**
68      * Checks if the local node is the owner of an entity.
69      *
70      * @param entity the entity
71      * @param sleepBetweenRetries the busy wait interval in millis if the entity is not yet present
72      * @param tries the total number of busy wait tries
73      * @return true is the owner, false otherwise
74      */
75     public boolean isEntityOwner(Entity entity, long sleepBetweenRetries, int tries) {
76         while (true) {
77             Optional<EntityOwnershipState> entityState = entityOwnershipService.getOwnershipState(entity);
78             if (entityState.isPresent()) {
79                 EntityOwnershipState entityOwnershipState = entityState.get();
80                 return entityOwnershipState == EntityOwnershipState.IS_OWNER;
81             }
82
83             tries--;
84
85             LOG.debug("EntityOwnershipState for {} is not yet available. {} tries left", entity, tries);
86
87             if (tries > 0) {
88                 try {
89                     Thread.sleep(sleepBetweenRetries);
90                 } catch (InterruptedException e) {
91                     break;
92                 }
93             } else {
94                 break;
95             }
96         }
97
98         return false;
99     }
100
101     /**
102      * Runs a job task if the local node is the owner of an entity.
103      *
104      * @param entityType the entity type
105      * @param entityName the entity name
106      * @param coordinator the JobCoordinator on which to run the job task
107      * @param jobDesc description of the job for logging
108      * @param job the job task
109      */
110     public void runOnlyInOwnerNode(String entityType, String entityName, JobCoordinator coordinator, String jobDesc,
111             Runnable job) {
112         final Entity entity = new Entity(entityType, entityName);
113         coordinator.enqueueJob(entity.toString(), () -> {
114             if (isEntityOwner(entity)) {
115                 LOG.debug("Running job {} for {}", jobDesc, entity);
116                 job.run();
117             } else {
118                 LOG.debug("runOnlyInOwnerNode: job {} was not run as I'm not the owner of {} ", jobDesc, entity);
119             }
120
121             return Collections.singletonList(Futures.immediateFuture(null));
122         });
123     }
124
125     /**
126      * Runs a job task if the local node is the owner of an entity.
127      *
128      * @param entityType the entity type
129      * @param entityName the entity name
130      * @param coordinator the JobCoordinator on which to run the job
131      * @param jobKey the job key
132      * @param jobDesc description of the job for logging
133      * @param job the job task
134      */
135     public void runOnlyInOwnerNode(String entityType, String entityName, JobCoordinator coordinator,
136             String jobKey, String jobDesc, Callable<List<ListenableFuture<Void>>> job) {
137         final Entity entity = new Entity(entityType, entityName);
138         coordinator.enqueueJob(entity.toString(), () -> {
139             if (isEntityOwner(entity)) {
140                 LOG.debug("Scheduling job {} for {}", jobDesc, entity);
141                 coordinator.enqueueJob(jobKey, job, SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
142             } else {
143                 LOG.debug("runOnlyInOwnerNode: job {} was not run as I'm not the owner of {} ", jobDesc, entity);
144             }
145
146             return Collections.singletonList(Futures.immediateFuture(null));
147         });
148     }
149 }