2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.openflowplugin.impl.role;
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import com.google.common.base.Verify;
13 import java.util.concurrent.ConcurrentHashMap;
14 import java.util.concurrent.ConcurrentMap;
15 import javax.annotation.CheckForNull;
16 import javax.annotation.Nonnull;
17 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
18 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
19 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
20 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
21 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
22 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipState;
23 import org.opendaylight.openflowplugin.api.openflow.role.RoleChangeListener;
24 import org.opendaylight.openflowplugin.api.openflow.role.RoleManager;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
30 * Class strictly separates {@link EntityOwnershipService} and OpenflowPlugin. So internal OpenflowPlugin
31 * implementation will stay without change for all {@link EntityOwnershipService} API changes.
33 * Created by kramesha on 9/14/15.
35 public class OpenflowOwnershipListener implements EntityOwnershipListener, AutoCloseable {
37 private static final Logger LOG = LoggerFactory.getLogger(OpenflowOwnershipListener.class);
39 public static boolean REMOVE_NODE_FROM_DS = true;
41 private final EntityOwnershipService entityOwnershipService;
42 private EntityOwnershipListenerRegistration entityOwnershipListenerRegistration;
43 private final ConcurrentMap<Entity, RoleChangeListener> roleChangeListenerMap = new ConcurrentHashMap<>();
46 * Initialization method has to be call from {@link org.opendaylight.openflowplugin.api.openflow.role.RoleManager}
47 * @param entityOwnershipService
49 public OpenflowOwnershipListener(@Nonnull final EntityOwnershipService entityOwnershipService) {
50 LOG.debug("New instance of OpenflowOwnershipListener is created");
51 this.entityOwnershipService = Preconditions.checkNotNull(entityOwnershipService);
55 * Initialization method is register {@link OpenflowOwnershipListener} as listener
56 * for EntityType = {@link RoleManager#ENTITY_TYPE}
59 LOG.debug("OpenflowOwnershipListener is registred as EntityOwnershipListener for {} type", RoleManager.ENTITY_TYPE);
60 entityOwnershipListenerRegistration = entityOwnershipService.registerListener(RoleManager.ENTITY_TYPE, this);
64 public void ownershipChanged(final EntityOwnershipChange ownershipChange) {
65 Preconditions.checkArgument(ownershipChange != null);
66 final RoleChangeListener roleChangeListener = roleChangeListenerMap.get(ownershipChange.getEntity());
69 if (roleChangeListener != null) {
70 LOG.debug("Found local entity:{}", ownershipChange.getEntity());
72 // if this was the master and entity does not have a master
73 if (ownershipChange.wasOwner() && !ownershipChange.isOwner() && !ownershipChange.hasOwner()) {
74 // possible the last node to be disconnected from device.
75 // eligible for the device to get deleted from inventory.
76 LOG.debug("Initiate removal from operational. Possibly the last node to be disconnected for :{}. ", ownershipChange);
77 roleChangeListener.onDeviceDisconnectedFromCluster();
80 final OfpRole newRole = ownershipChange.isOwner() ? OfpRole.BECOMEMASTER : OfpRole.BECOMESLAVE;
81 final OfpRole oldRole = ownershipChange.wasOwner() ? OfpRole.BECOMEMASTER : OfpRole.BECOMESLAVE;
82 // send even if they are same. we do the check for duplicates in SalRoleService and maintain a lastKnownRole
83 roleChangeListener.onRoleChanged(oldRole, newRole);
89 * Candidate registration process doesn't send Event about actual {@link EntityOwnershipState} for
90 * Candidate. So we have to ask {@link EntityOwnershipService#getOwnershipState(Entity)} directly
91 * for every new instance. Call this method from RoleManager after candidateRegistration.
92 * @param roleChangeListener - new {@link RoleChangeListener} RoleContext
94 public void registerRoleChangeListener(@CheckForNull final RoleChangeListener roleChangeListener) {
95 LOG.debug("registerRoleChangeListener {}", roleChangeListener);
96 Preconditions.checkArgument(roleChangeListener != null);
97 Verify.verify(roleChangeListenerMap.putIfAbsent(roleChangeListener.getEntity(), roleChangeListener) == null);
99 final Entity entity = roleChangeListener.getEntity();
101 final Optional<EntityOwnershipState> entityOwnershipStateOptional = entityOwnershipService.getOwnershipState(entity);
103 if (entityOwnershipStateOptional != null && entityOwnershipStateOptional.isPresent()) {
104 final EntityOwnershipState entityOwnershipState = entityOwnershipStateOptional.get();
105 if (entityOwnershipState.hasOwner()) {
106 LOG.debug("An owner exist for entity {}", entity);
107 if (entityOwnershipState.isOwner()) {
108 LOG.debug("Ownership is here for entity {} becoming master", entity);
109 roleChangeListener.onRoleChanged(OfpRole.BECOMEMASTER, OfpRole.BECOMEMASTER);
111 LOG.debug("Ownership is NOT here for entity {} becoming alave", entity);
112 roleChangeListener.onRoleChanged(OfpRole.BECOMESLAVE, OfpRole.BECOMESLAVE);
119 * Unregistration process has to remove {@link RoleChangeListener} from internal map, so
120 * we will not get anymore Events for this listener.
121 * @param roleChangeListener - RoleContext
123 public void unregisterRoleChangeListener(@CheckForNull final RoleChangeListener roleChangeListener) {
124 LOG.debug("unregisterroleChangeListener {}", roleChangeListener);
125 Preconditions.checkArgument(roleChangeListener != null);
126 roleChangeListenerMap.remove(roleChangeListener.getEntity(), roleChangeListener);
130 public void close() throws Exception {
131 if (entityOwnershipListenerRegistration != null) {
132 entityOwnershipListenerRegistration.close();