2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017-2018 Amdocs
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
21 package org.onap.crud.dao.champ;
23 import java.nio.charset.Charset;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
31 import javax.ws.rs.core.MediaType;
32 import javax.ws.rs.core.Response;
33 import org.apache.http.NameValuePair;
34 import org.apache.http.client.utils.URLEncodedUtils;
35 import org.apache.http.message.BasicNameValuePair;
36 import org.eclipse.jetty.util.security.Password;
37 import org.onap.aai.cl.mdc.MdcContext;
38 import org.onap.aai.restclient.client.OperationResult;
39 import org.onap.aai.restclient.client.RestClient;
40 import org.onap.aai.restclient.enums.RestAuthenticationMode;
41 import org.onap.crud.dao.GraphDao;
42 import org.onap.crud.entity.Edge;
43 import org.onap.crud.entity.Vertex;
44 import org.onap.crud.exception.CrudException;
45 import org.onap.crud.util.CrudServiceConstants;
47 import com.google.gson.Gson;
48 import com.google.gson.GsonBuilder;
49 import com.google.gson.reflect.TypeToken;
50 import net.dongliu.gson.GsonJava8TypeAdapterFactory;
52 public class ChampDao implements GraphDao {
53 protected RestClient client;
54 protected String baseObjectUrl;
55 protected String baseRelationshipUrl;
56 protected String baseTransactionUrl;
57 protected String baseBulkUrl;
59 protected static final String HEADER_FROM_APP = "X-FromAppId";
60 protected static final String HEADER_TRANS_ID = "X-TransactionId";
61 protected static final String FROM_APP_NAME = "Gizmo";
62 protected static final String OBJECT_SUB_URL = "objects";
63 protected static final String RELATIONSHIP_SUB_URL = "relationships";
64 protected static final String TRANSACTION_SUB_URL = "transaction";
65 protected static final String BULK_SUB_URL = "bulk";
67 // We use a custom vertex serializer for champ because it expects "key"
69 protected static final Gson champGson = new GsonBuilder()
70 .registerTypeAdapterFactory(new GsonJava8TypeAdapterFactory())
71 .registerTypeAdapter(Vertex.class, new ChampVertexSerializer())
72 .registerTypeAdapter(Edge.class, new ChampEdgeSerializer()).create();
77 public ChampDao(String champUrl, String certPassword) {
79 String deobfuscatedCertPassword = certPassword.startsWith("OBF:")?Password.deobfuscate(certPassword):certPassword;
80 client = new RestClient().authenticationMode(RestAuthenticationMode.SSL_CERT).validateServerHostname(false)
81 .validateServerCertChain(false).clientCertFile(CrudServiceConstants.CRD_CHAMP_AUTH_FILE)
82 .clientCertPassword(deobfuscatedCertPassword);
84 baseObjectUrl = champUrl + OBJECT_SUB_URL;
85 baseRelationshipUrl = champUrl + RELATIONSHIP_SUB_URL;
86 baseTransactionUrl = champUrl + TRANSACTION_SUB_URL;
87 baseBulkUrl = champUrl + BULK_SUB_URL;
88 } catch (Exception e) {
89 System.out.println("Error setting up Champ configuration");
95 public ChampDao(RestClient client, String baseObjectUrl, String baseRelationshipUrl, String baseTransactionUrl) {
97 this.baseObjectUrl = baseObjectUrl;
98 this.baseRelationshipUrl = baseRelationshipUrl;
99 this.baseTransactionUrl = baseTransactionUrl;
103 public Vertex getVertex(String id, String version) throws CrudException {
104 String url = baseObjectUrl + "/" + id;
105 OperationResult getResult = client.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
107 if (getResult.getResultCode() == 200) {
108 return Vertex.fromJson(getResult.getResult(), version);
110 // We didn't find a vertex with the supplied id, so just throw an
112 throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No vertex with id " + id + " found in graph");
117 public OperationResult getVertex(String id, String type, String version, Map<String, String> queryParams) throws CrudException {
118 StringBuilder strBuild = new StringBuilder(baseObjectUrl);
119 strBuild.append("/");
121 if(queryParams != null && !queryParams.isEmpty())
123 strBuild.append("?");
124 strBuild.append(URLEncodedUtils.format(convertToNameValuePair(queryParams), Charset.defaultCharset()));
127 OperationResult getResult = client.get(strBuild.toString(), createHeader(), MediaType.APPLICATION_JSON_TYPE);
129 if (getResult.getResultCode() == 200) {
130 Vertex vert = Vertex.fromJson(getResult.getResult(), version);
132 if (!vert.getType().equalsIgnoreCase(type)) {
133 // We didn't find a vertex with the supplied type, so just throw an
135 throw new CrudException("No vertex with id " + id + " and type " + type + " found in graph",
136 javax.ws.rs.core.Response.Status.NOT_FOUND);
140 // We didn't find a vertex with the supplied id, so just throw an
142 throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No vertex with id " + id + " found in graph");
147 public List<Edge> getVertexEdges(String id, Map<String, String> queryParams, String txId) throws CrudException {
148 StringBuilder strBuild = new StringBuilder(baseObjectUrl);
149 strBuild.append("/relationships/");
152 Map<String,String> queryParamsCopy = null;
153 if (queryParams != null) {
154 queryParamsCopy = new HashMap<String,String>(queryParams);
157 queryParamsCopy = new HashMap<String,String>();
161 queryParamsCopy.put("transactionId", txId);
164 if (!queryParamsCopy.isEmpty())
166 strBuild.append("?");
167 strBuild.append(URLEncodedUtils.format(convertToNameValuePair(queryParamsCopy), Charset.defaultCharset()));
170 OperationResult getResult = client.get(strBuild.toString(), createHeader(), MediaType.APPLICATION_JSON_TYPE);
172 if (getResult.getResultCode() == 200) {
173 return champGson.fromJson(getResult.getResult(), new TypeToken<List<Edge>>() {
176 // We didn't find a vertex with the supplied id, so just throw an
178 throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No vertex with id " + id + " found in graph");
183 public OperationResult getVertices(String type, Map<String, Object> filter, String version) throws CrudException {
184 return getVertices(type, filter, new HashSet<String>(), version);
188 public OperationResult getVertices(String type, Map<String, Object> filter, Set<String> properties, String version) throws CrudException {
189 filter.put(org.onap.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName(), type);
191 List<NameValuePair> queryParams = convertToNameValuePair(filter);
192 queryParams.addAll(convertToNameValuePair("properties", properties));
193 String url = baseObjectUrl + "/filter" + "?"
194 + URLEncodedUtils.format(queryParams, Charset.defaultCharset());
196 OperationResult getResult = client.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
198 if (getResult.getResultCode() == 200) {
201 // We didn't find a vertex with the supplied id, so just throw an
203 throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No vertices found in graph for given filters");
208 public OperationResult getEdge(String id, String type, Map<String, String> queryParams) throws CrudException {
209 StringBuilder strBuild = new StringBuilder(baseRelationshipUrl);
210 strBuild.append("/");
212 if(queryParams != null && !queryParams.isEmpty())
214 strBuild.append("?");
215 strBuild.append(URLEncodedUtils.format(convertToNameValuePair(queryParams), Charset.defaultCharset()));
217 OperationResult getResult = client.get(strBuild.toString(), createHeader(), MediaType.APPLICATION_JSON_TYPE);
219 if (getResult.getResultCode() == 200) {
220 Edge edge = Edge.fromJson(getResult.getResult());
222 if (!edge.getType().equalsIgnoreCase(type)) {
223 // We didn't find an edge with the supplied type, so just throw an
225 throw new CrudException("No edge with id " + id + " and type " + type + " found in graph",
226 javax.ws.rs.core.Response.Status.NOT_FOUND);
230 // We didn't find a edge with the supplied type, so just throw an
232 throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No edge with id " + id + " found in graph");
237 public OperationResult getEdges(String type, Map<String, Object> filter) throws CrudException {
238 String url = baseRelationshipUrl + "/filter" + "?"
239 + URLEncodedUtils.format(convertToNameValuePair(filter), Charset.defaultCharset());
241 OperationResult getResult = client.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
243 if (getResult.getResultCode() == 200) {
246 // We didn't find a vertex with the supplied id, so just throw an
248 throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No edges found in graph for given filters");
253 public OperationResult addVertex(String type, Map<String, Object> properties, String version) throws CrudException {
254 String url = baseObjectUrl;
256 // Add the aai_node_type so that AAI can read the data created by gizmo
257 // TODO: This probably shouldn't be here
258 properties.put(org.onap.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName(), type);
260 Vertex.Builder insertVertexBuilder = new Vertex.Builder(type);
261 properties.forEach(insertVertexBuilder::property);
262 Vertex insertVertex = insertVertexBuilder.build();
264 OperationResult getResult = client.post(url, insertVertex.toJson(), createHeader(), MediaType.APPLICATION_JSON_TYPE,
265 MediaType.APPLICATION_JSON_TYPE);
267 if (getResult.getResultCode() == Response.Status.CREATED.getStatusCode()) {
270 // We didn't create a vertex with the supplied type, so just throw an
272 throw new CrudException("Failed to create vertex: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
277 public OperationResult updateVertex(String id, String type, Map<String, Object> properties, String version) throws CrudException {
278 String url = baseObjectUrl + "/" + id;
280 // Add the aai_node_type so that AAI can read the data created by gizmo
281 // TODO: This probably shouldn't be here
282 properties.put(org.onap.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName(), type);
284 Vertex.Builder insertVertexBuilder = new Vertex.Builder(type);
285 insertVertexBuilder.id(id);
286 properties.forEach(insertVertexBuilder::property);
287 Vertex insertVertex = insertVertexBuilder.build();
289 String payload = insertVertex.toJson(champGson);
290 OperationResult getResult = client.put(url, payload, createHeader(), MediaType.APPLICATION_JSON_TYPE,
291 MediaType.APPLICATION_JSON_TYPE);
293 if (getResult.getResultCode() == Response.Status.OK.getStatusCode()) {
296 // We didn't create a vertex with the supplied type, so just throw an
298 throw new CrudException("Failed to update vertex: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
303 public void deleteVertex(String id, String type) throws CrudException {
304 String url = baseObjectUrl + "/" + id;
305 OperationResult getResult = client.delete(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
307 if (getResult.getResultCode() != Response.Status.OK.getStatusCode()) {
308 // We didn't delete a vertex with the supplied id, so just throw an
310 throw new CrudException("Failed to delete vertex: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
315 public OperationResult addEdge(String type, Vertex source, Vertex target, Map<String, Object> properties, String version) throws CrudException {
316 String url = baseRelationshipUrl;
318 // Try requests to ensure source and target exist in Champ
319 OperationResult dbSourceOpResult = getVertex(source.getId().get(), source.getType(), version, new HashMap<String, String>());
320 Vertex dbSource = Vertex.fromJson(dbSourceOpResult.getResult(), version);
321 OperationResult dbTargetOpResult = getVertex(target.getId().get(), target.getType(), version, new HashMap<String, String>());
322 Vertex dbTarget = Vertex.fromJson(dbTargetOpResult.getResult(), version);
324 Edge.Builder insertEdgeBuilder = new Edge.Builder(type).source(dbSource).target(dbTarget);
325 properties.forEach(insertEdgeBuilder::property);
326 Edge insertEdge = insertEdgeBuilder.build();
328 String edgeJson = insertEdge.toJson(champGson);
329 OperationResult getResult = client.post(url, edgeJson, createHeader(), MediaType.APPLICATION_JSON_TYPE,
330 MediaType.APPLICATION_JSON_TYPE);
332 if (getResult.getResultCode() == Response.Status.CREATED.getStatusCode()) {
335 // We didn't create an edge with the supplied type, so just throw an
337 throw new CrudException("Failed to create edge: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
342 public OperationResult updateEdge(Edge edge) throws CrudException {
343 if (!edge.getId().isPresent()) {
344 throw new CrudException("Unable to identify edge: " + edge.toString(), Response.Status.BAD_REQUEST);
346 String url = baseRelationshipUrl + "/" + edge.getId().get();
348 String edgeJson = edge.toJson(champGson);
349 OperationResult getResult = client.put(url, edgeJson, createHeader(), MediaType.APPLICATION_JSON_TYPE,
350 MediaType.APPLICATION_JSON_TYPE);
352 if (getResult.getResultCode() == Response.Status.OK.getStatusCode()) {
355 // We didn't create an edge with the supplied type, so just throw an
357 throw new CrudException("Failed to update edge: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
362 public void deleteEdge(String id) throws CrudException {
363 String url = baseRelationshipUrl + "/" + id;
364 OperationResult getResult = client.delete(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
366 if (getResult.getResultCode() != 200) {
367 // We didn't find an edge with the supplied type, so just throw an
369 throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No edge with id " + id + " found in graph");
374 public String openTransaction() {
375 String url = baseTransactionUrl;
377 OperationResult getResult = client.post(url, "", createHeader(), MediaType.TEXT_PLAIN_TYPE, MediaType.TEXT_PLAIN_TYPE);
379 if (getResult.getResultCode() == 200) {
380 return getResult.getResult();
387 public void commitTransaction(String id) throws CrudException {
388 String url = baseTransactionUrl + "/" + id;
390 OperationResult getResult = client.put(url, "{\"method\": \"commit\"}", createHeader(), MediaType.APPLICATION_JSON_TYPE,
391 MediaType.TEXT_PLAIN_TYPE);
393 if (getResult.getResultCode() != 200) {
394 throw new CrudException("Unable to commit transaction",
395 Response.Status.fromStatusCode(getResult.getResultCode()));
400 public void rollbackTransaction(String id) throws CrudException {
401 String url = baseTransactionUrl + "/" + id;
403 OperationResult getResult = client.put(url, "{\"method\": \"rollback\"}", createHeader(), MediaType.APPLICATION_JSON_TYPE,
404 MediaType.TEXT_PLAIN_TYPE);
406 if (getResult.getResultCode() != 200) {
407 throw new CrudException("Unable to rollback transaction",
408 Response.Status.fromStatusCode(getResult.getResultCode()));
413 public boolean transactionExists(String id) throws CrudException {
414 String url = baseTransactionUrl + "/" + id;
415 Map<String, List<String>> headers = new HashMap<>();
416 headers.put(HEADER_FROM_APP, Arrays.asList("Gizmo"));
417 headers.put(HEADER_TRANS_ID, Arrays.asList(MDC.get(MdcContext.MDC_REQUEST_ID)));
419 OperationResult getResult = client.get(url, headers, MediaType.APPLICATION_JSON_TYPE);
421 return getResult.getResultCode() == 200;
425 public Vertex addVertex(String type, Map<String, Object> properties, String version, String txId) throws CrudException {
426 String url = baseObjectUrl + "?transactionId=" + txId;
428 // Add the aai_node_type so that AAI can read the data created by gizmo
429 // TODO: This probably shouldn't be here
430 properties.put(org.onap.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName(), type);
432 Vertex.Builder insertVertexBuilder = new Vertex.Builder(type);
433 properties.forEach(insertVertexBuilder::property);
434 Vertex insertVertex = insertVertexBuilder.build();
436 OperationResult getResult = client.post(url, insertVertex.toJson(), createHeader(), MediaType.APPLICATION_JSON_TYPE,
437 MediaType.APPLICATION_JSON_TYPE);
439 if (getResult.getResultCode() == Response.Status.CREATED.getStatusCode()) {
440 return Vertex.fromJson(getResult.getResult(), version);
442 // We didn't create a vertex with the supplied type, so just throw an
444 throw new CrudException("Failed to create vertex: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
449 public Edge addEdge(String type, Vertex source, Vertex target, Map<String, Object> properties, String version, String txId)
450 throws CrudException {
451 String url = baseRelationshipUrl + "?transactionId=" + txId;
453 // Try requests to ensure source and target exist in Champ
454 Vertex dbSource = getVertex(source.getId().get(), source.getType(), version, txId);
455 Vertex dbTarget = getVertex(target.getId().get(), target.getType(), version, txId);
457 Edge.Builder insertEdgeBuilder = new Edge.Builder(type).source(dbSource).target(dbTarget);
458 properties.forEach(insertEdgeBuilder::property);
459 Edge insertEdge = insertEdgeBuilder.build();
461 OperationResult getResult = client.post(url, insertEdge.toJson(champGson), createHeader(),
462 MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON_TYPE);
464 if (getResult.getResultCode() == Response.Status.CREATED.getStatusCode()) {
465 return Edge.fromJson(getResult.getResult());
467 // We didn't create an edge with the supplied type, so just throw an
469 throw new CrudException("Failed to create edge: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
474 public Vertex updateVertex(String id, String type, Map<String, Object> properties, String version, String txId) throws CrudException {
475 String url = baseObjectUrl + "/" + id + "?transactionId=" + txId;
477 // Add the aai_node_type so that AAI can read the data created by gizmo
478 // TODO: This probably shouldn't be here
479 properties.put(org.onap.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName(), type);
481 Vertex.Builder insertVertexBuilder = new Vertex.Builder(type);
482 insertVertexBuilder.id(id);
483 properties.forEach(insertVertexBuilder::property);
484 Vertex insertVertex = insertVertexBuilder.build();
486 String payload = insertVertex.toJson(champGson);
487 OperationResult getResult = client.put(url, payload, createHeader(), MediaType.APPLICATION_JSON_TYPE,
488 MediaType.APPLICATION_JSON_TYPE);
490 if (getResult.getResultCode() == Response.Status.OK.getStatusCode()) {
491 return Vertex.fromJson(getResult.getResult(), version);
493 // We didn't create a vertex with the supplied type, so just throw an
495 throw new CrudException("Failed to update vertex: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
500 public void deleteVertex(String id, String type, String txId) throws CrudException {
501 String url = baseObjectUrl + "/" + id + "?transactionId=" + txId;
502 OperationResult getResult = client.delete(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
504 if (getResult.getResultCode() != Response.Status.OK.getStatusCode()) {
505 // We didn't delete a vertex with the supplied id, so just throw an
507 throw new CrudException("Failed to delete vertex: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));
512 public Edge updateEdge(Edge edge, String txId) throws CrudException {
513 if (!edge.getId().isPresent()) {
514 throw new CrudException("Unable to identify edge: " + edge.toString(), Response.Status.BAD_REQUEST);
516 String url = baseRelationshipUrl + "/" + edge.getId().get() + "?transactionId=" + txId;
517 OperationResult getResult = client.put(url, edge.toJson(champGson), createHeader(), MediaType.APPLICATION_JSON_TYPE,
518 MediaType.APPLICATION_JSON_TYPE);
520 if (getResult.getResultCode() == Response.Status.OK.getStatusCode()) {
521 return Edge.fromJson(getResult.getResult());
523 // We didn't create an edge with the supplied type, so just throw an
525 throw new CrudException("Failed to update edge: " + getResult.getFailureCause(),
526 Response.Status.fromStatusCode(getResult.getResultCode()));
531 public void deleteEdge(String id, String txId) throws CrudException {
532 String url = baseRelationshipUrl + "/" + id + "?transactionId=" + txId;
533 OperationResult getResult = client.delete(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
535 if (getResult.getResultCode() != 200) {
536 // We didn't find an edge with the supplied type, so just throw an
538 throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No edge with id " + id + " found in graph");
543 public Edge getEdge(String id, String txId) throws CrudException {
544 String url = baseRelationshipUrl + "/" + id + "?transactionId=" + txId;
545 OperationResult getResult = client.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
547 if (getResult.getResultCode() == 200) {
548 Edge edge = Edge.fromJson(getResult.getResult());
551 // We didn't find an edge with the supplied id, so just throw an
553 throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No edge with id " + id + " found in graph");
558 public Edge getEdge(String id) throws CrudException {
559 String url = baseRelationshipUrl + "/" + id;
560 OperationResult getResult = client.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
562 if (getResult.getResultCode() == 200) {
563 Edge edge = Edge.fromJson(getResult.getResult());
566 // We didn't find an edge with the supplied id, so just throw an exception.
567 throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No edge with id " + id + " found in graph");
571 public Vertex getVertex(String id, String type, String version, String txId) throws CrudException {
572 String url = baseObjectUrl + "/" + id + "?transactionId=" + txId;
573 OperationResult getResult = client.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE);
575 if (getResult.getResultCode() == 200) {
576 Vertex vert = Vertex.fromJson(getResult.getResult(), version);
578 if (!vert.getType().equalsIgnoreCase(type)) {
579 // We didn't find a vertex with the supplied type, so just throw an
581 throw new CrudException("No vertex with id " + id + " and type " + type + " found in graph",
582 javax.ws.rs.core.Response.Status.NOT_FOUND);
586 // We didn't find a vertex with the supplied id, so just throw an
588 throw createErrorException(getResult, javax.ws.rs.core.Response.Status.NOT_FOUND, "No vertex with id " + id + " found in graph");
592 // https://stackoverflow.com/questions/26942330/convert-mapstring-string-to-listnamevaluepair-is-this-the-most-efficient
593 private List<NameValuePair> convertToNameValuePair(Map<String, ? super String> pairs) {
594 List<NameValuePair> nvpList = new ArrayList<>(pairs.size());
596 pairs.forEach((key, value) -> nvpList.add(new BasicNameValuePair(key, value.toString())));
601 // https://stackoverflow.com/questions/26942330/convert-mapstring-string-to-listnamevaluepair-is-this-the-most-efficient
602 private List<NameValuePair> convertToNameValuePair(String k, Set<String> values) {
603 List<NameValuePair> nvpList = new ArrayList<>(values.size());
605 values.forEach((v) -> nvpList.add(new BasicNameValuePair(k, v)));
610 private Map<String, List<String>> createHeader() {
611 Map<String, List<String>> headers = new HashMap<>();
612 headers.put(HEADER_FROM_APP, Arrays.asList(FROM_APP_NAME));
613 headers.put(HEADER_TRANS_ID, Arrays.asList(MDC.get(MdcContext.MDC_REQUEST_ID)));
617 private CrudException createErrorException(OperationResult result, javax.ws.rs.core.Response.Status defaultErrorCode , String defaultErrorMsg)
619 CrudException ce = null;
621 ce = new CrudException(result.getFailureCause(), Response.Status.fromStatusCode(result.getResultCode()));
623 ce = new CrudException(defaultErrorMsg, defaultErrorCode);
628 public OperationResult bulkOperation(ChampBulkPayload champPayload) throws CrudException {
629 String url = baseBulkUrl;
631 OperationResult getResult = client.post(url, champPayload.toJson(), createHeader(), MediaType.APPLICATION_JSON_TYPE,
632 MediaType.APPLICATION_JSON_TYPE);
634 if (getResult.getResultCode() == Response.Status.OK.getStatusCode()) {
637 throw new CrudException("Bulk request failed: " + getResult.getFailureCause(), Response.Status.fromStatusCode(getResult.getResultCode()));