2 * Copyright (c) 2017 Inocybe Technologies and others. All rights reserved.
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
8 package org.opendaylight.genius.utils.clustering;
10 import com.google.common.util.concurrent.Futures;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import java.util.Collections;
13 import java.util.List;
14 import java.util.Objects;
15 import java.util.concurrent.Callable;
16 import javax.inject.Inject;
17 import org.opendaylight.genius.utils.SystemPropertyReader;
18 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
19 import org.opendaylight.mdsal.eos.binding.api.Entity;
20 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
21 import org.opendaylight.mdsal.eos.common.api.EntityOwnershipState;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
26 * EntityOwnershipService utilities.
28 * @author Thomas Pantelis
30 public class EntityOwnershipUtils {
31 private static final Logger LOG = LoggerFactory.getLogger(EntityOwnershipUtils.class);
33 private final EntityOwnershipService entityOwnershipService;
36 public EntityOwnershipUtils(EntityOwnershipService entityOwnershipService) {
37 this.entityOwnershipService = Objects.requireNonNull(entityOwnershipService);
40 public EntityOwnershipService getEntityOwnershipService() {
41 return entityOwnershipService;
45 * Checks if the local node is the owner of an entity.
47 * @param entityType the entity type
48 * @param entityName the entity name
49 * @return true is the owner, false otherwise
51 public boolean isEntityOwner(String entityType, String entityName) {
52 return isEntityOwner(new Entity(entityType, entityName));
56 * Checks if the local node is the owner of an entity.
58 * @param entity the entity
59 * @return true is the owner, false otherwise
61 public boolean isEntityOwner(Entity entity) {
62 return isEntityOwner(entity, SystemPropertyReader.Cluster.getSleepTimeBetweenRetries(),
63 SystemPropertyReader.Cluster.getMaxRetries());
67 * Checks if the local node is the owner of an entity.
69 * @param entity the entity
70 * @param sleepBetweenRetries the busy wait interval in millis if the entity is not yet present
71 * @param tries the total number of busy wait tries
72 * @return true is the owner, false otherwise
74 public boolean isEntityOwner(Entity entity, long sleepBetweenRetries, int tries) {
76 java.util.Optional<EntityOwnershipState> entityState = entityOwnershipService.getOwnershipState(entity);
77 if (entityState.isPresent()) {
78 EntityOwnershipState entityOwnershipState = entityState.get();
79 return entityOwnershipState == EntityOwnershipState.IS_OWNER;
84 LOG.debug("EntityOwnershipState for {} is not yet available. {} tries left", entity, tries);
88 Thread.sleep(sleepBetweenRetries);
89 } catch (InterruptedException e) {
101 * Runs a job task if the local node is the owner of an entity.
103 * @param entityType the entity type
104 * @param entityName the entity name
105 * @param coordinator the JobCoordinator on which to run the job task
106 * @param jobDesc description of the job for logging
107 * @param job the job task
109 public void runOnlyInOwnerNode(String entityType, String entityName, JobCoordinator coordinator, String jobDesc,
111 final Entity entity = new Entity(entityType, entityName);
112 coordinator.enqueueJob(getEntityIdentifierString(entityType, entityName), () -> {
113 if (isEntityOwner(entity)) {
114 LOG.debug("Running job {} for {}", jobDesc, entity);
117 LOG.debug("runOnlyInOwnerNode: job {} was not run as I'm not the owner of {} ", jobDesc, entity);
120 return Collections.singletonList(Futures.immediateFuture(null));
125 * Runs a job task if the local node is the owner of an entity.
127 * @param entityType the entity type
128 * @param entityName the entity name
129 * @param coordinator the JobCoordinator on which to run the job
130 * @param jobKey the job key
131 * @param jobDesc description of the job for logging
132 * @param job the job task
134 public void runOnlyInOwnerNode(String entityType, String entityName, JobCoordinator coordinator,
135 String jobKey, String jobDesc, Callable<List<? extends ListenableFuture<?>>> job) {
136 final Entity entity = new Entity(entityType, entityName);
137 coordinator.enqueueJob(getEntityIdentifierString(entityType, entityName), () -> {
138 if (isEntityOwner(entity)) {
139 LOG.debug("Scheduling job {} for {}", jobDesc, entity);
140 coordinator.enqueueJob(jobKey, job, SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
142 LOG.debug("runOnlyInOwnerNode: job {} was not run as I'm not the owner of {} ", jobDesc, entity);
145 return Collections.singletonList(Futures.immediateFuture(null));
149 // see GENIUS-237 why we do this optimization instead of using Entity.toString()
150 private static String getEntityIdentifierString(String entityType, String entityName) {
151 return new StringBuilder(entityType.length() + entityName.length()).append(entityType).append(entityName)