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