package org.opendaylight.mdsal.singleton.dom.impl;
+import static com.google.common.base.Verify.verify;
+import static com.google.common.base.Verify.verifyNotNull;
+
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
+import com.google.common.base.Verify;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
+import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
import org.opendaylight.mdsal.eos.common.api.GenericEntity;
import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipChange;
import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipListener;
R extends GenericEntityOwnershipListenerRegistration<P, G>>
implements ClusterSingletonServiceProvider, GenericEntityOwnershipListener<P, C> {
- private static final Logger LOG = LoggerFactory
- .getLogger(AbstractClusterSingletonServiceProviderImpl.class.getName());
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractClusterSingletonServiceProviderImpl.class);
- private static final String SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.ServiceEntityType";
- private static final String CLOSE_SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.AsyncServiceCloseEntityType";
+ @VisibleForTesting
+ static final String SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.ServiceEntityType";
+ @VisibleForTesting
+ static final String CLOSE_SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.AsyncServiceCloseEntityType";
private final S entityOwnershipService;
- private final ConcurrentMap<String, ClusterSingletonServiceGroup<P, E, C>> serviceGroupMap =
- new ConcurrentHashMap<>();
+ private final Map<String, ClusterSingletonServiceGroup<P, E, C>> serviceGroupMap = new ConcurrentHashMap<>();
/* EOS Entity Listeners Registration */
private R serviceEntityListenerReg;
* This method must be called once on startup to initialize this provider.
*/
public final void initializeProvider() {
- LOG.debug("Initialization method for ClusterSingletonService Provider {}", this.getClass().getName());
+ LOG.debug("Initialization method for ClusterSingletonService Provider {}", this);
this.serviceEntityListenerReg = registerListener(SERVICE_ENTITY_TYPE, entityOwnershipService);
this.asyncCloseEntityListenerReg = registerListener(CLOSE_SERVICE_ENTITY_TYPE, entityOwnershipService);
}
@Override
- public final ClusterSingletonServiceRegistration registerClusterSingletonService(
+ public final synchronized ClusterSingletonServiceRegistration registerClusterSingletonService(
@CheckForNull final ClusterSingletonService service) {
- LOG.debug("Call registrationService {} method for ClusterSingletonService Provider {}", service,
- this.getClass().getName());
-
- Preconditions.checkArgument(service != null);
- Preconditions.checkArgument(!Strings.isNullOrEmpty(service.getIdentifier().getValue()),
- "ClusterSingletonService idetnifier can not be null. {}", service);
+ LOG.debug("Call registrationService {} method for ClusterSingletonService Provider {}", service, this);
final String serviceIdentifier = service.getIdentifier().getValue();
- ClusterSingletonServiceGroup<P, E, C> serviceGroup = serviceGroupMap.get(serviceIdentifier);
- if (serviceGroup == null) {
- final E mainEntity = createEntity(SERVICE_ENTITY_TYPE, serviceIdentifier);
- final E closeEntity = createEntity(CLOSE_SERVICE_ENTITY_TYPE, serviceIdentifier);
- serviceGroup = new ClusterSingletonServiceGroupImpl<>(serviceIdentifier,
- mainEntity, closeEntity, entityOwnershipService, serviceGroupMap);
- serviceGroupMap.put(service.getIdentifier().getValue(), serviceGroup);
- serviceGroup.initializationClusterSingletonGroup();
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(serviceIdentifier),
+ "ClusterSingletonService identifier may not be null nor empty");
+
+ final ClusterSingletonServiceGroup<P, E, C> serviceGroup;
+ ClusterSingletonServiceGroup<P, E, C> existing = serviceGroupMap.get(serviceIdentifier);
+ if (existing == null) {
+ serviceGroup = createGroup(serviceIdentifier, new ArrayList<>(1));
+ serviceGroupMap.put(serviceIdentifier, serviceGroup);
+
+ try {
+ initializeOrRemoveGroup(serviceGroup);
+ } catch (CandidateAlreadyRegisteredException e) {
+ throw new IllegalArgumentException("Service group already registered", e);
+ }
+ } else {
+ serviceGroup = existing;
+ }
+
+ serviceGroup.registerService(service);
+ return new AbstractClusterSingletonServiceRegistration(service) {
+ @Override
+ protected void removeRegistration() {
+ // We need to bounce the unregistration through a ordered lock in order not to deal with asynchronous
+ // shutdown of the group and user registering it again.
+ AbstractClusterSingletonServiceProviderImpl.this.removeRegistration(serviceIdentifier, service);
+ }
+ };
+ }
+
+ private ClusterSingletonServiceGroup<P, E, C> createGroup(final String serviceIdentifier,
+ final List<ClusterSingletonService> services) {
+ return new ClusterSingletonServiceGroupImpl<>(serviceIdentifier, entityOwnershipService,
+ createEntity(SERVICE_ENTITY_TYPE, serviceIdentifier),
+ createEntity(CLOSE_SERVICE_ENTITY_TYPE, serviceIdentifier), services);
+ }
+
+ private void initializeOrRemoveGroup(final ClusterSingletonServiceGroup<P, E, C> group)
+ throws CandidateAlreadyRegisteredException {
+ try {
+ group.initialize();
+ } catch (CandidateAlreadyRegisteredException e) {
+ serviceGroupMap.remove(group.getIdentifier(), group);
+ throw e;
+ }
+ }
+
+ void removeRegistration(final String serviceIdentifier, final ClusterSingletonService service) {
+
+ final PlaceholderGroup<P, E, C> placeHolder;
+ final ListenableFuture<?> future;
+ synchronized (this) {
+ final ClusterSingletonServiceGroup<P, E, C> lookup = verifyNotNull(serviceGroupMap.get(serviceIdentifier));
+ if (!lookup.unregisterService(service)) {
+ return;
+ }
+
+ // Close the group and replace it with a placeholder
+ LOG.debug("Closing service group {}", serviceIdentifier);
+ future = lookup.closeClusterSingletonGroup();
+ placeHolder = new PlaceholderGroup<>(lookup, future);
+
+ final String identifier = service.getIdentifier().getValue();
+ verify(serviceGroupMap.replace(identifier, lookup, placeHolder));
+ LOG.debug("Replaced group {} with {}", serviceIdentifier, placeHolder);
+ }
+
+ future.addListener(() -> finishShutdown(placeHolder), MoreExecutors.directExecutor());
+ }
+
+ synchronized void finishShutdown(final PlaceholderGroup<P, E, C> placeHolder) {
+ final String identifier = placeHolder.getIdentifier();
+ LOG.debug("Service group {} closed", identifier);
+
+ final List<ClusterSingletonService> services = placeHolder.getServices();
+ if (services.isEmpty()) {
+ // No services, we are all done
+ if (serviceGroupMap.remove(identifier, placeHolder)) {
+ LOG.debug("Service group {} removed", placeHolder);
+ } else {
+ LOG.debug("Service group {} superseded by {}", placeHolder, serviceGroupMap.get(identifier));
+ }
+ return;
+ }
+
+ // Placeholder is being retired, we are reusing its services as the seed for the group.
+ final ClusterSingletonServiceGroup<P, E, C> group = createGroup(identifier, services);
+ Verify.verify(serviceGroupMap.replace(identifier, placeHolder, group));
+ placeHolder.setSuccessor(group);
+ LOG.debug("Service group upgraded from {} to {}", placeHolder, group);
+
+ try {
+ initializeOrRemoveGroup(group);
+ } catch (CandidateAlreadyRegisteredException e) {
+ LOG.error("Failed to register delayed group {}, it will remain inoperational", identifier, e);
}
- return serviceGroup.registerService(service);
}
@Override
public final void close() {
- LOG.debug("Close method for ClusterSingletonService Provider {}", this.getClass().getName());
+ LOG.debug("Close method for ClusterSingletonService Provider {}", this);
if (serviceEntityListenerReg != null) {
serviceEntityListenerReg.close();
serviceEntityListenerReg = null;
}
- final List<ListenableFuture<List<Void>>> listGroupCloseListFuture = new ArrayList<>();
+ final List<ListenableFuture<?>> listGroupCloseListFuture = new ArrayList<>();
for (final ClusterSingletonServiceGroup<P, E, C> serviceGroup : serviceGroupMap.values()) {
listGroupCloseListFuture.add(serviceGroup.closeClusterSingletonGroup());
}
- final ListenableFuture<List<List<Void>>> finalCloseFuture = Futures.allAsList(listGroupCloseListFuture);
- Futures.addCallback(finalCloseFuture, new FutureCallback<List<List<Void>>>() {
+ final ListenableFuture<List<Object>> finalCloseFuture = Futures.allAsList(listGroupCloseListFuture);
+ Futures.addCallback(finalCloseFuture, new FutureCallback<List<?>>() {
@Override
- public void onSuccess(final List<List<Void>> result) {
- cleaningProvider(null);
+ public void onSuccess(final List<?> result) {
+ cleanup();
}
@Override
public void onFailure(final Throwable throwable) {
- cleaningProvider(throwable);
+ LOG.warn("Unexpected problem by closing ClusterSingletonServiceProvider {}",
+ AbstractClusterSingletonServiceProviderImpl.this, throwable);
+ cleanup();
}
});
}
/**
* Method is called async. from close method in end of Provider lifecycle.
- *
- * @param throwable Throwable (needs for log)
*/
- protected final void cleaningProvider(@Nullable final Throwable throwable) {
- LOG.debug("Final cleaning ClusterSingletonServiceProvider {}", this.getClass().getName());
- if (throwable != null) {
- LOG.warn("Unexpected problem by closing ClusterSingletonServiceProvider {}",
- this.getClass().getName(), throwable);
- }
+ final void cleanup() {
+ LOG.debug("Final cleaning ClusterSingletonServiceProvider {}", this);
if (asyncCloseEntityListenerReg != null) {
asyncCloseEntityListenerReg.close();
asyncCloseEntityListenerReg = null;
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.singleton.dom.impl;
+
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+
+abstract class AbstractClusterSingletonServiceRegistration extends AbstractObjectRegistration<ClusterSingletonService>
+ implements ClusterSingletonServiceRegistration {
+
+ AbstractClusterSingletonServiceRegistration(final ClusterSingletonService instance) {
+ super(instance);
+ }
+}
package org.opendaylight.mdsal.singleton.dom.impl;
import com.google.common.util.concurrent.ListenableFuture;
-import java.util.List;
+import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
import org.opendaylight.mdsal.eos.common.api.GenericEntity;
import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipChange;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+import org.opendaylight.yangtools.concepts.Identifiable;
import org.opendaylight.yangtools.concepts.Path;
/**
- * {@link ClusterSingletonServiceGroup} maintains a group of {@link ClusterSingletonService}
- * instancies. All EntityOwnershipChange notifications have to applied to all registered
- * services at the same time in the same manner.
- * So this interface represents a single cluster service group instance." - remove this
- * sentence. All registered services have only one instantiated service instance in a cluster
- * at one time on same Cluster Node. This is realized via a double candidate approach where
- * a service group instance maintains a candidate registration for ownership of the service
- * entity in the cluster and also a registration that acts as a guard to ensure a service
- * group instance has fully closed prior to relinquishing service ownership. To achieve
- * ownership of the service group, a service group candidate must hold ownership
- * of both these entities.
+ * {@link ClusterSingletonServiceGroup} maintains a group of {@link ClusterSingletonService} instances.
+ * All EntityOwnershipChange notifications have to applied to all registered services at the same time in the same
+ * manner. All registered services have only one instantiated service instance in a cluster at one time on same
+ * Cluster Node. This is realized via a double candidate approach where a service group instance maintains a candidate
+ * registration for ownership of the service entity in the cluster and also a registration that acts as a guard to
+ * ensure a service group instance has fully closed prior to relinquishing service ownership. To achieve ownership
+ * of the service group, a service group candidate must hold ownership of both these entities.
*
* @param <P> the instance identifier path type
* @param <E> the GenericEntity type
* @param <C> the GenericEntityOwnershipChange type
*/
-interface ClusterSingletonServiceGroup<P extends Path<P>, E extends GenericEntity<P>,
- C extends GenericEntityOwnershipChange<P, E>> {
+abstract class ClusterSingletonServiceGroup<P extends Path<P>, E extends GenericEntity<P>,
+ C extends GenericEntityOwnershipChange<P, E>> implements Identifiable<String> {
/**
* This method must be called once on startup to initialize this group and
* register the relevant group entity candidate. It means create relevant
* Group Entity Candidate Registration.
*/
- void initializationClusterSingletonGroup();
+ abstract void initialize() throws CandidateAlreadyRegisteredException;
/**
* This method registers a service instance for this service group. If the local node has
* method is called. Otherwise, the method is called once the local node gains ownership.
*
* @param service instance
- * @return closable {@link ClusterSingletonServiceRegistration}
*/
- ClusterSingletonServiceRegistration registerService(ClusterSingletonService service);
+ abstract void registerService(ClusterSingletonService service);
/**
* Method provides possibility to restart some service from group without change
* without clustering.
*
* @param service instance
+ * @return True if this was the last service registered
*/
- void unregisterService(ClusterSingletonService service);
+ abstract boolean unregisterService(ClusterSingletonService service);
/**
* Method implementation has to apply ownershipChange for all registered services.
*
* @param ownershipChange change role for ClusterSingletonServiceGroup
*/
- void ownershipChanged(C ownershipChange);
+ abstract void ownershipChanged(C ownershipChange);
/**
* Closes this service group. All registered service providers are also closed. Please be careful
*
* @return {@link ListenableFuture} in list for all Future from closing {@link ClusterSingletonService}
*/
- ListenableFuture<List<Void>> closeClusterSingletonGroup();
-
+ abstract ListenableFuture<?> closeClusterSingletonGroup();
}
package org.opendaylight.mdsal.singleton.dom.impl;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
import com.google.common.base.Verify;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
import java.util.ArrayList;
-import java.util.LinkedList;
import java.util.List;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
-import javax.annotation.Nullable;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.locks.ReentrantLock;
+import javax.annotation.CheckReturnValue;
import javax.annotation.concurrent.GuardedBy;
import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
-import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
import org.opendaylight.mdsal.eos.common.api.GenericEntity;
import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipCandidateRegistration;
import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipChange;
import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipListener;
import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
import org.opendaylight.yangtools.concepts.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Implementation of {@link ClusterSingletonServiceGroup}.
+ * Implementation of {@link ClusterSingletonServiceGroup} on top of the Entitiy Ownership Service. Since EOS is atomic
+ * in its operation and singleton services incur startup and most notably cleanup, we need to do something smart here.
+ *
+ * <p>
+ * The implementation takes advantage of the fact that EOS provides stable ownership, i.e. owners are not moved as
+ * a result on new candidates appearing. We use two entities:
+ * - service entity, to which all nodes register
+ * - cleanup entity, which only the service entity owner registers to
+ *
+ * <p>
+ * Once the cleanup entity ownership is acquired, services are started. As long as the cleanup entity is registered,
+ * it should remain the owner. In case a new service owner emerges, the old owner will start the cleanup process,
+ * eventually releasing the cleanup entity. The new owner registers for the cleanup entity -- but will not see it
+ * granted until the old owner finishes the cleanup.
*
* @param <P> the instance identifier path type
* @param <E> the GenericEntity type
* @param <G> the GenericEntityOwnershipListener type
* @param <S> the GenericEntityOwnershipService type
*/
-@VisibleForTesting
final class ClusterSingletonServiceGroupImpl<P extends Path<P>, E extends GenericEntity<P>,
- C extends GenericEntityOwnershipChange<P, E>,
- G extends GenericEntityOwnershipListener<P, C>,
- S extends GenericEntityOwnershipService<P, E, G>>
- implements ClusterSingletonServiceGroup<P, E, C> {
+ C extends GenericEntityOwnershipChange<P, E>, G extends GenericEntityOwnershipListener<P, C>,
+ S extends GenericEntityOwnershipService<P, E, G>> extends ClusterSingletonServiceGroup<P, E, C> {
+ private enum State {
+ /**
+ * This group has been freshly allocated and has not been started yet.
+ */
+ INITIAL,
+ /**
+ * Operational state. Service entity is registered, but ownership was not resolved yet.
+ */
+ REGISTERED,
+ /**
+ * Operational state. Service entity confirmed to be follower.
+ */
+ STANDBY,
+ /**
+ * Service entity acquired. Attempting to acquire cleanup entity.
+ */
+ TAKING_OWNERSHIP,
+ /**
+ * Both entities held and user services are being started.
+ */
+ STARTING_SERVICES,
+ /**
+ * Steady state. Both entities held and services have finished starting.
+ */
+ OWNER,
+ /**
+ * User services are being stopped due to either loss of an entity or a shutdown.
+ */
+ STOPPING_SERVICES,
+ /**
+ * We have stopped services and are now relinquishing the cleanup entity.
+ */
+ RELEASING_OWNERSHIP,
+ /**
+ * Terminated, this group cannot be used anymore.
+ */
+ TERMINATED
+ }
- private static final Logger LOG = LoggerFactory.getLogger(ClusterSingletonServiceGroupImpl.class.getName());
+ private static final Logger LOG = LoggerFactory.getLogger(ClusterSingletonServiceGroupImpl.class);
private final S entityOwnershipService;
- private final String clusterSingletonGroupIdentifier;
- private final Semaphore clusterLock = new Semaphore(1, true);
+ private final String identifier;
/* Entity instances */
private final E serviceEntity;
- private final E doubleCandidateEntity;
-
- // TODO :it needs to rewrite for StateMachine (INITIALIZED, TRY_TO_TAKE_LEADERSHIP, LEADER, FOLLOWER, TERMINATED)
- // INITIALIZED : we have registered baseCandidate and we are waiting for first EOS response (!do we really need it?)
- // FOLLOWER : baseCandidate is registered correctly
- // TRY_TO_TAKE_LEADERSHIP : guardCandidate is registered correctly
- // LEADER : both candidate have mastership from EOS
- // TERMINATED : service go down
- @GuardedBy("clusterLock")
- private boolean hasOwnership = false;
- @GuardedBy("clusterLock")
- private final List<ClusterSingletonServiceRegistrationDelegator> serviceGroup = new LinkedList<>();
- private final ConcurrentMap<String, ClusterSingletonServiceGroup<P, E, C>> allServiceGroups;
+ private final E cleanupEntity;
+
+ private final AtomicReference<SettableFuture<Void>> closeFuture = new AtomicReference<>();
+ private final ReentrantLock lock = new ReentrantLock(true);
+
+ @GuardedBy("lock")
+ private final List<ClusterSingletonService> serviceGroup;
+
+ @GuardedBy("lock")
+ private State state = State.INITIAL;
+
+ @GuardedBy("lock")
+ private List<C> capture;
/* EOS Candidate Registrations */
- private GenericEntityOwnershipCandidateRegistration<P, E> serviceEntityCandidateReg;
- private GenericEntityOwnershipCandidateRegistration<P, E> asyncCloseEntityCandidateReg;
+ @GuardedBy("lock")
+ private GenericEntityOwnershipCandidateRegistration<P, E> serviceEntityReg;
+ @GuardedBy("lock")
+ private GenericEntityOwnershipCandidateRegistration<P, E> cleanupEntityReg;
/**
- * Class constructor.
+ * Class constructor. Note: last argument is reused as-is.
*
- * @param clusterSingletonServiceGroupIdentifier not empty string as identifier
+ * @param identifier non-empty string as identifier
* @param mainEntity as Entity instance
* @param closeEntity as Entity instance
* @param entityOwnershipService GenericEntityOwnershipService instance
- * @param allServiceGroups concurrentMap of String and ClusterSingletonServiceGroup type
+ * @param parent parent service
+ * @param services Services list
*/
- ClusterSingletonServiceGroupImpl(final String clusterSingletonServiceGroupIdentifier, final E mainEntity,
- final E closeEntity, final S entityOwnershipService,
- final ConcurrentMap<String, ClusterSingletonServiceGroup<P, E, C>> allServiceGroups) {
- LOG.debug("New Instance of ClusterSingletonServiceGroup {}", clusterSingletonServiceGroupIdentifier);
- Preconditions.checkArgument(!Strings.isNullOrEmpty(clusterSingletonServiceGroupIdentifier));
- this.clusterSingletonGroupIdentifier = clusterSingletonServiceGroupIdentifier;
+ ClusterSingletonServiceGroupImpl(final String identifier, final S entityOwnershipService, final E mainEntity,
+ final E closeEntity, final List<ClusterSingletonService> services) {
+ Preconditions.checkArgument(!identifier.isEmpty(), "Identifier may not be empty");
+ this.identifier = identifier;
this.entityOwnershipService = Preconditions.checkNotNull(entityOwnershipService);
this.serviceEntity = Preconditions.checkNotNull(mainEntity);
- this.doubleCandidateEntity = Preconditions.checkNotNull(closeEntity);
- this.allServiceGroups = Preconditions.checkNotNull(allServiceGroups);
+ this.cleanupEntity = Preconditions.checkNotNull(closeEntity);
+ this.serviceGroup = Preconditions.checkNotNull(services);
+ LOG.debug("Instantiated new service group for {}", identifier);
+ }
+
+ @VisibleForTesting
+ ClusterSingletonServiceGroupImpl(final String identifier, final E mainEntity,
+ final E closeEntity, final S entityOwnershipService) {
+ this(identifier, entityOwnershipService, mainEntity, closeEntity, new ArrayList<>(1));
+ }
+
+ @Override
+ public String getIdentifier() {
+ return identifier;
}
- @SuppressWarnings("checkstyle:IllegalCatch")
@Override
- public ListenableFuture<List<Void>> closeClusterSingletonGroup() {
- LOG.debug("Close method for service Provider {}", clusterSingletonGroupIdentifier);
- boolean needReleaseLock = false;
- final ListenableFuture<List<Void>> destroyFuture;
+ ListenableFuture<?> closeClusterSingletonGroup() {
+ // Assert our future first
+ final SettableFuture<Void> future = SettableFuture.create();
+ final SettableFuture<Void> existing = closeFuture.getAndSet(future);
+ if (existing != null) {
+ return existing;
+ }
+
+ if (!lock.tryLock()) {
+ // The lock is held, the cleanup will be finished by the owner thread
+ LOG.debug("Singleton group {} cleanup postponed", identifier);
+ return future;
+ }
+
try {
- needReleaseLock = clusterLock.tryAcquire(1, TimeUnit.SECONDS);
- } catch (final Exception e) {
- LOG.warn("Unexpected Exception for service Provider {} in closing phase.", clusterSingletonGroupIdentifier,
- e);
+ lockedClose(future);
} finally {
- if (serviceEntityCandidateReg != null) {
- serviceEntityCandidateReg.close();
- serviceEntityCandidateReg = null;
- }
- final List<ListenableFuture<Void>> serviceCloseFutureList = new ArrayList<>();
- if (hasOwnership) {
- for (final ClusterSingletonServiceRegistrationDelegator service : serviceGroup) {
- try {
- serviceCloseFutureList.add(service.closeServiceInstance());
- } catch (final RuntimeException e) {
- LOG.warn("Unexpected exception while closing service: {}, resuming with next..",
- service.getIdentifier());
- }
- }
- hasOwnership = false;
- }
- destroyFuture = Futures.allAsList(serviceCloseFutureList);
- final Semaphore finalRelease = needReleaseLock ? clusterLock : null;
- Futures.addCallback(destroyFuture, newAsyncCloseCallback(finalRelease, true));
+ lock.unlock();
}
- return destroyFuture;
+
+ LOG.debug("Service group {} {}", identifier, future.isDone() ? "closed" : "closing");
+ return future;
+ }
+
+ private boolean isClosed() {
+ return closeFuture.get() != null;
+ }
+
+ @GuardedBy("lock")
+ private void updateState(final State newState) {
+ LOG.debug("Service group {} switching from {} to {}", identifier, state, newState);
+ state = Verify.verifyNotNull(newState);
+ }
+
+ @GuardedBy("lock")
+ private void lockedClose(final SettableFuture<Void> future) {
+ if (serviceEntityReg != null) {
+ LOG.debug("Service group {} unregistering", identifier);
+ serviceEntityReg.close();
+ serviceEntityReg = null;
+ }
+
+ switch (state) {
+ case INITIAL:
+ // Not started: not much to do
+ terminate(future);
+ break;
+ case TERMINATED:
+ // Already done: no-op
+ break;
+ case REGISTERED:
+ case STANDBY:
+ LOG.debug("Service group {} terminated", identifier);
+ terminate(future);
+ break;
+ case OWNER:
+ // No-op, we will react to the loss of registration instead.
+ break;
+ case STOPPING_SERVICES:
+ // Waiting for services. Will resume once we get notified.
+ break;
+ case RELEASING_OWNERSHIP:
+ // Waiting for cleanup entity to flip, will resume afterwards.
+ break;
+ case TAKING_OWNERSHIP:
+ // Abort taking of ownership and close
+ LOG.debug("Service group {} aborting ownership bid", identifier);
+ cleanupEntityReg.close();
+ cleanupEntityReg = null;
+ updateState(State.RELEASING_OWNERSHIP);
+ break;
+ default:
+ throw new IllegalStateException("Unhandled state " + state);
+ }
+ }
+
+ @GuardedBy("lock")
+ private void terminate(final SettableFuture<Void> future) {
+ updateState(State.TERMINATED);
+ Verify.verify(future.set(null));
}
- @SuppressWarnings("checkstyle:IllegalCatch")
@Override
- public void initializationClusterSingletonGroup() {
- LOG.debug("Initialization ClusterSingletonGroup {}", clusterSingletonGroupIdentifier);
- boolean needReleaseLock = false;
- boolean needCloseProviderInstance = false;
+ void initialize() throws CandidateAlreadyRegisteredException {
+ LOG.debug("Initialization ClusterSingletonGroup {}", identifier);
+
+ lock.lock();
try {
- clusterLock.acquire();
- needReleaseLock = true;
- Verify.verify(serviceGroup.isEmpty());
- Verify.verify(!hasOwnership);
- Verify.verify(serviceEntityCandidateReg == null);
- serviceEntityCandidateReg = entityOwnershipService.registerCandidate(serviceEntity);
- } catch (final RuntimeException | InterruptedException | CandidateAlreadyRegisteredException e) {
- LOG.debug("Unexpected error by registration service Provider {}", clusterSingletonGroupIdentifier, e);
- needCloseProviderInstance = true;
- throw new RuntimeException(e);
+ Preconditions.checkState(state == State.INITIAL, "Unexpected singleton group %s state %s", identifier,
+ state);
+
+ // Catch events if they fire during this call
+ capture = new ArrayList<>(0);
+ serviceEntityReg = entityOwnershipService.registerCandidate(serviceEntity);
+ state = State.REGISTERED;
+
+ final List<C> captured = capture;
+ capture = null;
+ captured.forEach(this::lockedOwnershipChanged);
} finally {
- closeResources(needReleaseLock, needCloseProviderInstance);
+ lock.unlock();
}
}
- @SuppressWarnings("checkstyle:IllegalCatch")
+ private void checkNotClosed() {
+ Preconditions.checkState(closeFuture.get() == null, "Service group %s has already been closed",
+ identifier);
+ }
+
@Override
- public ClusterSingletonServiceRegistration registerService(final ClusterSingletonService service) {
- LOG.debug("RegisterService method call for ClusterSingletonServiceGroup {}", clusterSingletonGroupIdentifier);
- Verify.verify(clusterSingletonGroupIdentifier.equals(service.getIdentifier().getValue()));
- boolean needReleaseLock = false;
- boolean needCloseProviderInstance = false;
- ClusterSingletonServiceRegistrationDelegator reg = null;
+ void registerService(final ClusterSingletonService service) {
+ Verify.verify(identifier.equals(service.getIdentifier().getValue()));
+ checkNotClosed();
+
+ LOG.debug("RegisterService method call for ClusterSingletonServiceGroup {}", identifier);
+
+ lock.lock();
try {
- clusterLock.acquire();
- needReleaseLock = true;
- Verify.verify(serviceEntityCandidateReg != null);
- reg = new ClusterSingletonServiceRegistrationDelegator(service, this);
- serviceGroup.add(reg);
- if (hasOwnership) {
- service.instantiateServiceInstance();
+ Preconditions.checkState(state != State.INITIAL, "Service group %s is not initialized yet", identifier);
+ serviceGroup.add(service);
+
+ switch (state) {
+ case OWNER:
+ case STARTING_SERVICES:
+ service.instantiateServiceInstance();
+ break;
+ default:
+ break;
}
- } catch (final RuntimeException | InterruptedException e) {
- LOG.debug("Unexpected error by registration service Provider {}", clusterSingletonGroupIdentifier, e);
- needCloseProviderInstance = true;
- throw new RuntimeException(e);
} finally {
- closeResources(needReleaseLock, needCloseProviderInstance);
+ lock.unlock();
}
- return reg;
}
- @SuppressWarnings("checkstyle:IllegalCatch")
+ @CheckReturnValue
@Override
- public void unregisterService(final ClusterSingletonService service) {
- LOG.debug("UnregisterService method call for ClusterSingletonServiceGroup {}", clusterSingletonGroupIdentifier);
- Verify.verify(clusterSingletonGroupIdentifier.equals(service.getIdentifier().getValue()));
- boolean needReleaseLock = false;
- boolean needCloseProviderInstance = false;
+ boolean unregisterService(final ClusterSingletonService service) {
+ Verify.verify(identifier.equals(service.getIdentifier().getValue()));
+ checkNotClosed();
+
+ lock.lock();
try {
- clusterLock.acquire();
- needReleaseLock = true;
- if (serviceGroup.size() > 1) {
- if (hasOwnership) {
+ // There is a slight problem here, as the type does not match the list type, hence we need to tread
+ // carefully.
+ if (serviceGroup.size() == 1) {
+ Verify.verify(serviceGroup.contains(service));
+ return true;
+ }
+
+ Verify.verify(serviceGroup.remove(service));
+ LOG.debug("Service {} was removed from group.", service.getIdentifier().getValue());
+
+ switch (state) {
+ case OWNER:
+ case STARTING_SERVICES:
service.closeServiceInstance();
- }
- serviceGroup.remove(service);
- LOG.debug("Service {} was removed from group.", service.getIdentifier().getValue());
- } else {
- needCloseProviderInstance = true;
+ break;
+ default:
+ break;
}
- } catch (final RuntimeException | InterruptedException e) {
- LOG.debug("Unexpected error by registration service Provider {}", clusterSingletonGroupIdentifier, e);
- needCloseProviderInstance = true;
- throw new RuntimeException(e);
+
+ return false;
} finally {
- closeResources(needReleaseLock, needCloseProviderInstance);
+ lock.unlock();
+ finishCloseIfNeeded();
}
}
- @SuppressWarnings("checkstyle:IllegalCatch")
@Override
- public void ownershipChanged(final C ownershipChange) {
- LOG.debug("Ownership change {} for ClusterSingletonServiceGroup {}", ownershipChange,
- clusterSingletonGroupIdentifier);
+ void ownershipChanged(final C ownershipChange) {
+ LOG.debug("Ownership change {} for ClusterSingletonServiceGroup {}", ownershipChange, identifier);
+
+ lock.lock();
try {
- if (ownershipChange.inJeopardy()) {
- LOG.warn("Cluster Node lost connection to another cluster nodes {}", ownershipChange);
- lostOwnership();
- return;
+ if (capture != null) {
+ capture.add(ownershipChange);
+ } else {
+ lockedOwnershipChanged(ownershipChange);
}
- if (serviceEntity.equals(ownershipChange.getEntity())) {
- if (EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED.equals(ownershipChange.getState())) {
- /*
- * SLAVE to MASTER : ownershipChange.getState().isOwner() && !ownershipChange.getState().wasOwner()
- */
- tryToTakeOwnership();
- } else if (EntityOwnershipChangeState.LOCAL_OWNERSHIP_LOST_NEW_OWNER.equals(ownershipChange.getState())
- || EntityOwnershipChangeState.LOCAL_OWNERSHIP_LOST_NO_OWNER
- .equals(ownershipChange.getState())) {
- /*
- * MASTER to SLAVE : !ownershipChange.getState().isOwner() && ownershipChange.getState().wasOwner()
- */
- lostOwnership();
- } else {
- /* Not needed notifications */
- LOG.debug("Not processed entity OwnershipChange {} in service Provider {}", ownershipChange,
- clusterSingletonGroupIdentifier);
+ } finally {
+ lock.unlock();
+ finishCloseIfNeeded();
+ }
+ }
+
+ private void lockedOwnershipChanged(final C ownershipChange) {
+ if (ownershipChange.inJeopardy()) {
+ LOG.warn("Cluster Node lost connection to another cluster nodes {}", ownershipChange);
+ lostOwnership();
+ return;
+ }
+
+ final E entity = ownershipChange.getEntity();
+ if (serviceEntity.equals(entity)) {
+ serviceOwnershipChanged(ownershipChange);
+ } else if (cleanupEntity.equals(entity)) {
+ cleanupCandidateOwnershipChanged(ownershipChange);
+ } else {
+ LOG.warn("Group {} received unrecognized change {}", identifier, ownershipChange);
+ }
+ }
+
+ private void cleanupCandidateOwnershipChanged(final C ownershipChange) {
+ switch (ownershipChange.getState()) {
+ case LOCAL_OWNERSHIP_GRANTED:
+ switch (state) {
+ case TAKING_OWNERSHIP:
+ // SLAVE to MASTER
+ startServices();
+ return;
+ default:
+ break;
}
- } else if (doubleCandidateEntity.equals(ownershipChange.getEntity())) {
- if (EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED.equals(ownershipChange.getState())) {
- /*
- * SLAVE to MASTER : ownershipChange.getState().isOwner() && !ownershipChange.getState().wasOwner()
- */
- takeOwnership();
- } else {
- /* Not needed notifications */
- LOG.debug("Not processed doubleCandidate OwnershipChange {} in service Provider {}",
- ownershipChange, clusterSingletonGroupIdentifier);
+ break;
+ case LOCAL_OWNERSHIP_LOST_NEW_OWNER:
+ case LOCAL_OWNERSHIP_LOST_NO_OWNER:
+ switch (state) {
+ case RELEASING_OWNERSHIP:
+ // Slight cheat: if we are closing down, we just need to notify the future
+ updateState(isClosed() ? State.INITIAL : State.STANDBY);
+ return;
+ case STARTING_SERVICES:
+ case OWNER:
+ case TAKING_OWNERSHIP:
+ LOG.warn("Group {} lost cleanup ownership in state {}", identifier, state);
+ return;
+ default:
+ break;
}
- } else {
- LOG.warn("Unexpected EntityOwnershipChangeEvent for entity {}", ownershipChange);
+
+ break;
+ case LOCAL_OWNERSHIP_RETAINED_WITH_NO_CHANGE:
+ case REMOTE_OWNERSHIP_CHANGED:
+ case REMOTE_OWNERSHIP_LOST_NO_OWNER:
+ default:
+ break;
+ }
+
+ LOG.debug("Group {} in state {} ignoring cleanup OwnershipChange {}", identifier, state, ownershipChange);
+ }
+
+ private void serviceOwnershipChanged(final C ownershipChange) {
+ switch (ownershipChange.getState()) {
+ case LOCAL_OWNERSHIP_GRANTED:
+ // SLAVE to MASTER : ownershipChange.getState().isOwner() && !ownershipChange.getState().wasOwner()
+ takeOwnership();
+ break;
+ case LOCAL_OWNERSHIP_LOST_NEW_OWNER:
+ case LOCAL_OWNERSHIP_LOST_NO_OWNER:
+ // MASTER to SLAVE : !ownershipChange.getState().isOwner() && ownershipChange.getState().wasOwner()
+ lostOwnership();
+ break;
+ default:
+ // Not needed notifications
+ LOG.debug("Group {} in state {} not processed entity OwnershipChange {}", identifier, state,
+ ownershipChange);
+ }
+ }
+
+ private void finishCloseIfNeeded() {
+ final SettableFuture<Void> future = closeFuture.get();
+ if (future != null) {
+ lock.lock();
+ try {
+ lockedClose(future);
+ } finally {
+ lock.unlock();
}
- } catch (final Exception e) {
- LOG.error("Unexpected Exception for service Provider {}", clusterSingletonGroupIdentifier, e);
- // TODO : think about close ... is it necessary?
}
}
* Help method to registered DoubleCandidateEntity. It is first step
* before the actual instance take Leadership.
*/
- @SuppressWarnings("checkstyle:IllegalCatch")
- private void tryToTakeOwnership() {
- LOG.debug("TryToTakeLeadership method for service Provider {}", clusterSingletonGroupIdentifier);
- boolean needReleaseLock = false;
- boolean needCloseProviderInstance = false;
+ private void takeOwnership() {
+ if (isClosed()) {
+ LOG.debug("Service group {} is closed, not taking ownership", identifier);
+ return;
+ }
+
+ LOG.debug("Group {} taking ownership", identifier);
+
+ updateState(State.TAKING_OWNERSHIP);
try {
- clusterLock.acquire();
- needReleaseLock = true;
- if (serviceEntityCandidateReg != null) {
- Verify.verify(asyncCloseEntityCandidateReg == null);
- asyncCloseEntityCandidateReg = entityOwnershipService.registerCandidate(doubleCandidateEntity);
- } else {
- LOG.debug("Service {} is closed, so don't to tryTakeLeadership", clusterSingletonGroupIdentifier);
- }
- } catch (final Exception e) {
- LOG.error("Unexpected exception state for service Provider {} in TryToTakeLeadership",
- clusterSingletonGroupIdentifier, e);
- needCloseProviderInstance = true;
- } finally {
- closeResources(needReleaseLock, needCloseProviderInstance);
+ cleanupEntityReg = entityOwnershipService.registerCandidate(cleanupEntity);
+ } catch (CandidateAlreadyRegisteredException e) {
+ LOG.error("Service group {} failed to take ownership", identifier, e);
}
}
/*
- * Help method calls setupService method for create single cluster-wide service instance.
+ * Help method calls instantiateServiceInstance method for create single cluster-wide service instance.
*/
@SuppressWarnings("checkstyle:IllegalCatch")
- private void takeOwnership() {
- LOG.debug("TakeLeadership method for service Provider {}", clusterSingletonGroupIdentifier);
- boolean needReleaseLock = false;
- boolean needCloseProviderInstance = false;
- try {
- clusterLock.acquire();
- needReleaseLock = true;
- if (serviceEntityCandidateReg != null) {
- Verify.verify(asyncCloseEntityCandidateReg != null);
- for (final ClusterSingletonServiceRegistrationDelegator service : serviceGroup) {
- service.instantiateServiceInstance();
- }
- hasOwnership = true;
- } else {
- LOG.debug("Service {} is closed, so don't take leadership", clusterSingletonGroupIdentifier);
- }
- } catch (final RuntimeException | InterruptedException e) {
- LOG.error("Unexpected exception state for service Provider {} in TakeLeadership",
- clusterSingletonGroupIdentifier, e);
- needCloseProviderInstance = true;
- } finally {
- closeResources(needReleaseLock, needCloseProviderInstance);
+ private void startServices() {
+ if (isClosed()) {
+ LOG.debug("Service group {} is closed, not starting services", identifier);
+ return;
}
+
+ LOG.debug("Service group {} starting services", identifier);
+ serviceGroup.forEach(service -> {
+ LOG.debug("Starting service {}", service);
+ try {
+ service.instantiateServiceInstance();
+ } catch (Exception e) {
+ LOG.warn("Service group {} service {} failed to start, attempting to continue", identifier, service, e);
+ }
+ });
+
+ LOG.debug("Service group {} services started", identifier);
+ updateState(State.OWNER);
}
/*
* The last async. step has to close DoubleCandidateRegistration reference what should initialize
* new election for DoubleCandidateEntity.
*/
- @SuppressWarnings("checkstyle:IllegalCatch")
private void lostOwnership() {
- LOG.debug("LostLeadership method for service Provider {}", clusterSingletonGroupIdentifier);
- boolean needReleaseLock = false;
- boolean needCloseProviderInstance = false;
- try {
- clusterLock.acquire();
- needReleaseLock = true;
- final List<ListenableFuture<Void>> serviceCloseFutureList = new ArrayList<>();
- if (hasOwnership) {
- Verify.verify(asyncCloseEntityCandidateReg != null);
- for (final ClusterSingletonServiceRegistrationDelegator service : serviceGroup) {
- try {
- serviceCloseFutureList.add(service.closeServiceInstance());
- } catch (final RuntimeException e) {
- LOG.error("Unexpected exception while closing service: {}, resuming with next..",
- service.getIdentifier());
- }
- }
- hasOwnership = false;
- }
-
- final ListenableFuture<List<Void>> destroyFuture = Futures.allAsList(serviceCloseFutureList);
- if (serviceEntityCandidateReg != null) {
- // we don't want to remove this instance from map
- Futures.addCallback(destroyFuture, newAsyncCloseCallback(clusterLock, false));
- } else {
- // we have to remove this ClusterSingletonServiceGroup instance from map
- Futures.addCallback(destroyFuture, newAsyncCloseCallback(clusterLock, true));
- }
- /*
- * We wish to stop all possible EOS activities before we don't close
- * a close candidate registration that acts as a guard. So we don't want
- * to release Semaphore (clusterLock) before we are not fully finished.
- * Semaphore lock release has to be realized as FutureCallback after a service
- * instance has fully closed prior to relinquishing service ownership.
- */
- needReleaseLock = false;
- } catch (final InterruptedException e) {
- LOG.error("Unexpected exception state for service Provider {} in LostLeadership",
- clusterSingletonGroupIdentifier, e);
- needCloseProviderInstance = true;
- } finally {
- closeResources(needReleaseLock, needCloseProviderInstance);
+ LOG.debug("Service group {} lost ownership in state {}", identifier, state);
+ switch (state) {
+ case REGISTERED:
+ updateState(State.STANDBY);
+ break;
+ case OWNER:
+ stopServices();
+ break;
+ case STARTING_SERVICES:
+ case STOPPING_SERVICES:
+ // No-op, as these will re-check state before proceeding
+ break;
+ case TAKING_OWNERSHIP:
+ cleanupEntityReg.close();
+ cleanupEntityReg = null;
+ updateState(State.STANDBY);
+ break;
+ case INITIAL:
+ case TERMINATED:
+ default:
+ LOG.info("Service group {} ignoring lost ownership in state {},", identifier, state);
+ break;
}
}
- /*
- * Help method for finalization every acquired functionality
- */
- @GuardedBy("clusterLock")
- private void closeResources(final boolean needReleaseLock, final boolean needCloseProvider) {
- if (needCloseProvider) {
- // The Game Over for this ClusterSingletonServiceGroup instance
- if (serviceEntityCandidateReg != null) {
- serviceEntityCandidateReg.close();
- serviceEntityCandidateReg = null;
- }
- // Remove instance immediately because actual state is follower or initialization
- if (asyncCloseEntityCandidateReg == null) {
- allServiceGroups.remove(clusterSingletonGroupIdentifier, this);
- }
- }
+ @SuppressWarnings("checkstyle:IllegalCatch")
+ void stopServices() {
+ updateState(State.STOPPING_SERVICES);
- if (needReleaseLock) {
- clusterLock.release();
- }
- }
+ final List<ListenableFuture<Void>> serviceCloseFutureList = new ArrayList<>(serviceGroup.size());
+ for (final ClusterSingletonService service : serviceGroup) {
+ final ListenableFuture<Void> future;
- /*
- * Help method creates FutureCallback for suspend Future
- */
- private FutureCallback<List<Void>> newAsyncCloseCallback(@Nullable final Semaphore semaphore,
- final boolean isInCloseProcess) {
- final Consumer<Throwable> closeEntityCandidateRegistration = (@Nullable final Throwable throwable) -> {
- if (throwable != null) {
- LOG.warn("Unexpected error closing service instance {}", clusterSingletonGroupIdentifier, throwable);
- } else {
- LOG.debug("Destroy service Instance {} is success", clusterSingletonGroupIdentifier);
- }
- if (asyncCloseEntityCandidateReg != null) {
- asyncCloseEntityCandidateReg.close();
- asyncCloseEntityCandidateReg = null;
- }
- if (isInCloseProcess) {
- allServiceGroups.remove(clusterSingletonGroupIdentifier, this);
+ try {
+ future = service.closeServiceInstance();
+ } catch (Exception e) {
+ LOG.warn("Service group {} service {} failed to stop, attempting to continue", identifier,
+ service, e);
+ continue;
}
- if (semaphore != null) {
- semaphore.release();
- }
- };
- return new FutureCallback<List<Void>>() {
+ serviceCloseFutureList.add(future);
+ }
+ Futures.addCallback(Futures.allAsList(serviceCloseFutureList), new FutureCallback<List<Void>>() {
@Override
- public void onSuccess(final List<Void> result) {
- closeEntityCandidateRegistration.accept(null);
+ public void onFailure(final Throwable cause) {
+ LOG.warn("Service group {} service stopping reported error", identifier, cause);
+ onServicesStopped();
}
@Override
- public void onFailure(final Throwable throwable) {
- closeEntityCandidateRegistration.accept(throwable);
+ public void onSuccess(final List<Void> nulls) {
+ onServicesStopped();
}
- };
+ });
}
+ void onServicesStopped() {
+ LOG.debug("Service group {} finished stopping services", identifier);
+ lock.lock();
+ try {
+ if (cleanupEntityReg != null) {
+ updateState(State.RELEASING_OWNERSHIP);
+ cleanupEntityReg.close();
+ cleanupEntityReg = null;
+ } else {
+ updateState(State.STANDBY);
+ }
+ } finally {
+ lock.unlock();
+ finishCloseIfNeeded();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("identifier", identifier).add("state", state).toString();
+ }
}
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.mdsal.singleton.dom.impl;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
-import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
-
-/**
- * Package protected help class represent a Delegator for {@link ClusterSingletonService}
- * instance and {@link ClusterSingletonServiceRegistration} implementation.
- * Close registration means remove {@link ClusterSingletonService} instance from internal
- * ClusterSingletonServiceGroup list reference.
- *
- *<p>
- * Close {@link ClusterSingletonServiceRegistration} is prepared for a possible restart
- * service or application in osgi container. Any another services from group can not be
- * stopped.
- */
-class ClusterSingletonServiceRegistrationDelegator
- implements ClusterSingletonServiceRegistration, ClusterSingletonService {
-
- private final ClusterSingletonService service;
- private final ClusterSingletonServiceGroup<?, ?, ?> group;
-
- ClusterSingletonServiceRegistrationDelegator(final ClusterSingletonService service,
- final ClusterSingletonServiceGroup<?, ?, ?> group) {
- this.service = Preconditions.checkNotNull(service);
- this.group = Preconditions.checkNotNull(group);
- }
-
- @Override
- public void close() throws Exception {
- group.unregisterService(this);
- }
-
- @Override
- public void instantiateServiceInstance() {
- service.instantiateServiceInstance();
- }
-
- @Override
- public ListenableFuture<Void> closeServiceInstance() {
- return service.closeServiceInstance();
- }
-
- @Override
- public ServiceGroupIdentifier getIdentifier() {
- return service.getIdentifier();
- }
-
- public String getServiceGroupIdentifier() {
- return service.getIdentifier().getValue();
- }
-}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.singleton.dom.impl;
+
+import static com.google.common.base.Verify.verify;
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
+import org.opendaylight.mdsal.eos.common.api.GenericEntity;
+import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipChange;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
+import org.opendaylight.yangtools.concepts.Path;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Intermediate place-holder to catch user requests while asynchronous shutdown of previous incarnation of
+ * a {@link ClusterSingletonServiceGroup} finishes.
+ */
+final class PlaceholderGroup<P extends Path<P>, E extends GenericEntity<P>,
+ C extends GenericEntityOwnershipChange<P, E>> extends ClusterSingletonServiceGroup<P, E, C> {
+ private static final Logger LOG = LoggerFactory.getLogger(PlaceholderGroup.class);
+
+ private final List<ClusterSingletonService> services = new ArrayList<>(0);
+ private final ClusterSingletonServiceGroup<P, E, C> previous;
+ private final ListenableFuture<?> closeFuture;
+
+ private volatile ClusterSingletonServiceGroup<P, E, C> successor;
+
+ PlaceholderGroup(final ClusterSingletonServiceGroup<P, E, C> previous, final ListenableFuture<?> closeFuture) {
+ this.previous = requireNonNull(previous);
+ this.closeFuture = requireNonNull(closeFuture);
+ }
+
+ @Override
+ public String getIdentifier() {
+ return previous.getIdentifier();
+ }
+
+ @Override
+ void initialize() throws CandidateAlreadyRegisteredException {
+ throw new UnsupportedOperationException("This should never be invoked");
+ }
+
+ @Override
+ void registerService(final ClusterSingletonService service) {
+ verifyNoSuccessor();
+ services.add(service);
+ LOG.debug("{}: added service {}", this, service);
+ }
+
+ @Override
+ boolean unregisterService(final ClusterSingletonService service) {
+ verifyNoSuccessor();
+ services.remove(service);
+ LOG.debug("{}: removed service {}", this, service);
+ return false;
+ }
+
+ @Override
+ void ownershipChanged(final C ownershipChange) {
+ // This really should not happen, but let's be defensive
+ final ClusterSingletonServiceGroup<P, E, C> local = successor;
+ (local == null ? previous : local).ownershipChanged(ownershipChange);
+ }
+
+ @Override
+ ListenableFuture<?> closeClusterSingletonGroup() {
+ final ClusterSingletonServiceGroup<P, E, C> local = successor;
+ return local == null ? closeFuture : local.closeClusterSingletonGroup();
+ }
+
+ // Note: this is a leaked structure, the caller can reuse it at will, but has to regard
+ List<ClusterSingletonService> getServices() {
+ verifyNoSuccessor();
+ LOG.trace("{}: returning services {}", this, services);
+ return services;
+ }
+
+ void setSuccessor(final ClusterSingletonServiceGroup<P, E, C> successor) {
+ verifyNoSuccessor();
+ this.successor = verifyNotNull(successor);
+ LOG.debug("{}: successor set to {}", this, successor);
+ }
+
+ private void verifyNoSuccessor() {
+ verify(successor == null, "Placeholder already superseded by %s", successor);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("id", getIdentifier()).toString();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.singleton.dom.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.opendaylight.mdsal.singleton.dom.impl.AbstractClusterSingletonServiceProviderImpl.CLOSE_SERVICE_ENTITY_TYPE;
+import static org.opendaylight.mdsal.singleton.dom.impl.AbstractClusterSingletonServiceProviderImpl.SERVICE_ENTITY_TYPE;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
+import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
+import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
+import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipCandidateRegistration;
+import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipChange;
+import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListenerRegistration;
+import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipService;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
+import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
+import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
+
+/**
+ * Abstract {@link DOMClusterSingletonServiceProviderImpl} testing substrate.
+ */
+public abstract class AbstractDOMClusterServiceProviderTest {
+ /**
+ * Base states for AbstractClusterProjectProvider.
+ */
+ enum TestClusterSingletonServiceState {
+ /**
+ * State represents a correct Instantiated process.
+ */
+ STARTED,
+ /**
+ * State represents a correct call abstract method instantiatingProject.
+ */
+ INITIALIZED,
+ /**
+ * State represents a correct call abstract method destryingProject.
+ */
+ DESTROYED,
+ }
+
+ static class TestClusterSingletonService implements ClusterSingletonService {
+ private static final ServiceGroupIdentifier SERVICE_ID = ServiceGroupIdentifier.create(SERVICE_NAME);
+
+ private TestClusterSingletonServiceState serviceState = TestClusterSingletonServiceState.INITIALIZED;
+
+ @Override
+ public final ServiceGroupIdentifier getIdentifier() {
+ return SERVICE_ID;
+ }
+
+ @Override
+ public final void instantiateServiceInstance() {
+ this.serviceState = TestClusterSingletonServiceState.STARTED;
+ }
+
+ final TestClusterSingletonServiceState getServiceState() {
+ return serviceState;
+ }
+
+ @Override
+ public ListenableFuture<Void> closeServiceInstance() {
+ this.serviceState = TestClusterSingletonServiceState.DESTROYED;
+ return Futures.immediateFuture(null);
+ }
+ }
+
+ static final String SERVICE_NAME = "testServiceName";
+ static final DOMEntity ENTITY = new DOMEntity(SERVICE_ENTITY_TYPE, SERVICE_NAME);
+ static final DOMEntity DOUBLE_ENTITY = new DOMEntity(CLOSE_SERVICE_ENTITY_TYPE, SERVICE_NAME);
+
+ @Mock
+ protected DOMEntityOwnershipService mockEos;
+ @Mock
+ protected DOMEntityOwnershipCandidateRegistration mockEntityCandReg;
+ @Mock
+ protected DOMEntityOwnershipCandidateRegistration mockDoubleEntityCandReg;
+ @Mock
+ protected DOMEntityOwnershipListenerRegistration mockEosEntityListReg;
+ @Mock
+ protected DOMEntityOwnershipListenerRegistration mockEosDoubleEntityListReg;
+
+ protected DOMClusterSingletonServiceProviderImpl clusterSingletonServiceProvider;
+ protected TestClusterSingletonService clusterSingletonService;
+ protected TestClusterSingletonService clusterSingletonService2;
+
+ @Before
+ public void setup() throws CandidateAlreadyRegisteredException {
+ MockitoAnnotations.initMocks(this);
+
+ doNothing().when(mockEosEntityListReg).close();
+ doNothing().when(mockEosDoubleEntityListReg).close();
+ doNothing().when(mockEntityCandReg).close();
+ doNothing().when(mockDoubleEntityCandReg).close();
+ doReturn(mockEosEntityListReg).when(mockEos).registerListener(eq(SERVICE_ENTITY_TYPE),
+ any(DOMClusterSingletonServiceProviderImpl.class));
+ doReturn(mockEosDoubleEntityListReg).when(mockEos).registerListener(eq(CLOSE_SERVICE_ENTITY_TYPE),
+ any(DOMClusterSingletonServiceProviderImpl.class));
+ doReturn(mockEntityCandReg).when(mockEos).registerCandidate(ENTITY);
+ doReturn(mockDoubleEntityCandReg).when(mockEos).registerCandidate(DOUBLE_ENTITY);
+
+ clusterSingletonServiceProvider = new DOMClusterSingletonServiceProviderImpl(mockEos);
+ clusterSingletonServiceProvider.initializeProvider();
+ verify(mockEos).registerListener(SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
+ verify(mockEos).registerListener(CLOSE_SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
+
+ clusterSingletonService = instantiateService();
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonService2 = instantiateService();
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ }
+
+ TestClusterSingletonService instantiateService() {
+ return new TestClusterSingletonService();
+ }
+
+ static final DOMEntityOwnershipChange getEntityToMaster() {
+ return new DOMEntityOwnershipChange(ENTITY, EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED);
+ }
+
+ static final DOMEntityOwnershipChange getEntityToSlave() {
+ return new DOMEntityOwnershipChange(ENTITY, EntityOwnershipChangeState.LOCAL_OWNERSHIP_LOST_NEW_OWNER);
+ }
+
+ static final DOMEntityOwnershipChange getInitEntityToSlave() {
+ return new DOMEntityOwnershipChange(ENTITY, EntityOwnershipChangeState.REMOTE_OWNERSHIP_CHANGED);
+ }
+
+ static final DOMEntityOwnershipChange getInitEntityToSlaveNoMaster() {
+ return new DOMEntityOwnershipChange(ENTITY, EntityOwnershipChangeState.REMOTE_OWNERSHIP_LOST_NO_OWNER);
+ }
+
+ static final DOMEntityOwnershipChange getDoubleEntityToMaster() {
+ return new DOMEntityOwnershipChange(DOUBLE_ENTITY, EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED);
+ }
+
+ static final DOMEntityOwnershipChange getInitDoubleEntityToSlave() {
+ return new DOMEntityOwnershipChange(DOUBLE_ENTITY, EntityOwnershipChangeState.REMOTE_OWNERSHIP_CHANGED);
+ }
+
+ static final DOMEntityOwnershipChange getDoubleEntityToSlave() {
+ return new DOMEntityOwnershipChange(DOUBLE_ENTITY, EntityOwnershipChangeState.LOCAL_OWNERSHIP_LOST_NEW_OWNER);
+ }
+
+ static final DOMEntityOwnershipChange getEntityToJeopardy() {
+ return new DOMEntityOwnershipChange(ENTITY, EntityOwnershipChangeState.REMOTE_OWNERSHIP_LOST_NO_OWNER, true);
+ }
+
+ /**
+ * Test checks NullPointer for null {@link DOMEntityOwnershipService} input value.
+ */
+ @Test(expected = NullPointerException.class)
+ public void initializationClusterSingletonServiceProviderNullInputTest() {
+ new DOMClusterSingletonServiceProviderImpl(null).close();
+ }
+
+ /**
+ * Test GoldPath for close {@link DOMClusterSingletonServiceProviderImpl}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void closeClusterSingletonServiceProviderTest() throws Exception {
+ verify(mockEos).registerListener(SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
+ verify(mockEos).registerListener(CLOSE_SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
+ clusterSingletonServiceProvider.close();
+ verify(mockEosEntityListReg).close();
+ verify(mockEosDoubleEntityListReg).close();
+ }
+
+ /**
+ * Test parser ServiceIdentifier from Entity.
+ */
+ @Test
+ public void makeEntityClusterSingletonServiceProviderTest() {
+ final DOMEntity testEntity = clusterSingletonServiceProvider.createEntity(SERVICE_ENTITY_TYPE, SERVICE_NAME);
+ assertEquals(ENTITY, testEntity);
+ final DOMEntity testDbEn = clusterSingletonServiceProvider.createEntity(CLOSE_SERVICE_ENTITY_TYPE,
+ SERVICE_NAME);
+ assertEquals(DOUBLE_ENTITY, testDbEn);
+ }
+
+ /**
+ * Test parser ServiceIdentifier from Entity.
+ */
+ @Test
+ public void getIdentifierClusterSingletonServiceProviderTest() {
+ final String entityIdentifier = clusterSingletonServiceProvider.getServiceIdentifierFromEntity(ENTITY);
+ assertEquals(SERVICE_NAME, entityIdentifier);
+ final String doubleEntityId = clusterSingletonServiceProvider.getServiceIdentifierFromEntity(DOUBLE_ENTITY);
+ assertEquals(SERVICE_NAME, doubleEntityId);
+ }
+
+ /**
+ * Test GoldPath for initialization {@link ClusterSingletonService}.
+ *
+ * @throws CandidateAlreadyRegisteredException if the condition does not meet
+ */
+ @Test
+ public void initializationClusterSingletonServiceTest() throws CandidateAlreadyRegisteredException {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for initialization with init ownership result SLAVE {@link ClusterSingletonService}.
+ *
+ * @throws CandidateAlreadyRegisteredException if the condition does not meet
+ */
+ @Test
+ public void slaveInitClusterSingletonServiceTest() throws CandidateAlreadyRegisteredException {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
+ verify(mockEos, never()).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for initialization with init ownership result SLAVE, but NO-MASTER {@link ClusterSingletonService}.
+ *
+ * @throws CandidateAlreadyRegisteredException if the condition does not meet
+ */
+ @Test
+ public void slaveInitNoMasterClusterSingletonServiceTest() throws CandidateAlreadyRegisteredException {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlaveNoMaster());
+ verify(mockEos, never()).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for initialization with init ownership result MASTER {@link ClusterSingletonService}.
+ *
+ * @throws CandidateAlreadyRegisteredException if the condition does not meet
+ */
+ @Test
+ public void masterInitClusterSingletonServiceTest() throws CandidateAlreadyRegisteredException {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for initialization with init ownership result MASTER {@link ClusterSingletonService}.
+ *
+ * @throws CandidateAlreadyRegisteredException if the condition does not meet
+ */
+ @Test
+ public void masterInitSlaveDoubleCandidateClusterSingletonServiceTest() throws CandidateAlreadyRegisteredException {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
+ *
+ * @throws CandidateAlreadyRegisteredException if the condition does not meet
+ */
+ @Test
+ public void takeLeadershipClusterSingletonServiceTest() throws CandidateAlreadyRegisteredException {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for initialization with init ownership result MASTER {@link ClusterSingletonService}.
+ *
+ * @throws CandidateAlreadyRegisteredException if the condition does not meet
+ */
+ @Test
+ public void masterInitClusterSingletonServiceTwoServicesTest() throws CandidateAlreadyRegisteredException {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService2);
+ assertNotNull(reg2);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
+ *
+ * @throws CandidateAlreadyRegisteredException if the condition does not meet
+ */
+ @Test
+ public void takeLeadershipClusterSingletonServiceTwoAddDuringWaitPhaseServicesTest()
+ throws CandidateAlreadyRegisteredException {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService2);
+ assertNotNull(reg2);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
+ }
+
+ /**
+ * Test checks CandidateAlreadyRegisteredException processing in initialization phase.
+ *
+ * @throws CandidateAlreadyRegisteredException if the condition does not meet
+ */
+ @Test(expected = RuntimeException.class)
+ public void initializationClusterSingletonServiceCandidateAlreadyRegistredTest()
+ throws CandidateAlreadyRegisteredException {
+ doThrow(CandidateAlreadyRegisteredException.class).when(mockEos).registerCandidate(ENTITY);
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNull(reg);
+ }
+
+ /**
+ * Test GoldPath for lostLeadership during tryToTakeLeadership with ownership result MASTER
+ * {@link ClusterSingletonService}.
+ *
+ * @throws CandidateAlreadyRegisteredException if the condition does not meet
+ */
+ @Test
+ public void lostLeadershipDuringTryToTakeLeadershipClusterSingletonServiceTest()
+ throws CandidateAlreadyRegisteredException {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test GoldPath for lostLeadership with ownership result MASTER-TO-SLAVE {@link ClusterSingletonService}.
+ *
+ * @throws CandidateAlreadyRegisteredException if the condition does not meet
+ */
+ @Test
+ public void lostLeadershipClusterSingletonServiceTest() throws CandidateAlreadyRegisteredException {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test checks inJeopardy Cluster Node state for Slave Instance.
+ *
+ * @throws CandidateAlreadyRegisteredException if the condition does not meet
+ */
+ @Test
+ public void inJeopardySlaveTest() throws CandidateAlreadyRegisteredException {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
+ verify(mockEos, never()).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToJeopardy());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, never()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ }
+
+ /**
+ * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
+ *
+ * @throws CandidateAlreadyRegisteredException if the condition does not meet
+ */
+ @Test
+ public void takeLeadershipClusterSingletonServiceTowServicesTest() throws CandidateAlreadyRegisteredException {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService2);
+ assertNotNull(reg2);
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
+ }
+
+ /**
+ * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void closeClusterSingletonServiceRegistrationNoRoleTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ reg.close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void closeClusterSingletonServiceRegistrationNoRoleTwoServicesTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService2);
+ assertNotNull(reg2);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ reg.close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, never()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ }
+
+ /**
+ * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void closeClusterSingletonServiceRegistrationSlaveTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
+ reg.close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ }
+
+ /**
+ * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void closeClusterSingletonServiceRegistrationSlaveTwoServicesTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
+ final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService2);
+ assertNotNull(reg2);
+ clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ reg.close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, never()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ }
+
+ /**
+ * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void closeClusterSingletonServiceRegistrationMasterTwoServicesTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService2);
+ assertNotNull(reg2);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ verify(mockEos).registerCandidate(ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
+ reg.close();
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, never()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
+ }
+
+ /**
+ * Test checks validation Error processing for SLAVE-TO-MASTER entity Candidate role change.
+ *
+ * @throws Exception if the condition does not meet
+ */
+ @Test
+ public void tryToTakeLeaderForClosedServiceRegistrationTest() throws Exception {
+ final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService);
+ assertNotNull(reg);
+ final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
+ .registerClusterSingletonService(clusterSingletonService2);
+ assertNotNull(reg2);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ verify(mockEos).registerCandidate(ENTITY);
+ reg.close();
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ verify(mockEntityCandReg, never()).close();
+ verify(mockDoubleEntityCandReg, never()).close();
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
+ }
+}
package org.opendaylight.mdsal.singleton.dom.impl;
-import static org.mockito.Mockito.atLeastOnce;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.opendaylight.mdsal.singleton.dom.impl.AbstractClusterSingletonServiceProviderImpl.CLOSE_SERVICE_ENTITY_TYPE;
+import static org.opendaylight.mdsal.singleton.dom.impl.AbstractClusterSingletonServiceProviderImpl.SERVICE_ENTITY_TYPE;
import com.google.common.util.concurrent.Futures;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import org.junit.Assert;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.ExecutionException;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipCandidateRegistration;
import org.opendaylight.mdsal.eos.common.api.GenericEntityOwnershipChange;
* Testing {@link ClusterSingletonServiceGroupImpl}.
*/
public class ClusterSingletonServiceGroupImplTest {
-
- private static final String SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.ServiceEntityType";
- private static final String CLOSE_SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.AsyncServiceCloseEntityType";
private static final String SERVICE_IDENTIFIER = "TestServiceIdent";
private static final ServiceGroupIdentifier SERVICE_GROUP_IDENT = ServiceGroupIdentifier.create(SERVICE_IDENTIFIER);
+ private static final TestEntity MAIN_ENTITY = new TestEntity(SERVICE_ENTITY_TYPE, SERVICE_IDENTIFIER);
+ private static final TestEntity CLOSE_ENTITY = new TestEntity(CLOSE_SERVICE_ENTITY_TYPE, SERVICE_IDENTIFIER);
+
@Mock
private ClusterSingletonService mockClusterSingletonService;
@Mock
GenericEntityOwnershipListener<TestInstanceIdentifier,
GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity>>>> singletonServiceGroup;
- private final TestEntity mainEntity = new TestEntity(SERVICE_ENTITY_TYPE, SERVICE_IDENTIFIER);
- private final TestEntity closeEntity = new TestEntity(CLOSE_SERVICE_ENTITY_TYPE, SERVICE_IDENTIFIER);
- private final ConcurrentMap<String, ClusterSingletonServiceGroup<?, ?, ?>> map = new ConcurrentHashMap<>();
-
/**
* Initialization functionality for every Tests in this suite.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException unexpected exception.
*/
@Before
- public void setup() throws Exception {
+ public void setup() throws CandidateAlreadyRegisteredException {
MockitoAnnotations.initMocks(this);
- doReturn(mockEntityCandReg).when(mockEosService).registerCandidate(mainEntity);
- doReturn(mockCloseEntityCandReg).when(mockEosService).registerCandidate(closeEntity);
+ doReturn(mockEntityCandReg).when(mockEosService).registerCandidate(MAIN_ENTITY);
+ doReturn(mockCloseEntityCandReg).when(mockEosService).registerCandidate(CLOSE_ENTITY);
doNothing().when(mockEntityCandReg).close();
doNothing().when(mockCloseEntityCandReg).close();
doNothing().when(mockClusterSingletonService).instantiateServiceInstance();
doReturn(SERVICE_GROUP_IDENT).when(mockClusterSingletonService).getIdentifier();
doReturn(SERVICE_GROUP_IDENT).when(mockClusterSingletonServiceSecond).getIdentifier();
- singletonServiceGroup = new ClusterSingletonServiceGroupImpl(
- SERVICE_IDENTIFIER, mainEntity, closeEntity, mockEosService, map);
+ singletonServiceGroup = new ClusterSingletonServiceGroupImpl<>(SERVICE_IDENTIFIER, MAIN_ENTITY, CLOSE_ENTITY,
+ mockEosService);
}
/**
* Test NULL ServiceIdent input for new ServiceGroup instance.
- *
- * @throws Exception - unexpected exception
*/
- @Test(expected = IllegalArgumentException.class)
- public void instantiationClusterSingletonServiceGroupNullIdentTest() throws Exception {
- singletonServiceGroup = new ClusterSingletonServiceGroupImpl(
- null, mainEntity, closeEntity, mockEosService, map);
+ @Test(expected = NullPointerException.class)
+ public void instantiationClusterSingletonServiceGroupNullIdentTest() {
+ new ClusterSingletonServiceGroupImpl<>(null, MAIN_ENTITY, CLOSE_ENTITY, mockEosService);
}
/**
* Test empty ServiceIdent input for new ServiceGroup instance.
- *
- * @throws Exception - unexpected exception
*/
@Test(expected = IllegalArgumentException.class)
- public void instantiationClusterSingletonServiceGroupEmptyIdentTest() throws Exception {
- singletonServiceGroup = new ClusterSingletonServiceGroupImpl("", mainEntity, closeEntity, mockEosService, map);
- }
-
- /**
- * Test NULL MainEntity input for new ServiceGroup instance.
- *
- * @throws Exception - unexpected exception
- */
- @Test(expected = NullPointerException.class)
- public void instantiationClusterSingletonServiceGroupNullMainEntityTest() throws Exception {
- singletonServiceGroup = new ClusterSingletonServiceGroupImpl(
- SERVICE_IDENTIFIER, null, closeEntity, mockEosService, map);
+ public void instantiationClusterSingletonServiceGroupEmptyIdentTest() {
+ new ClusterSingletonServiceGroupImpl<>("", MAIN_ENTITY, CLOSE_ENTITY, mockEosService);
}
/**
* Test NULL MainEntity input for new ServiceGroup instance.
- *
- * @throws Exception - unexpected exception
*/
@Test(expected = NullPointerException.class)
- public void instantiationClusterSingletonServiceGroupNullCloseEntityTest() throws Exception {
- singletonServiceGroup = new ClusterSingletonServiceGroupImpl(
- SERVICE_IDENTIFIER, mainEntity, null, mockEosService, map);
+ public void instantiationClusterSingletonServiceGroupNullMainEntityTest() {
+ new ClusterSingletonServiceGroupImpl<>(SERVICE_IDENTIFIER, null, CLOSE_ENTITY, mockEosService);
}
/**
- * Test NULL MainEntity input for new ServiceGroup instance.
- *
- * @throws Exception - unexpected exception
+ * Test NULL CloseEntity input for new ServiceGroup instance.
*/
@Test(expected = NullPointerException.class)
- public void instantiationClusterSingletonServiceGroupNullEOS_Test() throws Exception {
- singletonServiceGroup = new ClusterSingletonServiceGroupImpl(
- SERVICE_IDENTIFIER, mainEntity, closeEntity, null, map);
+ public void instantiationClusterSingletonServiceGroupNullCloseEntityTest() {
+ new ClusterSingletonServiceGroupImpl<>(SERVICE_IDENTIFIER, MAIN_ENTITY, null, mockEosService);
}
/**
- * Test NULL MainEntity input for new ServiceGroup instance.
- *
- * @throws Exception - unexpected exception
+ * Test NULL EntityOwnershipService input for new ServiceGroup instance.
*/
@Test(expected = NullPointerException.class)
- public void instantiationClusterSingletonServiceGroupNullMapRefTest() throws Exception {
- singletonServiceGroup = new ClusterSingletonServiceGroupImpl(
- SERVICE_IDENTIFIER, mainEntity, closeEntity, mockEosService, null);
+ public void instantiationClusterSingletonServiceGroupNullEOS_Test() {
+ new ClusterSingletonServiceGroupImpl<>(SERVICE_IDENTIFIER, MAIN_ENTITY, CLOSE_ENTITY, null);
}
/**
* Test GoldPath for initialization ServiceGroup.
- *
- * @throws Exception - unexpected exception
*/
@Test
- public void initializationClusterSingletonServiceGroupTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- verify(mockEosService).registerCandidate(mainEntity);
+ public void initializationClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
}
/**
* Test GoldPath for NO-TO-SLAVE entity Candidate role change.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void initializationSlaveTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
+ public void initializationSlaveTest() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
singletonServiceGroup.ownershipChanged(getEntityToSlave());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
- verify(mockEosService, never()).registerCandidate(closeEntity);
+ verify(mockEosService, never()).registerCandidate(CLOSE_ENTITY);
}
/**
* Test GoldPath for NO-TO-SLAVE but without MASTER entity Candidate role change.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void initializationNoMasterTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
+ public void initializationNoMasterTest() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
singletonServiceGroup.ownershipChanged(getEntityToSlaveNoMaster());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
- verify(mockEosService, never()).registerCandidate(closeEntity);
+ verify(mockEosService, never()).registerCandidate(CLOSE_ENTITY);
}
/**
* Test GoldPath for InJeopardy entity Candidate role change.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void initializationInJeopardyTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- map.putIfAbsent(SERVICE_IDENTIFIER, singletonServiceGroup);
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
+ public void initializationInJeopardyTest() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
singletonServiceGroup.ownershipChanged(getEntityToJeopardy());
- final ClusterSingletonServiceGroup<?, ?, ?> serviceGroup = map.get(SERVICE_IDENTIFIER);
- Assert.assertNotNull(serviceGroup);
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
- verify(mockEosService, never()).registerCandidate(closeEntity);
+ verify(mockEosService, never()).registerCandidate(CLOSE_ENTITY);
}
/**
* Test GoldPath for registration SingletonService.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void serviceRegistrationClusterSingletonServiceGroupTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
+ public void serviceRegistrationClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
}
/**
* Test GoldPath for registration SingletonService.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void serviceRegistrationClusterSingletonServiceGroupTwoServiceTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
- final ClusterSingletonServiceRegistration reg2 = singletonServiceGroup
- .registerService(mockClusterSingletonServiceSecond);
- Assert.assertNotNull(reg2);
+ public void serviceRegistrationClusterSingletonServiceGroupTwoServiceTest()
+ throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
+ singletonServiceGroup.registerService(mockClusterSingletonServiceSecond);
}
/**
* Test GoldPath for unregistration SingletonService don't call closeServiceInstance
* without mastership and don't remove ServiceGroup from map.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void serviceUnregistrationClusterSingletonServiceGroupTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- map.putIfAbsent(SERVICE_IDENTIFIER, singletonServiceGroup);
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
- reg.close();
+ public void serviceUnregistrationClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
+ assertTrue(singletonServiceGroup.unregisterService(mockClusterSingletonService));
verify(mockClusterSingletonService, never()).closeServiceInstance();
- final ClusterSingletonServiceGroup<?, ?, ?> serviceGroup = map.get(SERVICE_IDENTIFIER);
- Assert.assertNull(serviceGroup);
}
/**
* Test GoldPath for unregistration SingletonService don't call closeServiceInstance
* without mastership and don't remove ServiceGroup from map.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void serviceUnregistrationClusterSingletonServiceGroupTwoServicesTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- map.putIfAbsent(SERVICE_IDENTIFIER, singletonServiceGroup);
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
- final ClusterSingletonServiceRegistration reg2 = singletonServiceGroup
- .registerService(mockClusterSingletonServiceSecond);
- Assert.assertNotNull(reg2);
- reg.close();
+ public void serviceUnregistrationClusterSingletonServiceGroupTwoServicesTest()
+ throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
+ singletonServiceGroup.registerService(mockClusterSingletonServiceSecond);
+ assertFalse(singletonServiceGroup.unregisterService(mockClusterSingletonService));
verify(mockClusterSingletonService, never()).closeServiceInstance();
- final ClusterSingletonServiceGroup<?, ?, ?> serviceGroup = map.get(SERVICE_IDENTIFIER);
- Assert.assertNotNull(serviceGroup);
}
/**
* Test GoldPath get Slave role for registered main entity.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void getSlaveClusterSingletonServiceGroupTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
+ public void getSlaveClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
singletonServiceGroup.ownershipChanged(getEntityToSlave());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
}
/**
* Test GoldPath get Master role for registered main entity.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void tryToTakeLeaderClusterSingletonServiceGroupTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
+ public void tryToTakeLeaderClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
singletonServiceGroup.ownershipChanged(getEntityToMaster());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
- verify(mockEosService).registerCandidate(closeEntity);
+ verify(mockEosService).registerCandidate(CLOSE_ENTITY);
}
/**
* Test GoldPath get Master role for registered close entity.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void takeMasterClusterSingletonServiceGroupTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
+ public void takeMasterClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
singletonServiceGroup.ownershipChanged(getEntityToMaster());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
- verify(mockEosService).registerCandidate(closeEntity);
+ verify(mockEosService).registerCandidate(CLOSE_ENTITY);
singletonServiceGroup.ownershipChanged(getDoubleEntityToMaster());
verify(mockClusterSingletonService).instantiateServiceInstance();
}
* Test GoldPath get Master role for registered entity but initial Slave
* role for closeEntity.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void waitToTakeMasterClusterSingletonServiceGroupTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- map.putIfAbsent(SERVICE_IDENTIFIER, singletonServiceGroup);
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
+ public void waitToTakeMasterClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
singletonServiceGroup.ownershipChanged(getEntityToMaster());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
- verify(mockEosService).registerCandidate(closeEntity);
+ verify(mockEosService).registerCandidate(CLOSE_ENTITY);
singletonServiceGroup.ownershipChanged(getInitDoubleEntityToSlave());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
verify(mockClusterSingletonService, never()).closeServiceInstance();
- final ClusterSingletonServiceGroup<?, ?, ?> serviceGroup = map.get(SERVICE_IDENTIFIER);
- Assert.assertNotNull(serviceGroup);
}
/**
* Test inJeopardy validation during wait phase for Master role for closeEntity.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void inJeopardyInWaitPhaseClusterSingletonServiceGroupTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- map.putIfAbsent(SERVICE_IDENTIFIER, singletonServiceGroup);
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
+ public void inJeopardyInWaitPhaseClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
singletonServiceGroup.ownershipChanged(getEntityToMaster());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
- verify(mockEosService).registerCandidate(closeEntity);
+ verify(mockEosService).registerCandidate(CLOSE_ENTITY);
singletonServiceGroup.ownershipChanged(getEntityToJeopardy());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
verify(mockClusterSingletonService, never()).closeServiceInstance();
- final ClusterSingletonServiceGroup<?, ?, ?> serviceGroup = map.get(SERVICE_IDENTIFIER);
- Assert.assertNotNull(serviceGroup);
}
/**
* Test inJeopardy validation during wait phase for Master role for closeEntity.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void inJeopardyInWaitPhaseClusterSingletonServiceGroupTwoServiceTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- map.putIfAbsent(SERVICE_IDENTIFIER, singletonServiceGroup);
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
- final ClusterSingletonServiceRegistration reg2 = singletonServiceGroup
- .registerService(mockClusterSingletonServiceSecond);
- Assert.assertNotNull(reg2);
+ public void inJeopardyInWaitPhaseClusterSingletonServiceGroupTwoServiceTest()
+ throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
+ singletonServiceGroup.registerService(mockClusterSingletonServiceSecond);
singletonServiceGroup.ownershipChanged(getEntityToMaster());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
- verify(mockEosService).registerCandidate(closeEntity);
+ verify(mockEosService).registerCandidate(CLOSE_ENTITY);
singletonServiceGroup.ownershipChanged(getEntityToJeopardy());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
verify(mockClusterSingletonService, never()).closeServiceInstance();
- final ClusterSingletonServiceGroup<?, ?, ?> serviceGroup = map.get(SERVICE_IDENTIFIER);
- Assert.assertNotNull(serviceGroup);
}
/**
* Test inJeopardy validation for holding leadership.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void inJeopardyLeaderClusterSingletonServiceGroupTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- map.putIfAbsent(SERVICE_IDENTIFIER, singletonServiceGroup);
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
+ public void inJeopardyLeaderClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
singletonServiceGroup.ownershipChanged(getEntityToMaster());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
- verify(mockEosService).registerCandidate(closeEntity);
+ verify(mockEosService).registerCandidate(CLOSE_ENTITY);
singletonServiceGroup.ownershipChanged(getDoubleEntityToMaster());
verify(mockClusterSingletonService).instantiateServiceInstance();
singletonServiceGroup.ownershipChanged(getEntityToJeopardy());
verify(mockClusterSingletonService).closeServiceInstance();
- final ClusterSingletonServiceGroup<?, ?, ?> serviceGroup = map.get(SERVICE_IDENTIFIER);
- Assert.assertNotNull(serviceGroup);
}
/**
* Test GoldPath for SLAVE-TO-MASTER entity Candidate role change.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void lostLeaderClusterSingletonServiceGroupTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
+ public void lostLeaderClusterSingletonServiceGroupTest() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
singletonServiceGroup.ownershipChanged(getEntityToMaster());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
- verify(mockEosService).registerCandidate(closeEntity);
+ verify(mockEosService).registerCandidate(CLOSE_ENTITY);
singletonServiceGroup.ownershipChanged(getDoubleEntityToMaster());
verify(mockClusterSingletonService).instantiateServiceInstance();
singletonServiceGroup.ownershipChanged(getEntityToSlave());
* Test checks validation Error processing for SLAVE-TO-MASTER entity Candidate role change.
* Not initialized provider has to close and remove all singletonServices from Group and
* Group itself remove too.
- *
- * @throws Exception - unexpected exception
*/
@Test(expected = RuntimeException.class)
- public void tryToTakeLeaderForNotInitializedGroupTest() throws Exception {
- map.putIfAbsent(SERVICE_IDENTIFIER, singletonServiceGroup);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNull(reg);
- final ClusterSingletonServiceGroup<?, ?, ?> serviceGroup = map.get(SERVICE_IDENTIFIER);
- Assert.assertNull(serviceGroup);
+ public void tryToTakeLeaderForNotInitializedGroupTest() {
+ singletonServiceGroup.registerService(mockClusterSingletonService);
}
/**
- * Test checks closing procesing for close {@link ClusterSingletonServiceRegistration}.
+ * Test checks closing processing for close {@link ClusterSingletonServiceRegistration}.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void checkClosingRegistrationTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- map.putIfAbsent(SERVICE_IDENTIFIER, singletonServiceGroup);
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
+ public void checkClosingRegistrationTest() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
singletonServiceGroup.ownershipChanged(getEntityToMaster());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
- verify(mockEosService).registerCandidate(closeEntity);
+ verify(mockEosService).registerCandidate(CLOSE_ENTITY);
singletonServiceGroup.ownershipChanged(getDoubleEntityToMaster());
verify(mockClusterSingletonService).instantiateServiceInstance();
- reg.close();
+ assertTrue(singletonServiceGroup.unregisterService(mockClusterSingletonService));
verify(mockClusterSingletonService, never()).closeServiceInstance();
singletonServiceGroup.ownershipChanged(getEntityToSlaveNoMaster());
- verify(mockClusterSingletonService, atLeastOnce()).closeServiceInstance();
- final ClusterSingletonServiceGroup<?, ?, ?> serviceGroup = map.get(SERVICE_IDENTIFIER);
- Assert.assertNull(serviceGroup);
+ verify(mockClusterSingletonService).closeServiceInstance();
}
/**
* Test checks validation Error processing for MASTER-TO-SLAVE closeEntity Candidate role change.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void checkClosingUnexpectedDoubleEntityForMasterOwnershipChangeRegistrationTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- map.putIfAbsent(SERVICE_IDENTIFIER, singletonServiceGroup);
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
+ public void checkClosingUnexpectedDoubleEntityForMasterOwnershipChangeRegistrationTest()
+ throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
singletonServiceGroup.ownershipChanged(getEntityToMaster());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
- verify(mockEosService).registerCandidate(closeEntity);
+ verify(mockEosService).registerCandidate(CLOSE_ENTITY);
singletonServiceGroup.ownershipChanged(getDoubleEntityToMaster());
verify(mockClusterSingletonService).instantiateServiceInstance();
singletonServiceGroup.ownershipChanged(getDoubleEntityToSlave());
verify(mockClusterSingletonService, never()).closeServiceInstance();
- final ClusterSingletonServiceGroup<?, ?, ?> serviceGroup = map.get(SERVICE_IDENTIFIER);
- Assert.assertNotNull(serviceGroup);
}
/**
* Test checks validation Error processing for MASTER-TO-SLAVE closeEntity Candidate role change
* without closeEntity registration.
*
- * @throws Exception - unexpected exception
+ * @throws CandidateAlreadyRegisteredException - unexpected exception
*/
@Test
- public void checkClosingUnexpectedDoubleEntityForSlaveOwnershipChangeRegistrationTest() throws Exception {
- singletonServiceGroup.initializationClusterSingletonGroup();
- map.putIfAbsent(SERVICE_IDENTIFIER, singletonServiceGroup);
- verify(mockEosService).registerCandidate(mainEntity);
- final ClusterSingletonServiceRegistration reg = singletonServiceGroup
- .registerService(mockClusterSingletonService);
- Assert.assertNotNull(reg);
+ public void checkClosingUnexpectedDoubleEntityForSlaveOwnershipChangeRegistrationTest()
+ throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ singletonServiceGroup.registerService(mockClusterSingletonService);
singletonServiceGroup.ownershipChanged(getEntityToSlave());
verify(mockClusterSingletonService, never()).instantiateServiceInstance();
- verify(mockEosService, never()).registerCandidate(closeEntity);
+ verify(mockEosService, never()).registerCandidate(CLOSE_ENTITY);
singletonServiceGroup.ownershipChanged(getDoubleEntityToSlave());
verify(mockClusterSingletonService, never()).closeServiceInstance();
- final ClusterSingletonServiceGroup<?, ?, ?> serviceGroup = map.get(SERVICE_IDENTIFIER);
- Assert.assertNotNull(serviceGroup);
}
- private GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getEntityToMaster() {
- return new GenericEntityOwnershipChange<>(mainEntity, EntityOwnershipChangeState.from(false, true, true));
+ @Test
+ public void testRegisterCloseShutdown() throws CandidateAlreadyRegisteredException, InterruptedException,
+ ExecutionException {
+ initializeGroupAndStartService();
+
+ assertTrue(singletonServiceGroup.unregisterService(mockClusterSingletonService));
+ verify(mockClusterSingletonService, never()).closeServiceInstance();
+ verify(mockEntityCandReg, never()).close();
+
+ final ListenableFuture<?> future = singletonServiceGroup.closeClusterSingletonGroup();
+ assertNotNull(future);
+ assertFalse(future.isDone());
+ verify(mockClusterSingletonService, never()).closeServiceInstance();
+ verify(mockEntityCandReg).close();
+
+ singletonServiceGroup.ownershipChanged(getEntityToSlave());
+ verify(mockClusterSingletonService).closeServiceInstance();
+ verify(mockCloseEntityCandReg).close();
+
+ singletonServiceGroup.ownershipChanged(getDoubleEntityToSlave());
+ assertTrue(future.isDone());
+ assertNull(future.get());
+ }
+
+ private void initialize() throws CandidateAlreadyRegisteredException {
+ singletonServiceGroup.initialize();
+ verify(mockEosService).registerCandidate(MAIN_ENTITY);
+ }
+
+ private void initializeGroupAndStartService() throws CandidateAlreadyRegisteredException {
+ initialize();
+ singletonServiceGroup.registerService(mockClusterSingletonService);
+ singletonServiceGroup.ownershipChanged(getEntityToMaster());
+ verify(mockEosService).registerCandidate(CLOSE_ENTITY);
+ singletonServiceGroup.ownershipChanged(getDoubleEntityToMaster());
+ verify(mockClusterSingletonService).instantiateServiceInstance();
}
- private GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getEntityToSlave() {
- return new GenericEntityOwnershipChange<>(mainEntity, EntityOwnershipChangeState.from(true, false, true));
+ private static GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getEntityToMaster() {
+ return new GenericEntityOwnershipChange<>(MAIN_ENTITY, EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED);
}
- private GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getEntityToSlaveNoMaster() {
- return new GenericEntityOwnershipChange<>(mainEntity, EntityOwnershipChangeState.from(true, false, false));
+ private static GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getEntityToSlave() {
+ return new GenericEntityOwnershipChange<>(MAIN_ENTITY,
+ EntityOwnershipChangeState.LOCAL_OWNERSHIP_LOST_NEW_OWNER);
}
- private GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getDoubleEntityToMaster() {
- return new GenericEntityOwnershipChange<>(closeEntity, EntityOwnershipChangeState.from(false, true, true));
+ private static GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getEntityToSlaveNoMaster() {
+ return new GenericEntityOwnershipChange<>(MAIN_ENTITY,
+ EntityOwnershipChangeState.LOCAL_OWNERSHIP_LOST_NO_OWNER);
}
- private GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getDoubleEntityToSlave() {
- return new GenericEntityOwnershipChange<>(closeEntity, EntityOwnershipChangeState.from(true, false, true));
+ private static GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getDoubleEntityToMaster() {
+ return new GenericEntityOwnershipChange<>(CLOSE_ENTITY, EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED);
}
- private GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getInitDoubleEntityToSlave() {
- return new GenericEntityOwnershipChange<>(closeEntity, EntityOwnershipChangeState.from(false, false, true));
+ private static GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getDoubleEntityToSlave() {
+ return new GenericEntityOwnershipChange<>(CLOSE_ENTITY,
+ EntityOwnershipChangeState.LOCAL_OWNERSHIP_LOST_NEW_OWNER);
}
- private GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getEntityToJeopardy() {
- return new GenericEntityOwnershipChange<>(mainEntity,
- EntityOwnershipChangeState.from(false, false, false), true);
+ private static GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getInitDoubleEntityToSlave() {
+ return new GenericEntityOwnershipChange<>(CLOSE_ENTITY, EntityOwnershipChangeState.REMOTE_OWNERSHIP_CHANGED);
}
+ private static GenericEntityOwnershipChange<TestInstanceIdentifier, TestEntity> getEntityToJeopardy() {
+ return new GenericEntityOwnershipChange<>(MAIN_ENTITY,
+ EntityOwnershipChangeState.REMOTE_OWNERSHIP_LOST_NO_OWNER, true);
+ }
}
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.mdsal.singleton.dom.impl;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.util.concurrent.Futures;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
-import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
-
-/**
- * Testing {@link ClusterSingletonServiceRegistrationDelegator}.
- */
-public class ClusterSingletonServiceRegistrationDelegatorTest {
-
- private static final String SERVICE_IDENTIFIER_NAME = "TestServiceIdent";
- private static final ServiceGroupIdentifier SERVICE_IDENTIFIER = ServiceGroupIdentifier
- .create(SERVICE_IDENTIFIER_NAME);
-
- @Mock
- private ClusterSingletonServiceGroup<?, ?, ?> mockClusterSingletonServiceGroup;
- @Mock
- private ClusterSingletonService mockClusterSingletonService;
-
- private ClusterSingletonServiceRegistrationDelegator delegator;
-
- /**
- * Initialization functionality for every Tests in this suite.
- *
- * @throws Exception - unexpected setup exception
- */
- @Before
- public void setup() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- doNothing().when(mockClusterSingletonServiceGroup)
- .unregisterService(any(ClusterSingletonServiceRegistrationDelegator.class));
- doReturn(SERVICE_IDENTIFIER).when(mockClusterSingletonService).getIdentifier();
- doNothing().when(mockClusterSingletonService).instantiateServiceInstance();
- doReturn(Futures.immediateFuture(null)).when(mockClusterSingletonService).closeServiceInstance();
- delegator = new ClusterSingletonServiceRegistrationDelegator(mockClusterSingletonService,
- mockClusterSingletonServiceGroup);
- }
-
- /**
- * Test create input with {@link ClusterSingletonService} as null.
- */
- @Test(expected = NullPointerException.class)
- public void testSetupNullService() {
- delegator = new ClusterSingletonServiceRegistrationDelegator(null, mockClusterSingletonServiceGroup);
- }
-
- /**
- * Test create input with {@link ClusterSingletonServiceGroupImpl} as null.
- */
- @Test(expected = NullPointerException.class)
- public void testSetupNullGroup() {
- delegator = new ClusterSingletonServiceRegistrationDelegator(mockClusterSingletonService, null);
- }
-
- /**
- * Test a method delegation {@link ClusterSingletonService#instantiateServiceInstance()}.
- */
- @Test
- public void testInstatiateServiceDelegMethod() {
- delegator.instantiateServiceInstance();
- verify(mockClusterSingletonService).instantiateServiceInstance();
- }
-
- /**
- * Test a method delegation {@link ClusterSingletonService#instantiateServiceInstance()}.
- */
- @Test
- public void testCloseServiceDelegMethod() {
- delegator.closeServiceInstance();
- verify(mockClusterSingletonService).closeServiceInstance();
- }
-
- /**
- * Test a method delegation {@link ClusterSingletonService#getIdentifier()}.
- */
- @Test
- public void testGetServiceIdentifierDelegMethod() {
- final String serviceIdentifier = delegator.getServiceGroupIdentifier();
- Assert.assertEquals(SERVICE_IDENTIFIER_NAME, serviceIdentifier);
- verify(mockClusterSingletonService).getIdentifier();
- }
-
- /**
- * Test a close method delegation to
- * {@link ClusterSingletonServiceGroupImpl#unregisterService(ClusterSingletonService)}.
- *
- * @throws Exception is from AutoclosableInterface
- */
- @Test
- public void testCloseMethod() throws Exception {
- delegator.close();
- verify(mockClusterSingletonServiceGroup).unregisterService(delegator);
- }
-}
package org.opendaylight.mdsal.singleton.dom.impl;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import java.util.Timer;
import java.util.TimerTask;
import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
-import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipCandidateRegistration;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipChange;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListenerRegistration;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
-import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
/*
* Testing {@link DOMClusterSingletonServiceProviderImpl} implementation
*/
-public final class DOMClusterSingletonServiceProviderAsyncImplTest {
-
- private static final String SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.ServiceEntityType";
- private static final String CLOSE_SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.AsyncServiceCloseEntityType";
- private static final String SERVICE_NAME = "testServiceName";
-
- @Mock
- private DOMEntityOwnershipService mockEos;
- @Mock
- private DOMEntityOwnershipCandidateRegistration mockEntityCandReg;
- @Mock
- private DOMEntityOwnershipCandidateRegistration mockDoubleEntityCandReg;
- @Mock
- private DOMEntityOwnershipListenerRegistration mockEosEntityListReg;
- @Mock
- private DOMEntityOwnershipListenerRegistration mockEosDoubleEntityListReg;
-
- private DOMClusterSingletonServiceProviderImpl clusterSingletonServiceProvider;
- private TestClusterSingletonAsyncServiceInstance clusterSingletonService;
- private TestClusterSingletonAsyncServiceInstance clusterSingletonService2;
+public final class DOMClusterSingletonServiceProviderAsyncImplTest extends AbstractDOMClusterServiceProviderTest {
+ /*
+ * Test implementation of {@link ClusterSingletonService}
+ */
+ static class TestClusterSingletonAsyncServiceInstance extends TestClusterSingletonService {
+ @Override
+ public ListenableFuture<Void> closeServiceInstance() {
+ super.closeServiceInstance();
- private final DOMEntity entity = new DOMEntity(SERVICE_ENTITY_TYPE, SERVICE_NAME);
- private final DOMEntity doubleEntity = new DOMEntity(CLOSE_SERVICE_ENTITY_TYPE, SERVICE_NAME);
+ final SettableFuture<Void> future = SettableFuture.create();
+ TIMER.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ future.set(null);
+ }
+ }, ASYNC_TIME_DELAY_MILLIS);
+ return future;
+ }
+ }
- protected static Timer timer;
- protected static long ASYNC_TIME_DELAY_SEC = 100L;
+ protected static final long ASYNC_TIME_DELAY_MILLIS = 100L;
+ protected static Timer TIMER;
@BeforeClass
public static void asyncInitTest() {
- timer = new Timer();
+ TIMER = new Timer();
}
@AfterClass
public static void cleanTest() {
- timer.cancel();
- }
-
- /**
- * Initialization functionality for every Tests in this suite.
- *
- * @throws Exception if the condition does not meet
- */
- @Before
- public void setup() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- doNothing().when(mockEosEntityListReg).close();
- doNothing().when(mockEosDoubleEntityListReg).close();
- doNothing().when(mockEntityCandReg).close();
- doNothing().when(mockDoubleEntityCandReg).close();
- doReturn(mockEosEntityListReg).when(mockEos).registerListener(eq(SERVICE_ENTITY_TYPE),
- any(DOMClusterSingletonServiceProviderImpl.class));
- doReturn(mockEosDoubleEntityListReg).when(mockEos).registerListener(eq(CLOSE_SERVICE_ENTITY_TYPE),
- any(DOMClusterSingletonServiceProviderImpl.class));
- doReturn(mockEntityCandReg).when(mockEos).registerCandidate(entity);
- doReturn(mockDoubleEntityCandReg).when(mockEos).registerCandidate(doubleEntity);
-
- clusterSingletonServiceProvider = new DOMClusterSingletonServiceProviderImpl(mockEos);
- clusterSingletonServiceProvider.initializeProvider();
- verify(mockEos).registerListener(SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
- verify(mockEos).registerListener(CLOSE_SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
-
- clusterSingletonService = new TestClusterSingletonAsyncServiceInstance();
- clusterSingletonService2 = new TestClusterSingletonAsyncServiceInstance();
-
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ TIMER.cancel();
}
- /**
- * Test checks NullPointer for null {@link DOMEntityOwnershipService} input value.
- *
- * @throws Exception if the condition does not meet
- */
- @Test(expected = NullPointerException.class)
- public void initializationClusterSingletonServiceProviderNullInputTest() throws Exception {
- clusterSingletonServiceProvider = new DOMClusterSingletonServiceProviderImpl(null);
- }
-
- /**
- * Test GoldPath for close {@link DOMClusterSingletonServiceProviderImpl}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void closeClusterSingletonServiceProviderTest() throws Exception {
- verify(mockEos).registerListener(SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
- verify(mockEos).registerListener(CLOSE_SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
- clusterSingletonServiceProvider.close();
- verify(mockEosEntityListReg).close();
- verify(mockEosDoubleEntityListReg).close();
- }
-
- /**
- * Test parser ServiceIdentifier from Entity.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void makeEntityClusterSingletonServiceProviderTest() throws Exception {
- final DOMEntity testEntity = clusterSingletonServiceProvider.createEntity(SERVICE_ENTITY_TYPE, SERVICE_NAME);
- Assert.assertEquals(entity, testEntity);
- final DOMEntity testDbEn = clusterSingletonServiceProvider.createEntity(CLOSE_SERVICE_ENTITY_TYPE,
- SERVICE_NAME);
- Assert.assertEquals(doubleEntity, testDbEn);
- }
-
- /**
- * Test parser ServiceIdentifier from Entity.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void getIdentifierClusterSingletonServiceProviderTest() throws Exception {
- final String entityIdentifier = clusterSingletonServiceProvider.getServiceIdentifierFromEntity(entity);
- Assert.assertEquals(SERVICE_NAME, entityIdentifier);
- final String doubleEntityId = clusterSingletonServiceProvider.getServiceIdentifierFromEntity(doubleEntity);
- Assert.assertEquals(SERVICE_NAME, doubleEntityId);
- }
-
- /**
- * Test GoldPath for initialization {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void initializationClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test GoldPath for initialization with init ownership result SLAVE {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void slaveInitClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
- verify(mockEos, never()).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test GoldPath for initialization with init ownership result SLAVE, but NO-MASTER {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void slaveInitNoMasterClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlaveNoMaster());
- verify(mockEos, never()).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test GoldPath for initialization with init ownership result MASTER {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void masterInitClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test GoldPath for initialization with init ownership result MASTER {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void masterInitSlaveDoubleCandidateClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void takeLeadershipClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ @Override
+ TestClusterSingletonService instantiateService() {
+ return new TestClusterSingletonAsyncServiceInstance();
}
/**
public void takeDoubleLeadershipClusterSingletonServiceTest() throws Exception {
final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
.registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
+ verify(mockDoubleEntityCandReg).close();
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEosEntityListReg, never()).close();
verify(mockEntityCandReg, never()).close();
- verify(mockDoubleEntityCandReg).close();
- }
-
- /**
- * Test GoldPath for initialization with init ownership result MASTER {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void masterInitClusterSingletonServiceTwoServicesTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService2);
- Assert.assertNotNull(reg2);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- }
-
- /**
- * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void takeLeadershipClusterSingletonServiceTwoAddDuringWaitPhaseServicesTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService2);
- Assert.assertNotNull(reg2);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
- }
-
- /**
- * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void takeLeadershipClusterSingletonServiceTowServicesTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
- final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService2);
- Assert.assertNotNull(reg2);
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
- }
-
- /**
- * Test checks CandidateAlreadyRegisteredException processing in initialization phase.
- *
- * @throws Exception if the condition does not meet
- */
- @Test(expected = RuntimeException.class)
- public void initializationClusterSingletonServiceCandidateAlreadyRegistredTest() throws Exception {
- doThrow(CandidateAlreadyRegisteredException.class).when(mockEos).registerCandidate(entity);
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNull(reg);
- }
-
- /**
- * Test GoldPath for lostLeadership during tryToTakeLeadership with ownership result MASTER
- * {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void lostLeadershipDuringTryToTakeLeadershipClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test GoldPath for lostLeadership with ownership result MASTER-TO-SLAVE {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void lostLeadershipClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
}
/**
public void unexpectedLostLeadershipDoubleCandidateTest() throws Exception {
final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
.registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
- Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEntityCandReg, never()).close();
verify(mockDoubleEntityCandReg, never()).close();
verify(mockEntityCandReg, atLeastOnce()).close();
verify(mockDoubleEntityCandReg, never()).close();
clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
- Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
verify(mockEntityCandReg, atLeastOnce()).close();
verify(mockDoubleEntityCandReg, atLeastOnce()).close();
verify(mockEosDoubleEntityListReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
}
/**
public void inJeopardyMasterTest() throws Exception {
final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
.registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getEntityToJeopardy());
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
- Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
verify(mockEosEntityListReg, never()).close();
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEntityCandReg, never()).close();
verify(mockDoubleEntityCandReg).close();
}
- /**
- * Test checks inJeopardy Cluster Node state for Slave Instance.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void inJeopardySlaveTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
- verify(mockEos, never()).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getEntityToJeopardy());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- verify(mockEosEntityListReg, never()).close();
- verify(mockEosDoubleEntityListReg, never()).close();
- verify(mockEntityCandReg, never()).close();
- verify(mockDoubleEntityCandReg, never()).close();
- }
-
- /**
- * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void closeClusterSingletonServiceRegistrationNoRoleTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- reg.close();
- verify(mockEosEntityListReg, never()).close();
- verify(mockEosDoubleEntityListReg, never()).close();
- verify(mockEntityCandReg).close();
- verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void closeClusterSingletonServiceRegistrationNoRoleTwoServicesTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService2);
- Assert.assertNotNull(reg2);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- reg.close();
- verify(mockEosEntityListReg, never()).close();
- verify(mockEosDoubleEntityListReg, never()).close();
- verify(mockEntityCandReg, never()).close();
- verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- }
-
- /**
- * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void closeClusterSingletonServiceRegistrationSlaveTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
- reg.close();
- verify(mockEosEntityListReg, never()).close();
- verify(mockEosDoubleEntityListReg, never()).close();
- verify(mockEntityCandReg).close();
- verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void closeClusterSingletonServiceRegistrationSlaveTwoServicesTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService2);
- Assert.assertNotNull(reg2);
- clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- reg.close();
- verify(mockEosEntityListReg, never()).close();
- verify(mockEosDoubleEntityListReg, never()).close();
- verify(mockEntityCandReg, never()).close();
- verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- }
-
/**
* Test checks close processing for {@link ClusterSingletonServiceRegistration}.
*
public void closeClusterSingletonServiceRegistrationMasterTest() throws Exception {
final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
.registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- verify(mockEos).registerCandidate(entity);
+ assertNotNull(reg);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
reg.close();
- Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
verify(mockEosEntityListReg, never()).close();
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEntityCandReg, atLeastOnce()).close();
verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
- Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
verify(mockEntityCandReg, atLeastOnce()).close();
verify(mockDoubleEntityCandReg, atLeastOnce()).close();
verify(mockEosDoubleEntityListReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
}
/**
public void closeClusterSingletonServiceRegistrationMasterCloseWithNotificationTimesTest() throws Exception {
final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
.registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- verify(mockEos).registerCandidate(entity);
+ assertNotNull(reg);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
reg.close();
- Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
verify(mockEosEntityListReg, never()).close();
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEntityCandReg, atLeastOnce()).close();
verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
- Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
verify(mockEntityCandReg, atLeastOnce()).close();
verify(mockDoubleEntityCandReg, atLeastOnce()).close();
verify(mockEosDoubleEntityListReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
}
/**
public void closeClusterSingletonServiceRegistrationMasterCloseCoupleTimesTest() throws Exception {
final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
.registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- verify(mockEos).registerCandidate(entity);
+ assertNotNull(reg);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
reg.close();
reg.close();
- Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
verify(mockEosEntityListReg, never()).close();
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEntityCandReg, atLeastOnce()).close();
verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
- Thread.sleep(ASYNC_TIME_DELAY_SEC * 2);
+ Thread.sleep(ASYNC_TIME_DELAY_MILLIS * 2);
verify(mockEntityCandReg, atLeastOnce()).close();
verify(mockDoubleEntityCandReg, atLeastOnce()).close();
verify(mockEosDoubleEntityListReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void closeClusterSingletonServiceRegistrationMasterTwoServicesTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService2);
- Assert.assertNotNull(reg2);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
- reg.close();
- verify(mockEosEntityListReg, never()).close();
- verify(mockEosDoubleEntityListReg, never()).close();
- verify(mockEntityCandReg, never()).close();
- verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
- }
-
- /**
- * Test checks validation Error processing for SLAVE-TO-MASTER entity Candidate role change.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void tryToTakeLeaderForClosedServiceRegistrationTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService2);
- Assert.assertNotNull(reg2);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- verify(mockEos).registerCandidate(entity);
- reg.close();
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
- verify(mockEosEntityListReg, never()).close();
- verify(mockEosDoubleEntityListReg, never()).close();
- verify(mockEntityCandReg, never()).close();
- verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
- }
-
- private DOMEntityOwnershipChange getEntityToMaster() {
- return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(false, true, true));
- }
-
- private DOMEntityOwnershipChange getEntityToSlave() {
- return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(true, false, true));
- }
-
- private DOMEntityOwnershipChange getInitEntityToSlave() {
- return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(false, false, true));
- }
-
- private DOMEntityOwnershipChange getInitEntityToSlaveNoMaster() {
- return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(false, false, false));
- }
-
- private DOMEntityOwnershipChange getDoubleEntityToMaster() {
- return new DOMEntityOwnershipChange(doubleEntity, EntityOwnershipChangeState.from(false, true, true));
- }
-
- private DOMEntityOwnershipChange getInitDoubleEntityToSlave() {
- return new DOMEntityOwnershipChange(doubleEntity, EntityOwnershipChangeState.from(false, false, true));
- }
-
- private DOMEntityOwnershipChange getDoubleEntityToSlave() {
- return new DOMEntityOwnershipChange(doubleEntity, EntityOwnershipChangeState.from(true, false, true));
- }
-
- private DOMEntityOwnershipChange getEntityToJeopardy() {
- return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(false, false, false), true);
- }
-
- /*
- * Base states for AbstractClusterProjectProvider
- */
- enum TestClusterSingletonServiceState {
- /*
- * State represents a correct Instantiated process
- */
- STARTED,
- /*
- * State represents a correct call abstract method instantiatingProject
- */
- INITIALIZED,
- /*
- * State represents a correct call abstract method destryingProject
- */
- DESTROYED;
- }
-
- /*
- * Test implementation of {@link ClusterSingletonService}
- */
- class TestClusterSingletonAsyncServiceInstance implements ClusterSingletonService {
-
- private final ServiceGroupIdentifier serviceId = ServiceGroupIdentifier.create(SERVICE_NAME);
- private TestClusterSingletonServiceState serviceState;
- protected SettableFuture<Void> future;
-
- TestClusterSingletonAsyncServiceInstance() {
- this.serviceState = TestClusterSingletonServiceState.INITIALIZED;
- }
-
- @Override
- public void instantiateServiceInstance() {
- this.serviceState = TestClusterSingletonServiceState.STARTED;
- }
-
- @Override
- public ListenableFuture<Void> closeServiceInstance() {
- this.serviceState = TestClusterSingletonServiceState.DESTROYED;
- future = SettableFuture.create();
- timer.schedule(new TimerTask() {
-
- @Override
- public void run() {
- future.set(null);
- }
- }, ASYNC_TIME_DELAY_SEC);
- return future;
- }
-
- public TestClusterSingletonServiceState getServiceState() {
- return serviceState;
- }
-
- @Override
- public ServiceGroupIdentifier getIdentifier() {
- return serviceId;
- }
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
}
}
package org.opendaylight.mdsal.singleton.dom.impl;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
-import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipCandidateRegistration;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipChange;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListenerRegistration;
-import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
-import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
/**
- * Testing {@link DOMClusterSingletonServiceProviderImpl} implementation.
+ * Synchronous test suite.
*/
-public class DOMClusterSingletonServiceProviderImplTest {
-
- private static final String SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.ServiceEntityType";
- private static final String CLOSE_SERVICE_ENTITY_TYPE = "org.opendaylight.mdsal.AsyncServiceCloseEntityType";
- private static final String SERVICE_NAME = "testServiceName";
-
- @Mock
- private DOMEntityOwnershipService mockEos;
- @Mock
- private DOMEntityOwnershipCandidateRegistration mockEntityCandReg;
- @Mock
- private DOMEntityOwnershipCandidateRegistration mockDoubleEntityCandReg;
- @Mock
- private DOMEntityOwnershipListenerRegistration mockEosEntityListReg;
- @Mock
- private DOMEntityOwnershipListenerRegistration mockEosDoubleEntityListReg;
-
- private DOMClusterSingletonServiceProviderImpl clusterSingletonServiceProvider;
- private TestClusterSingletonServiceInstance clusterSingletonService;
- private TestClusterSingletonServiceInstance clusterSingletonService2;
-
- private final DOMEntity entity = new DOMEntity(SERVICE_ENTITY_TYPE, SERVICE_NAME);
- private final DOMEntity doubleEntity = new DOMEntity(CLOSE_SERVICE_ENTITY_TYPE, SERVICE_NAME);
-
+public class DOMClusterSingletonServiceProviderImplTest extends AbstractDOMClusterServiceProviderTest {
/**
* Initialization functionality for every Tests in this suite.
*
- * @throws Exception if the condition does not meet
+ * @throws CandidateAlreadyRegisteredException if the condition does not meet
*/
+ @Override
@Before
- public void setup() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- doNothing().when(mockEosEntityListReg).close();
- doNothing().when(mockEosDoubleEntityListReg).close();
- doNothing().when(mockEntityCandReg).close();
- doNothing().when(mockDoubleEntityCandReg).close();
- doReturn(mockEosEntityListReg).when(mockEos).registerListener(eq(SERVICE_ENTITY_TYPE),
- any(DOMClusterSingletonServiceProviderImpl.class));
- doReturn(mockEosDoubleEntityListReg).when(mockEos).registerListener(eq(CLOSE_SERVICE_ENTITY_TYPE),
- any(DOMClusterSingletonServiceProviderImpl.class));
- doReturn(mockEntityCandReg).when(mockEos).registerCandidate(entity);
- doReturn(mockDoubleEntityCandReg).when(mockEos).registerCandidate(doubleEntity);
-
- clusterSingletonServiceProvider = new DOMClusterSingletonServiceProviderImpl(mockEos);
- clusterSingletonServiceProvider.initializeProvider();
- verify(mockEos).registerListener(SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
- verify(mockEos).registerListener(CLOSE_SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
-
- clusterSingletonService = new TestClusterSingletonServiceInstance();
- clusterSingletonService2 = new TestClusterSingletonServiceInstance();
-
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- }
-
- /**
- * Test checks NullPointer for null {@link DOMEntityOwnershipService} input value.
- *
- * @throws Exception if the condition does not meet
- */
- @Test(expected = NullPointerException.class)
- public void initializationClusterSingletonServiceProviderNullInputTest() throws Exception {
- clusterSingletonServiceProvider = new DOMClusterSingletonServiceProviderImpl(null);
- }
-
- /**
- * Test GoldPath for close {@link DOMClusterSingletonServiceProviderImpl}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void closeClusterSingletonServiceProviderTest() throws Exception {
- verify(mockEos).registerListener(SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
- verify(mockEos).registerListener(CLOSE_SERVICE_ENTITY_TYPE, clusterSingletonServiceProvider);
- clusterSingletonServiceProvider.close();
- verify(mockEosEntityListReg).close();
- verify(mockEosDoubleEntityListReg).close();
- }
-
- /**
- * Test parser ServiceIdentifier from Entity.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void makeEntityClusterSingletonServiceProviderTest() throws Exception {
- final DOMEntity testEntity = clusterSingletonServiceProvider.createEntity(SERVICE_ENTITY_TYPE, SERVICE_NAME);
- Assert.assertEquals(entity, testEntity);
- final DOMEntity testDbEn = clusterSingletonServiceProvider.createEntity(CLOSE_SERVICE_ENTITY_TYPE,
- SERVICE_NAME);
- Assert.assertEquals(doubleEntity, testDbEn);
- }
-
- /**
- * Test parser ServiceIdentifier from Entity.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void getIdentifierClusterSingletonServiceProviderTest() throws Exception {
- final String entityIdentifier = clusterSingletonServiceProvider.getServiceIdentifierFromEntity(entity);
- Assert.assertEquals(SERVICE_NAME, entityIdentifier);
- final String doubleEntityId = clusterSingletonServiceProvider.getServiceIdentifierFromEntity(doubleEntity);
- Assert.assertEquals(SERVICE_NAME, doubleEntityId);
- }
-
- /**
- * Test GoldPath for initialization {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void initializationClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test GoldPath for initialization with init ownership result SLAVE {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void slaveInitClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
- verify(mockEos, never()).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test GoldPath for initialization with init ownership result SLAVE, but NO-MASTER {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void slaveInitNoMasterClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlaveNoMaster());
- verify(mockEos, never()).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test GoldPath for initialization with init ownership result MASTER {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void masterInitClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test GoldPath for initialization with init ownership result MASTER {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void masterInitSlaveDoubleCandidateClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void takeLeadershipClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test GoldPath for initialization with init ownership result MASTER {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void masterInitClusterSingletonServiceTwoServicesTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService2);
- Assert.assertNotNull(reg2);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
+ public void setup() throws CandidateAlreadyRegisteredException {
+ super.setup();
}
/**
public void takeDoubleLeadershipClusterSingletonServiceTest() throws Exception {
final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
.registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEosEntityListReg, never()).close();
verify(mockEntityCandReg, never()).close();
verify(mockDoubleEntityCandReg).close();
}
- /**
- * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void takeLeadershipClusterSingletonServiceTwoAddDuringWaitPhaseServicesTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService2);
- Assert.assertNotNull(reg2);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
- }
-
- /**
- * Test GoldPath for takeLeadership with ownership result MASTER {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void takeLeadershipClusterSingletonServiceTowServicesTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
- final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService2);
- Assert.assertNotNull(reg2);
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
- }
-
- /**
- * Test checks CandidateAlreadyRegisteredException processing in initialization phase.
- *
- * @throws Exception if the condition does not meet
- */
- @Test(expected = RuntimeException.class)
- public void initializationClusterSingletonServiceCandidateAlreadyRegistredTest() throws Exception {
- doThrow(CandidateAlreadyRegisteredException.class).when(mockEos).registerCandidate(entity);
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNull(reg);
- }
-
- /**
- * Test GoldPath for lostLeadership during tryToTakeLeadership with ownership result MASTER
- * {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void lostLeadershipDuringTryToTakeLeadershipClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test GoldPath for lostLeadership with ownership result MASTER-TO-SLAVE {@link ClusterSingletonService}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void lostLeadershipClusterSingletonServiceTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
- }
-
/**
* Test checks unexpected change for MASTER-TO-SLAVE double Candidate role change.
*
public void unexpectedLostLeadershipDoubleCandidateTest() throws Exception {
final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
.registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEntityCandReg, never()).close();
verify(mockDoubleEntityCandReg, never()).close();
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEntityCandReg, atLeastOnce()).close();
verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
verify(mockEntityCandReg, atLeastOnce()).close();
verify(mockDoubleEntityCandReg, atLeastOnce()).close();
verify(mockEosDoubleEntityListReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
}
/**
public void inJeopardyMasterTest() throws Exception {
final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
.registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
+ assertNotNull(reg);
+ verify(mockEos).registerCandidate(ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getInitDoubleEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getEntityToJeopardy());
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
verify(mockEosEntityListReg, never()).close();
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEntityCandReg, never()).close();
verify(mockDoubleEntityCandReg).close();
}
- /**
- * Test checks inJeopardy Cluster Node state for Slave Instance.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void inJeopardySlaveTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
- verify(mockEos, never()).registerCandidate(doubleEntity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- clusterSingletonServiceProvider.ownershipChanged(getEntityToJeopardy());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- verify(mockEosEntityListReg, never()).close();
- verify(mockEosDoubleEntityListReg, never()).close();
- verify(mockEntityCandReg, never()).close();
- verify(mockDoubleEntityCandReg, never()).close();
- }
-
/**
* Test checks close processing for {@link ClusterSingletonServiceRegistration}.
*
* @throws Exception if the condition does not meet
*/
@Test
- public void closeClusterSingletonServiceRegistrationNoRoleTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- reg.close();
- verify(mockEosEntityListReg, never()).close();
- verify(mockEosDoubleEntityListReg, never()).close();
- verify(mockEntityCandReg).close();
- verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test checks close procesing for {@link ClusterSingletonServiceRegistration}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void closeClusterSingletonServiceRegistrationNoRoleTwoServicesTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService2);
- Assert.assertNotNull(reg2);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- reg.close();
- verify(mockEosEntityListReg, never()).close();
- verify(mockEosDoubleEntityListReg, never()).close();
- verify(mockEntityCandReg, never()).close();
- verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- }
-
- /**
- * Test checks close procesing for {@link ClusterSingletonServiceRegistration}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void closeClusterSingletonServiceRegistrationSlaveTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- verify(mockEos).registerCandidate(entity);
- clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
- reg.close();
- verify(mockEosEntityListReg, never()).close();
- verify(mockEosDoubleEntityListReg, never()).close();
- verify(mockEntityCandReg).close();
- verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- }
-
- /**
- * Test checks close procesing for {@link ClusterSingletonServiceRegistration}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void closeClusterSingletonServiceRegistrationSlaveTwoServicesTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- verify(mockEos).registerCandidate(entity);
- final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService2);
- Assert.assertNotNull(reg2);
- clusterSingletonServiceProvider.ownershipChanged(getInitEntityToSlave());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- reg.close();
- verify(mockEosEntityListReg, never()).close();
- verify(mockEosDoubleEntityListReg, never()).close();
- verify(mockEntityCandReg, never()).close();
- verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- }
-
- /**
- * Test checks close procesing for {@link ClusterSingletonServiceRegistration}.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
public void closeClusterSingletonServiceRegistrationMasterTest() throws Exception {
final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
.registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- verify(mockEos).registerCandidate(entity);
+ assertNotNull(reg);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
reg.close();
clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
verify(mockEosEntityListReg, never()).close();
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEntityCandReg).close();
verify(mockDoubleEntityCandReg).close();
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
}
/**
public void closeClusterSingletonServiceRegistrationMasterCloseWithNotificationTimesTest() throws Exception {
final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
.registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- verify(mockEos).registerCandidate(entity);
+ assertNotNull(reg);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
reg.close();
verify(mockEosEntityListReg, never()).close();
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEntityCandReg, atLeastOnce()).close();
verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
verify(mockEntityCandReg, atLeastOnce()).close();
verify(mockDoubleEntityCandReg, atLeastOnce()).close();
verify(mockEosDoubleEntityListReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
}
/**
public void closeClusterSingletonServiceRegistrationMasterCloseCoupleTimesTest() throws Exception {
final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
.registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- verify(mockEos).registerCandidate(entity);
+ assertNotNull(reg);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
reg.close();
reg.close();
verify(mockEosEntityListReg, never()).close();
verify(mockEosDoubleEntityListReg, never()).close();
verify(mockEntityCandReg, atLeastOnce()).close();
verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
verify(mockEntityCandReg, atLeastOnce()).close();
verify(mockDoubleEntityCandReg, atLeastOnce()).close();
verify(mockEosDoubleEntityListReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
}
+
/**
- * Test checks close processing for {@link ClusterSingletonServiceRegistration}.
- *
- * @throws Exception if the condition does not meet
+ * Verify that closing a group does not prevent next incarnation of it to be registered and the next incarnation
+ * will become active once the old incarnation finishes cleaning up.
*/
@Test
- public void closeClusterSingletonServiceRegistrationMasterTwoServicesTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
+ public void testTwoIncarnations() throws Exception {
+ ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
.registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService2);
- Assert.assertNotNull(reg2);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- verify(mockEos).registerCandidate(entity);
+ assertNotNull(reg);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
+ verify(mockEos).registerCandidate(ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
- reg.close();
- verify(mockEosEntityListReg, never()).close();
- verify(mockEosDoubleEntityListReg, never()).close();
- verify(mockEntityCandReg, never()).close();
- verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
- }
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService.getServiceState());
- /**
- * Test checks validation Error processing for SLAVE-TO-MASTER entity Candidate role change.
- *
- * @throws Exception if the condition does not meet
- */
- @Test
- public void tryToTakeLeaderForClosedServiceRegistrationTest() throws Exception {
- final ClusterSingletonServiceRegistration reg = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService);
- Assert.assertNotNull(reg);
- final ClusterSingletonServiceRegistration reg2 = clusterSingletonServiceProvider
- .registerClusterSingletonService(clusterSingletonService2);
- Assert.assertNotNull(reg2);
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- verify(mockEos).registerCandidate(entity);
+ // Close, triggers unregistration, but we will not continue with it.
reg.close();
- clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
- verify(mockEos).registerCandidate(doubleEntity);
- clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
verify(mockEosEntityListReg, never()).close();
verify(mockEosDoubleEntityListReg, never()).close();
- verify(mockEntityCandReg, never()).close();
+ verify(mockEntityCandReg).close();
verify(mockDoubleEntityCandReg, never()).close();
- Assert.assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService.getServiceState());
- Assert.assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
- }
- private DOMEntityOwnershipChange getEntityToMaster() {
- return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(false, true, true));
- }
-
- private DOMEntityOwnershipChange getEntityToSlave() {
- return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(true, false, true));
- }
-
- private DOMEntityOwnershipChange getInitEntityToSlave() {
- return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(false, false, true));
- }
-
- private DOMEntityOwnershipChange getInitEntityToSlaveNoMaster() {
- return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(false, false, false));
- }
-
- private DOMEntityOwnershipChange getDoubleEntityToMaster() {
- return new DOMEntityOwnershipChange(doubleEntity, EntityOwnershipChangeState.from(false, true, true));
- }
-
- private DOMEntityOwnershipChange getInitDoubleEntityToSlave() {
- return new DOMEntityOwnershipChange(doubleEntity, EntityOwnershipChangeState.from(false, false, true));
- }
-
- private DOMEntityOwnershipChange getDoubleEntityToSlave() {
- return new DOMEntityOwnershipChange(doubleEntity, EntityOwnershipChangeState.from(true, false, true));
- }
-
- private DOMEntityOwnershipChange getEntityToJeopardy() {
- return new DOMEntityOwnershipChange(entity, EntityOwnershipChangeState.from(false, false, false), true);
- }
-
- /**
- * Base states for AbstractClusterProjectProvider.
- */
- enum TestClusterSingletonServiceState {
+ // Instantiate the next incarnation
+ reset(mockEos);
+ reg = clusterSingletonServiceProvider.registerClusterSingletonService(clusterSingletonService2);
+ verify(mockEos, never()).registerCandidate(ENTITY);
+ assertEquals(TestClusterSingletonServiceState.INITIALIZED, clusterSingletonService2.getServiceState());
- /**
- * State represents a correct Instantiated process.
- */
-
- STARTED,
- /**
- * State represents a correct call abstract method instantiatingProject.
- */
- INITIALIZED,
-
- /**
- * State represents a correct call abstract method destryingProject.
- */
- DESTROYED;
- }
-
- /**
- * Test implementation of {@link ClusterSingletonService}.
- */
- class TestClusterSingletonServiceInstance implements ClusterSingletonService {
-
- private final ServiceGroupIdentifier serviceIndent = ServiceGroupIdentifier.create(SERVICE_NAME);
- private TestClusterSingletonServiceState serviceState;
-
- TestClusterSingletonServiceInstance() {
- this.serviceState = TestClusterSingletonServiceState.INITIALIZED;
- }
-
- @Override
- public void instantiateServiceInstance() {
- this.serviceState = TestClusterSingletonServiceState.STARTED;
- }
+ // Drive the old incarnation to closure, resetting mocks as needed
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToSlave());
+ verify(mockEntityCandReg).close();
+ verify(mockDoubleEntityCandReg).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
- @Override
- public ListenableFuture<Void> closeServiceInstance() {
- this.serviceState = TestClusterSingletonServiceState.DESTROYED;
- return Futures.immediateFuture(null);
- }
+ // Reset mocks for reuse. The next change should see the previous group terminate and the next incarnation
+ // to start coming up
+ reset(mockEntityCandReg);
+ reset(mockDoubleEntityCandReg);
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToSlave());
+ verify(mockEos).registerCandidate(ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getEntityToMaster());
+ verify(mockEos).registerCandidate(DOUBLE_ENTITY);
+ clusterSingletonServiceProvider.ownershipChanged(getDoubleEntityToMaster());
+ assertEquals(TestClusterSingletonServiceState.STARTED, clusterSingletonService2.getServiceState());
- public TestClusterSingletonServiceState getServiceState() {
- return serviceState;
- }
+ // Check for potential service mixup
+ assertEquals(TestClusterSingletonServiceState.DESTROYED, clusterSingletonService.getServiceState());
- @Override
- public ServiceGroupIdentifier getIdentifier() {
- return serviceIndent;
- }
+ verify(mockEosEntityListReg, never()).close();
+ verify(mockEosDoubleEntityListReg, never()).close();
}
}
--- /dev/null
+org.slf4j.simpleLogger.showDateTime=true
+org.slf4j.simpleLogger.dateTimeFormat=hh:mm:ss,S a
+org.slf4j.simpleLogger.logFile=System.out
+org.slf4j.simpleLogger.showShortLogName=true
+org.slf4j.simpleLogger.levelInBrackets=true
+org.slf4j.simpleLogger.log.org.opendaylight.mdsal=debug