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.services.sal;
10 import com.google.common.base.Preconditions;
11 import com.google.common.util.concurrent.Futures;
12 import com.google.common.util.concurrent.JdkFutureAdapters;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import com.google.common.util.concurrent.MoreExecutors;
15 import java.math.BigInteger;
16 import java.util.concurrent.Future;
17 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext.CONNECTION_STATE;
18 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
19 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
20 import org.opendaylight.openflowplugin.api.openflow.device.Xid;
21 import org.opendaylight.openflowplugin.impl.services.AbstractSimpleService;
22 import org.opendaylight.openflowplugin.impl.services.RoleService;
23 import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SalRoleService;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput;
30 import org.opendaylight.yangtools.yang.common.RpcResult;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
35 public final class SalRoleServiceImpl extends AbstractSimpleService<SetRoleInput, SetRoleOutput>
36 implements SalRoleService {
38 private static final Logger LOG = LoggerFactory.getLogger(SalRoleServiceImpl.class);
39 private static final BigInteger MAX_GENERATION_ID = new BigInteger("ffffffffffffffff", 16);
41 private final DeviceContext deviceContext;
42 private final RoleService roleService;
44 public SalRoleServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext) {
45 super(requestContextStack, deviceContext, SetRoleOutput.class);
46 this.deviceContext = Preconditions.checkNotNull(deviceContext);
47 this.roleService = new RoleService(requestContextStack, deviceContext, RoleRequestOutput.class);
51 protected OfHeader buildRequest(final Xid xid, final SetRoleInput input) throws ServiceException {
56 public ListenableFuture<RpcResult<SetRoleOutput>> setRole(final SetRoleInput input) {
57 LOG.info("SetRole called with input:{}", input);
59 // Check current connection state
60 final CONNECTION_STATE state = deviceContext.getPrimaryConnectionContext().getConnectionState();
63 LOG.info("Device {} has been disconnected", input.getNode());
64 return Futures.immediateFailedFuture(new Exception(String
65 .format("Device connection doesn't exist anymore. Primary connection status : %s",
69 LOG.trace("Device {} has been working", input.getNode());
72 LOG.warn("Device {} is in state {}, role change is not allowed", input.getNode(), state);
73 return Futures.immediateFailedFuture(new Exception(String
74 .format("Unexpected device connection status : %s", state)));
77 LOG.info("Requesting state change to {}", input.getControllerRole());
78 return tryToChangeRole(input.getControllerRole());
81 private ListenableFuture<RpcResult<SetRoleOutput>> tryToChangeRole(final OfpRole role) {
82 LOG.info("RoleChangeTask called on device:{} OFPRole:{}", getDeviceInfo().getNodeId().getValue(), role);
84 final Future<BigInteger> generationFuture = roleService.getGenerationIdFromDevice(getVersion());
86 return Futures.transformAsync(JdkFutureAdapters.listenInPoolThread(generationFuture), generationId -> {
87 LOG.debug("RoleChangeTask, GenerationIdFromDevice from device {} is {}",
88 getDeviceInfo().getNodeId().getValue(), generationId);
89 final BigInteger nextGenerationId = getNextGenerationId(generationId);
90 LOG.debug("nextGenerationId received from device:{} is {}",
91 getDeviceInfo().getNodeId().getValue(), nextGenerationId);
92 final Future<RpcResult<SetRoleOutput>> submitRoleFuture =
93 roleService.submitRoleChange(role, getVersion(), nextGenerationId);
94 return JdkFutureAdapters.listenInPoolThread(submitRoleFuture);
95 }, MoreExecutors.directExecutor());
98 private static BigInteger getNextGenerationId(final BigInteger generationId) {
99 if (generationId.compareTo(MAX_GENERATION_ID) < 0) {
100 return generationId.add(BigInteger.ONE);
102 return BigInteger.ZERO;