2 * Copyright (c) 2016 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
9 package org.opendaylight.unimgr.impl;
11 import java.util.List;
12 import java.util.Optional;
13 import java.util.concurrent.locks.ReentrantReadWriteLock;
15 import javax.annotation.Nonnull;
17 import org.opendaylight.unimgr.mef.nrp.api.ActivationDriver;
18 import org.opendaylight.unimgr.mef.nrp.api.ActivationDriverAmbiguousException;
19 import org.opendaylight.unimgr.mef.nrp.api.ActivationDriverBuilder;
20 import org.opendaylight.unimgr.mef.nrp.api.ActivationDriverNotFoundException;
21 import org.opendaylight.unimgr.mef.nrp.api.ActivationDriverRepoService;
22 import org.opendaylight.unimgr.mef.nrp.impl.ActivationTransaction;
23 import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.forwarding.constructs.ForwardingConstruct;
24 import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
28 import static org.opendaylight.unimgr.mef.nrp.impl.ActivationTransaction.Result;
31 * @author bartosz.michalik@amartus.com
32 * @author krzysztof.bijakowski@amartus.com [modifications]
34 public class ForwardingConstructActivatorService {
35 private static final Logger LOG = LoggerFactory.getLogger(ForwardingConstructActivatorService.class);
36 private ActivationDriverRepoService activationRepoService;
37 private final ReentrantReadWriteLock lock;
39 public ForwardingConstructActivatorService(ActivationDriverRepoService activationRepoService) {
40 this.activationRepoService = activationRepoService;
41 lock = new ReentrantReadWriteLock();
45 * Activate a MEF ForwardingConstruct.
46 * @param forwardingConstruct the new route to activate
48 public void activate(@Nonnull ForwardingConstruct forwardingConstruct, @Nonnull ForwardingConstructActivationStateTracker stateTracker) {
49 if(stateTracker.isActivatable()) {
50 Optional<ActivationTransaction> tx = prepareTransaction(forwardingConstruct);
52 Result result = tx.get().activate();
54 if(result.isSuccessful()) {
55 stateTracker.activated(forwardingConstruct);
56 LOG.info("Forwarding construct activated successfully, request = {} ", forwardingConstruct);
58 stateTracker.activationFailed(forwardingConstruct);
59 LOG.warn("Forwarding construct activation failed, reason = {}, request = {}", result.getMessage(), forwardingConstruct);
62 LOG.warn("No transaction for this activation request {}", forwardingConstruct);
68 * Deactivate a MEF ForwardingConstruct.
69 * @param forwardingConstruct the existing route to deactivate
71 public void deactivate(@Nonnull ForwardingConstruct forwardingConstruct, @Nonnull ForwardingConstructActivationStateTracker stateTracker) {
72 if(stateTracker.isDeactivatable()) {
73 Optional<ActivationTransaction> tx = prepareTransaction(forwardingConstruct);
75 Result result = tx.get().deactivate();
77 if(result.isSuccessful()) {
78 stateTracker.deactivated();
79 LOG.info("Forwarding construct deactivated successfully, request = {}", forwardingConstruct);
81 stateTracker.deactivationFailed();
82 LOG.warn("Forwarding construct deactivation failed, reason = {}, request = {}", result.getMessage(), forwardingConstruct);
85 LOG.warn("No transaction for this deactivation request {}", forwardingConstruct);
90 private Optional<ActivationTransaction> prepareTransaction(ForwardingConstruct fwdC) {
91 final List<FcPort> list = fwdC.getFcPort();
92 //TODO validate pre-condition
93 final FcPort a = list.get(0);
94 final FcPort z = list.get(1);
96 return isTheSameNode(fwdC)
97 ? getTxForNode(a,z, fwdC) : getTxForMultiNode(a,z, fwdC);
100 private boolean isTheSameNode(ForwardingConstruct forwardingConstruct) {
101 final FcPort p1 = forwardingConstruct.getFcPort().get(0);
102 final FcPort p2 = forwardingConstruct.getFcPort().get(1);
103 return p1.getNode().equals(p2.getNode());
106 private Optional<ActivationTransaction> getTxForNode(FcPort portA, FcPort portZ, ForwardingConstruct fwdC) {
107 lock.readLock().lock();
109 final ActivationDriverBuilder.BuilderContext ctx = new ActivationDriverBuilder.BuilderContext();
110 ActivationDriver activator = activationRepoService.getDriver(portA, portZ, ctx);
112 activator.initialize(portA, portZ, fwdC);
113 ActivationTransaction tx = new ActivationTransaction();
114 tx.addDriver(activator);
115 return Optional.of(tx);
116 } catch (ActivationDriverNotFoundException e) {
117 LOG.warn("No unique activation driver found for {} <-> {}", portA, portZ);
118 return Optional.empty();
119 } catch (ActivationDriverAmbiguousException e) {
120 LOG.warn("Multiple activation driver found for {} <-> {}", portZ, portA);
121 return Optional.empty();
122 } catch (Exception e) {
123 LOG.error("driver initialization exception", e);
124 return Optional.empty();
126 lock.readLock().unlock();
130 private Optional<ActivationTransaction> getTxForMultiNode(FcPort portA, FcPort portZ, ForwardingConstruct fwdC) {
131 //1. find and initialize drivers
132 lock.readLock().lock();
135 final ActivationDriverBuilder.BuilderContext ctx = new ActivationDriverBuilder.BuilderContext();
136 ctx.put(ForwardingConstruct.class.getName(), fwdC);
138 Optional<ActivationDriver> aendActivator = findDriver(portA, ctx);
139 Optional<ActivationDriver> zendActivator = findDriver(portZ, ctx);
141 if (aendActivator.isPresent() && zendActivator.isPresent()) {
142 aendActivator.get().initialize(portA, portZ, fwdC);
143 zendActivator.get().initialize(portZ, portA, fwdC);
145 final ActivationTransaction tx = new ActivationTransaction();
146 tx.addDriver(aendActivator.get());
147 tx.addDriver(zendActivator.get());
149 return Optional.of(tx);
151 // ??? TODO improve comment for better traceability
152 LOG.error("drivers for both ends needed");
153 return Optional.empty();
156 } catch (Exception e) {
157 LOG.error("driver initialization exception",e);
158 return Optional.empty();
160 lock.readLock().unlock();
164 protected Optional<ActivationDriver> findDriver(FcPort port, ActivationDriverBuilder.BuilderContext fwdC) {
165 if (activationRepoService == null) {
166 LOG.warn("Activation Driver repo is not initialized");
167 return Optional.empty();
170 return Optional.ofNullable(activationRepoService.getDriver(port, fwdC));
171 } catch (ActivationDriverNotFoundException e) {
172 LOG.warn("No activation driver found for {}", port);
173 return Optional.empty();
174 } catch (ActivationDriverAmbiguousException e) {
175 LOG.warn("Multiple activation driver found for {}", port);
176 return Optional.empty();
183 * Set the activation driver repository service.
184 * @param activationRepoService service to use
186 public void setActivationRepoService(ActivationDriverRepoService activationRepoService) {
187 lock.writeLock().lock();
188 this.activationRepoService = activationRepoService;
189 lock.writeLock().unlock();
193 * Unset the activation driver repository service.
195 public void unsetActivationRepoService() {
196 lock.writeLock().lock();
197 this.activationRepoService = null;
198 lock.writeLock().unlock();
201 static final class Context {
204 final ForwardingConstruct fwC;
206 public Context(FcPort portA, FcPort portZ, ForwardingConstruct fwC) {