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