2 * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. 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.openflowplugin.applications.southboundcli;
11 import com.google.common.util.concurrent.SettableFuture;
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.List;
16 import java.util.concurrent.ExecutionException;
17 import java.util.concurrent.Future;
18 import java.util.stream.Collectors;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.openflowplugin.applications.southboundcli.util.OFNode;
21 import org.opendaylight.openflowplugin.applications.southboundcli.util.ShellUtil;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.admin.reconciliation.service.rev180227.AdminReconciliationService;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.admin.reconciliation.service.rev180227.ExecReconciliationInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.admin.reconciliation.service.rev180227.ExecReconciliationOutput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.reconciliation.service.rev180227.InitReconciliationInput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.reconciliation.service.rev180227.InitReconciliationInputBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.reconciliation.service.rev180227.InitReconciliationOutput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.reconciliation.service.rev180227.ReconciliationService;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.opendaylight.yangtools.yang.common.RpcError;
36 import org.opendaylight.yangtools.yang.common.RpcResult;
37 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 public class AdminReconciliationServiceImpl implements AdminReconciliationService {
43 private static final Logger LOG = LoggerFactory.getLogger(AdminReconciliationServiceImpl.class);
44 private final DataBroker broker;
45 private final ReconciliationService reconciliationService;
47 public AdminReconciliationServiceImpl(DataBroker broker, ReconciliationService reconciliationService) {
49 this.reconciliationService = reconciliationService;
54 public Future<RpcResult<ExecReconciliationOutput>> execReconciliation(ExecReconciliationInput input) {
55 boolean reconcileAllNodes = input.isReconcileAllNodes();
56 List<BigInteger> inputNodes = input.getNodes();
57 if (inputNodes == null) {
58 inputNodes = new ArrayList<>();
60 if (reconcileAllNodes && inputNodes.size() > 0) {
61 return buildErrorResponse("Error executing command execReconciliation."
62 + "If 'all' option is enabled, no Node must be specified as input parameter.");
64 if (!reconcileAllNodes && inputNodes.size() == 0) {
65 return buildErrorResponse("Error executing command execReconciliation. No Node information was specified.");
67 SettableFuture<RpcResult<ExecReconciliationOutput>> result = SettableFuture.create();
68 List<Long> nodeList = getAllNodes();
69 List<Long> nodesToReconcile = reconcileAllNodes ? nodeList :
70 inputNodes.stream().distinct().map(node -> node.longValue()).collect(Collectors.toList());
71 if (nodesToReconcile.size() > 0) {
72 List<Long> unresolvedNodes =
73 nodesToReconcile.stream().filter(node -> !nodeList.contains(node)).collect(Collectors.toList());
74 if (!unresolvedNodes.isEmpty()) {
75 return buildErrorResponse("Node(s) not found: " + String.join(", ", unresolvedNodes.toString()));
77 for (Long nodeId : nodesToReconcile) {
78 LOG.info("Executing admin reconciliation for node {}", nodeId);
79 BigInteger node = new BigInteger(String.valueOf(nodeId));
80 NodeKey nodeKey = new NodeKey(new NodeId("openflow:" + nodeId));
81 InitReconciliationInput initReconInput = new InitReconciliationInputBuilder()
82 .setNodeId(node).setNode(new NodeRef(InstanceIdentifier.builder(Nodes.class)
83 .child(Node.class, nodeKey).build())).build();
84 Future<RpcResult<InitReconciliationOutput>> initReconOutput = reconciliationService
85 .initReconciliation(initReconInput);
87 RpcResult<InitReconciliationOutput> rpcResult = initReconOutput.get();
88 if (rpcResult.isSuccessful()) {
89 LOG.info("Reconciliation successfully completed for node {}", nodeId);
91 LOG.error("Reconciliation failed for node {} with error {}", nodeId, rpcResult.getErrors());
93 } catch (ExecutionException | InterruptedException e) {
94 LOG.error("Error occurred while invoking execReconciliation RPC for node {}", nodeId, e);
98 return buildErrorResponse("No node found");
100 result.set(RpcResultBuilder.<ExecReconciliationOutput>success().build());
104 private Future<RpcResult<ExecReconciliationOutput>> buildErrorResponse(String msg) {
105 SettableFuture<RpcResult<ExecReconciliationOutput>> result = SettableFuture.create();
107 RpcError error = RpcResultBuilder.newError(RpcError.ErrorType.PROTOCOL, "execReconciliation", msg);
108 List<RpcError> errors = Collections.singletonList(error);
109 result.set(RpcResultBuilder.<ExecReconciliationOutput>failed().withRpcErrors(errors).build());
113 public List<Long> getAllNodes() {
114 List<OFNode> nodeList = ShellUtil.getAllNodes(broker);
115 List<Long> nodes = nodeList.stream().distinct().map(node -> node.getNodeId()).collect(Collectors.toList());