5d2fd46ff68136f6a7f1af4858e57f7fc6344778
[netconf.git] / restconf / restconf-nb / src / main / java / org / opendaylight / restconf / nb / rfc8040 / jersey / providers / JsonPatchStatusBodyWriter.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. 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 package org.opendaylight.restconf.nb.rfc8040.jersey.providers;
9
10 import com.google.gson.stream.JsonWriter;
11 import java.io.IOException;
12 import java.io.OutputStream;
13 import java.lang.annotation.Annotation;
14 import java.lang.reflect.Type;
15 import java.util.List;
16 import javax.ws.rs.Produces;
17 import javax.ws.rs.core.MediaType;
18 import javax.ws.rs.core.MultivaluedMap;
19 import javax.ws.rs.ext.Provider;
20 import org.opendaylight.restconf.api.MediaTypes;
21 import org.opendaylight.restconf.api.query.PrettyPrintParam;
22 import org.opendaylight.restconf.common.errors.RestconfError;
23 import org.opendaylight.restconf.server.api.DatabindContext;
24 import org.opendaylight.restconf.server.api.PatchStatusContext;
25 import org.opendaylight.restconf.server.spi.FormattableBodySupport;
26
27 @Provider
28 @Produces(MediaTypes.APPLICATION_YANG_DATA_JSON)
29 public class JsonPatchStatusBodyWriter extends AbstractPatchStatusBodyWriter {
30     @Override
31     public void writeTo(final PatchStatusContext patchStatusContext, final Class<?> type, final Type genericType,
32             final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap<String, Object> httpHeaders,
33             final OutputStream entityStream) throws IOException {
34         final var jsonWriter = FormattableBodySupport.createJsonWriter(entityStream, () -> PrettyPrintParam.FALSE);
35         jsonWriter.beginObject().name("ietf-yang-patch:yang-patch-status")
36             .beginObject().name("patch-id").value(patchStatusContext.patchId());
37
38         if (patchStatusContext.ok()) {
39             reportSuccess(jsonWriter);
40         } else {
41             final var globalErrors = patchStatusContext.globalErrors();
42             if (globalErrors != null) {
43                 reportErrors(patchStatusContext.databind(), globalErrors, jsonWriter);
44             } else {
45                 jsonWriter.name("edit-status").beginObject()
46                     .name("edit").beginArray();
47                 for (var editStatus : patchStatusContext.editCollection()) {
48                     jsonWriter.beginObject().name("edit-id").value(editStatus.getEditId());
49
50                     final var editErrors = editStatus.getEditErrors();
51                     if (editErrors != null) {
52                         reportErrors(patchStatusContext.databind(), editErrors, jsonWriter);
53                     } else if (editStatus.isOk()) {
54                         reportSuccess(jsonWriter);
55                     }
56                     jsonWriter.endObject();
57                 }
58                 jsonWriter.endArray().endObject();
59             }
60         }
61         jsonWriter.endObject().endObject().flush();
62     }
63
64     private static void reportSuccess(final JsonWriter jsonWriter) throws IOException {
65         jsonWriter.name("ok").beginArray().nullValue().endArray();
66     }
67
68     private static void reportErrors(final DatabindContext databind, final List<RestconfError> errors,
69             final JsonWriter jsonWriter) throws IOException {
70         jsonWriter.name("errors").beginObject().name("error").beginArray();
71
72         for (var restconfError : errors) {
73             jsonWriter.beginObject()
74                 .name("error-type").value(restconfError.getErrorType().elementBody())
75                 .name("error-tag").value(restconfError.getErrorTag().elementBody());
76
77             final var errorPath = restconfError.getErrorPath();
78             if (errorPath != null) {
79                 jsonWriter.name("error-path");
80                 databind.jsonCodecs().instanceIdentifierCodec().writeValue(jsonWriter, errorPath);
81             }
82             final var errorMessage = restconfError.getErrorMessage();
83             if (errorMessage != null) {
84                 jsonWriter.name("error-message").value(errorMessage);
85             }
86             final var errorInfo = restconfError.getErrorInfo();
87             if (errorInfo != null) {
88                 jsonWriter.name("error-info").value(errorInfo);
89             }
90
91             jsonWriter.endObject();
92         }
93
94         jsonWriter.endArray().endObject();
95     }
96 }