Bug-5523 CloseConnection changes
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / role / RoleContextImpl.java
1 /**
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.openflowplugin.impl.role;
9
10 import com.google.common.base.Preconditions;
11
12 import java.util.concurrent.Semaphore;
13 import java.util.concurrent.TimeUnit;
14 import javax.annotation.Nullable;
15
16 import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
17 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
18 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
19 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
20 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
21 import org.opendaylight.openflowplugin.api.openflow.role.RoleContext;
22 import org.opendaylight.openflowplugin.impl.LifecycleConductor;
23 import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SalRoleService;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * Role context hold information about entity ownership registration,
31  * register and unregister candidate (main and tx)
32  */
33 class RoleContextImpl implements RoleContext {
34
35     private static final Logger LOG = LoggerFactory.getLogger(RoleContextImpl.class);
36     private static final int TIMEOUT = 12;
37
38     private final NodeId nodeId;
39     private final EntityOwnershipService entityOwnershipService;
40     private volatile EntityOwnershipCandidateRegistration entityOwnershipCandidateRegistration = null;
41     private volatile EntityOwnershipCandidateRegistration txEntityOwnershipCandidateRegistration = null;
42
43     private final Entity entity;
44     private final Entity txEntity;
45
46     private SalRoleService salRoleService = null;
47
48     private final Semaphore roleChangeGuard = new Semaphore(1, true);
49
50     public RoleContextImpl(final NodeId nodeId, final EntityOwnershipService entityOwnershipService, final Entity entity, final Entity txEntity) {
51         this.entityOwnershipService = entityOwnershipService;
52         this.entity = entity;
53         this.txEntity = txEntity;
54         this.nodeId = nodeId;
55     }
56
57     @Override
58     public boolean initialization() {
59         LOG.info("Initialization main candidate for node {}", nodeId);
60         return registerCandidate(this.entity);
61     }
62
63     @Override
64     public void unregisterAllCandidates() {
65         LOG.info("Role context closed, unregistering all candidates for ownership for node {}", nodeId);
66         if (isMainCandidateRegistered()) {
67             unregisterCandidate(this.entity);
68         }
69         if (isTxCandidateRegistered()) {
70             unregisterCandidate(this.txEntity);
71         }
72         LifecycleConductor.getInstance().closeConnection(nodeId);
73     }
74
75     @Nullable
76     @Override
77     public <T> RequestContext<T> createRequestContext() {
78         return new AbstractRequestContext<T>(LifecycleConductor.getInstance().reserveXidForDeviceMessage(nodeId)) {
79             @Override
80             public void close() {
81             }
82         };
83     }
84
85     @Override
86     public void setSalRoleService(final SalRoleService salRoleService) {
87         Preconditions.checkNotNull(salRoleService);
88         this.salRoleService = salRoleService;
89     }
90
91     @Override
92     public SalRoleService getSalRoleService() {
93         return this.salRoleService;
94     }
95
96     @Override
97     public Entity getEntity() {
98         return this.entity;
99     }
100
101     @Override
102     public Entity getTxEntity() {
103         return this.txEntity;
104     }
105
106     @Override
107     public NodeId getNodeId() {
108         return nodeId;
109     }
110
111     @Override
112     public boolean isMainCandidateRegistered() {
113         return entityOwnershipCandidateRegistration != null;
114     }
115
116     @Override
117     public boolean isTxCandidateRegistered() {
118         return txEntityOwnershipCandidateRegistration != null;
119     }
120
121     @Override
122     public boolean registerCandidate(final Entity entity_) {
123         boolean permit = false;
124         try {
125             permit = roleChangeGuard.tryAcquire(TIMEOUT, TimeUnit.SECONDS);
126             if(permit) {
127                 LOG.debug("Register candidate for entity {}", entity_);
128                 if (entity_.equals(this.entity)) {
129                     entityOwnershipCandidateRegistration = entityOwnershipService.registerCandidate(entity_);
130                 } else {
131                     txEntityOwnershipCandidateRegistration = entityOwnershipService.registerCandidate(entity_);
132                 }
133             } else {
134                 return false;
135             }
136         } catch (final CandidateAlreadyRegisteredException e) {
137             LOG.warn("Candidate for entity {} is already registered.", entity_.getType());
138             return false;
139         } catch (final InterruptedException e) {
140             LOG.warn("Cannot acquire semaphore for register entity {} candidate.", entity_.getType());
141             return false;
142         } finally {
143             if (permit) {
144                 roleChangeGuard.release();
145             }
146         }
147         return true;
148     }
149
150     @Override
151     public boolean unregisterCandidate(final Entity entity_) {
152         boolean permit = false;
153         try {
154             permit = roleChangeGuard.tryAcquire(TIMEOUT, TimeUnit.SECONDS);
155             if(permit) {
156                 if (entity_.equals(this.entity)) {
157                     if (entityOwnershipCandidateRegistration != null) {
158                         LOG.debug("Unregister candidate for entity {}", entity_);
159                         entityOwnershipCandidateRegistration.close();
160                         entityOwnershipCandidateRegistration = null;
161                     }
162                 } else {
163                     if (txEntityOwnershipCandidateRegistration != null) {
164                         LOG.debug("Unregister candidate for tx entity {}", entity_);
165                         txEntityOwnershipCandidateRegistration.close();
166                         txEntityOwnershipCandidateRegistration = null;
167                     }
168                 }
169             } else {
170                 return false;
171             }
172         } catch (final InterruptedException e) {
173             LOG.warn("Cannot acquire semaphore for unregister entity {} candidate.", entity_.getType());
174             return false;
175         } finally {
176             if (permit) {
177                 roleChangeGuard.release();
178             }
179         }
180         return true;
181     }
182
183     @Override
184     public void close() {
185         unregisterAllCandidates();
186     }
187
188     public boolean isMaster(){
189         return (txEntityOwnershipCandidateRegistration != null && entityOwnershipCandidateRegistration != null);
190     }
191 }