Checkstyle fixes (to be enforced)
[ovsdb.git] / library / impl / src / main / java / org / opendaylight / ovsdb / lib / impl / FutureTransformUtils.java
1 /*
2  * Copyright (c) 2014, 2015 EBay Software Foundation 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
9 package org.opendaylight.ovsdb.lib.impl;
10
11 import com.fasterxml.jackson.databind.DeserializationFeature;
12 import com.fasterxml.jackson.databind.JsonNode;
13 import com.fasterxml.jackson.databind.ObjectMapper;
14 import com.google.common.base.Function;
15 import com.google.common.util.concurrent.Futures;
16 import com.google.common.util.concurrent.ListenableFuture;
17 import java.util.ArrayList;
18 import java.util.List;
19 import org.opendaylight.ovsdb.lib.operations.Operation;
20 import org.opendaylight.ovsdb.lib.operations.OperationResult;
21
22 public class FutureTransformUtils {
23     private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
24
25     private FutureTransformUtils() {
26     }
27
28     public static final ListenableFuture<List<OperationResult>> transformTransactResponse(
29             ListenableFuture<List<JsonNode>> transactResponseFuture, final List<Operation> operations) {
30         OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
31         return Futures.transform(transactResponseFuture, new Function<List<JsonNode>, List<OperationResult>>() {
32             @Override
33             public List<OperationResult> apply(List<JsonNode> jsonNodes) {
34                 final List<OperationResult> operationResults = new ArrayList<>();
35                 for (int index = 0; index < jsonNodes.size(); index++) {
36                     JsonNode jsonNode = jsonNodes.get(index);
37                     OperationResult or;
38                     if (jsonNode != null && jsonNode.size() > 0) {
39                         /*
40                          * As per RFC 7047, section 4.1.3 :
41                          * "In general, "result" contains some number of successful results,
42                          * possibly followed by an error, in turn followed by enough JSON null
43                          * values to match the number of elements in "params".  There is one
44                          * exception: if all of the operations succeed, but the results cannot
45                          * be committed, then "result" will have one more element than "params",
46                          * with the additional element being an <error>."
47                          *
48                          * Hence, it is possible for a transaction response to contain more
49                          * json elements than the transaction operation request.
50                          * Also handle that case by checking for i < operations.size().
51                          */
52                         if (index < operations.size()) {
53                             Operation op = operations.get(index);
54                             switch (op.getOp()) {
55                                 case "select":
56                                     or = new OperationResult();
57                                     or.setRows(op.getTableSchema().createRows(jsonNode));
58                                     break;
59
60                                 default:
61                                     or = OBJECT_MAPPER.convertValue(jsonNode, OperationResult.class);
62
63                                     break;
64                             }
65                         } else {
66                             or = OBJECT_MAPPER.convertValue(jsonNode, OperationResult.class);
67                         }
68                     } else {
69                         or = new OperationResult();
70                     }
71                     operationResults.add(or);
72                 }
73
74                 return operationResults;
75             }
76         });
77     }
78 }