X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=openflowplugin-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fopenflowplugin%2Fimpl%2Frole%2FRoleContextImpl.java;h=3e33a80845768c0a59b8f9fe9d67e162dfe7cf7f;hb=ccd98d1fef61f9adf810e117e090560f16a8e3c4;hp=dd0820feadb605cfd8adc277aaec8d8756a83f68;hpb=0ab4f7b6c3b033de6810dbfafc1907b8c3c724a6;p=openflowplugin.git diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleContextImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleContextImpl.java index dd0820fead..3e33a80845 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleContextImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/role/RoleContextImpl.java @@ -8,21 +8,31 @@ package org.opendaylight.openflowplugin.impl.role; import com.google.common.base.Preconditions; - -import java.util.concurrent.Semaphore; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.JdkFutureAdapters; +import com.google.common.util.concurrent.ListenableFuture; +import io.netty.util.HashedWheelTimer; +import io.netty.util.TimerTask; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import javax.annotation.Nonnull; import javax.annotation.Nullable; - -import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException; -import org.opendaylight.controller.md.sal.common.api.clustering.Entity; -import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration; -import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService; +import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; +import org.opendaylight.openflowplugin.api.OFConstants; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo; import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; import org.opendaylight.openflowplugin.api.openflow.role.RoleContext; -import org.opendaylight.openflowplugin.impl.LifecycleConductor; +import org.opendaylight.openflowplugin.api.openflow.role.RoleManager; import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole; import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SalRoleService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput; +import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,57 +43,36 @@ import org.slf4j.LoggerFactory; class RoleContextImpl implements RoleContext { private static final Logger LOG = LoggerFactory.getLogger(RoleContextImpl.class); - public static final int TIMEOUT = 12; - - private final NodeId nodeId; - private final EntityOwnershipService entityOwnershipService; - private volatile EntityOwnershipCandidateRegistration entityOwnershipCandidateRegistration = null; - private volatile EntityOwnershipCandidateRegistration txEntityOwnershipCandidateRegistration = null; - - private final Entity entity; - private final Entity txEntity; + // Maximum limit of timeout retries when cleaning DS, to prevent infinite recursive loops + private static final int MAX_CLEAN_DS_RETRIES = 3; private SalRoleService salRoleService = null; - - private final Semaphore roleChangeGuard = new Semaphore(1, true); - - public RoleContextImpl(NodeId nodeId, EntityOwnershipService entityOwnershipService, Entity entity, Entity txEntity) { - this.entityOwnershipService = entityOwnershipService; - this.entity = entity; - this.txEntity = txEntity; - this.nodeId = nodeId; - } - - @Override - public boolean initialization() { - LOG.info("Initialization main candidate for node {}", nodeId); - return registerCandidate(this.entity); - } - - @Override - public void unregisterAllCandidates() { - LOG.info("Role context closed, unregistering all candidates for ownership for node {}", nodeId); - if (isMainCandidateRegistered()) { - unregisterCandidate(this.entity); - } - if (isTxCandidateRegistered()) { - unregisterCandidate(this.txEntity); - } + private final HashedWheelTimer hashedWheelTimer; + private final DeviceInfo deviceInfo; + private CONTEXT_STATE state; + private final RoleManager myManager; + + RoleContextImpl(final DeviceInfo deviceInfo, + final HashedWheelTimer hashedWheelTimer, + final RoleManager myManager) { + this.deviceInfo = deviceInfo; + state = CONTEXT_STATE.WORKING; + this.myManager = myManager; + this.hashedWheelTimer = hashedWheelTimer; } @Nullable @Override public RequestContext createRequestContext() { - final AbstractRequestContext ret = new AbstractRequestContext(LifecycleConductor.getInstance().reserveXidForDeviceMessage(nodeId)) { + return new AbstractRequestContext(deviceInfo.reserveXidForDeviceMessage()) { @Override public void close() { } }; - return ret; } @Override - public void setSalRoleService(final SalRoleService salRoleService) { + public void setSalRoleService(@Nonnull final SalRoleService salRoleService) { Preconditions.checkNotNull(salRoleService); this.salRoleService = salRoleService; } @@ -94,98 +83,69 @@ class RoleContextImpl implements RoleContext { } @Override - public Entity getEntity() { - return this.entity; + public CONTEXT_STATE getState() { + return this.state; } @Override - public Entity getTxEntity() { - return this.txEntity; + public void setState(CONTEXT_STATE state) { + this.state = state; } @Override - public NodeId getNodeId() { - return nodeId; + public ServiceGroupIdentifier getServiceIdentifier() { + return this.deviceInfo.getServiceIdentifier(); } @Override - public boolean isMainCandidateRegistered() { - return entityOwnershipCandidateRegistration != null; + public DeviceInfo getDeviceInfo() { + return this.deviceInfo; } - @Override - public boolean isTxCandidateRegistered() { - return txEntityOwnershipCandidateRegistration != null; + public void startupClusterServices() throws ExecutionException, InterruptedException { + //TODO: Add callback ? + sendRoleChangeToDevice(OfpRole.BECOMEMASTER).get(); } @Override - public boolean registerCandidate(final Entity entity_) { - boolean permit = false; + public ListenableFuture stopClusterServices() { + ListenableFuture future; try { - permit = roleChangeGuard.tryAcquire(TIMEOUT, TimeUnit.SECONDS); - if(permit) { - LOG.debug("Register candidate for entity {}", entity_); - if (entity_.equals(this.entity)) { - entityOwnershipCandidateRegistration = entityOwnershipService.registerCandidate(entity_); - } else { - txEntityOwnershipCandidateRegistration = entityOwnershipService.registerCandidate(entity_); - } - } else { - return false; - } - } catch (CandidateAlreadyRegisteredException e) { - LOG.warn("Candidate for entity {} is already registered.", entity_.getType()); - return false; - } catch (InterruptedException e) { - LOG.warn("Cannot acquire semaphore for register entity {} candidate.", entity_.getType()); - return false; + //TODO: Add callback + sendRoleChangeToDevice(OfpRole.BECOMESLAVE).get(); + } catch (InterruptedException | ExecutionException e) { + LOG.warn("Send role to device failed ", e); } finally { - if (permit) { - roleChangeGuard.release(); - } + myManager.removeDeviceFromOperationalDS(deviceInfo, MAX_CLEAN_DS_RETRIES); + future = Futures.immediateFuture(null); } - return true; + return future; } - @Override - public boolean unregisterCandidate(final Entity entity_) { - boolean permit = false; - try { - permit = roleChangeGuard.tryAcquire(TIMEOUT, TimeUnit.SECONDS); - if(permit) { - if (entity_.equals(this.entity)) { - if (entityOwnershipCandidateRegistration != null) { - LOG.debug("Unregister candidate for entity {}", entity_); - entityOwnershipCandidateRegistration.close(); - entityOwnershipCandidateRegistration = null; - } - } else { - if (txEntityOwnershipCandidateRegistration != null) { - LOG.debug("Unregister candidate for tx entity {}", entity_); - txEntityOwnershipCandidateRegistration.close(); - txEntityOwnershipCandidateRegistration = null; - } + private ListenableFuture> sendRoleChangeToDevice(final OfpRole newRole) { + LOG.debug("Sending new role {} to device {}", newRole, deviceInfo.getNodeId()); + final Future> setRoleOutputFuture; + final Short version = deviceInfo.getVersion(); + if (null == version) { + LOG.debug("Device version is null"); + return Futures.immediateFuture(null); + } + if (version < OFConstants.OFP_VERSION_1_3) { + LOG.debug("Device version not support ROLE"); + return Futures.immediateFuture(null); + } else { + final SetRoleInput setRoleInput = (new SetRoleInputBuilder()).setControllerRole(newRole) + .setNode(new NodeRef(DeviceStateUtil.createNodeInstanceIdentifier(deviceInfo.getNodeId()))).build(); + setRoleOutputFuture = getSalRoleService().setRole(setRoleInput); + final TimerTask timerTask = timeout -> { + if (!setRoleOutputFuture.isDone()) { + LOG.warn("New role {} was not propagated to device {} during 10 sec", newRole, deviceInfo.getNodeId()); + setRoleOutputFuture.cancel(true); } - } else { - return false; - } - } catch (InterruptedException e) { - LOG.warn("Cannot acquire semaphore for unregister entity {} candidate.", entity_.getType()); - return false; - } finally { - if (permit) { - roleChangeGuard.release(); - } + }; + hashedWheelTimer.newTimeout(timerTask, 10, TimeUnit.SECONDS); } - return true; + return JdkFutureAdapters.listenInPoolThread(setRoleOutputFuture); } - @Override - public void close() { - unregisterAllCandidates(); - } - - public boolean isMaster(){ - return (txEntityOwnershipCandidateRegistration != null && entityOwnershipCandidateRegistration != null); - } }