2 * Copyright (c) 2021 PANTHEON.tech, s.r.o. 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
8 package org.opendaylight.restconf.server.api;
10 import static java.util.Objects.requireNonNull;
11 import static org.opendaylight.restconf.server.api.OperationsGetResultHelper.appendJSON;
12 import static org.opendaylight.restconf.server.api.OperationsGetResultHelper.appendXML;
13 import static org.opendaylight.restconf.server.api.OperationsGetResultHelper.jsonPrefix;
15 import com.google.common.base.MoreObjects;
16 import com.google.common.collect.ImmutableSetMultimap;
17 import java.util.Comparator;
19 import java.util.Map.Entry;
20 import org.eclipse.jdt.annotation.NonNull;
21 import org.opendaylight.yangtools.yang.common.QName;
22 import org.opendaylight.yangtools.yang.common.QNameModule;
23 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
26 * RESTCONF {@code /operations} content for a {@code GET} operation as per
27 * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-3.3.2">RFC8040</a>.
29 public sealed interface OperationsGetResult {
30 record Leaf(EffectiveModelContext modelContext, QName rpc) implements OperationsGetResult {
32 requireNonNull(modelContext);
37 public String toJSON() {
38 // https://www.rfc-editor.org/rfc/rfc8040#page-84:
40 // In JSON, the YANG module name identifies the module:
42 // { 'ietf-system:system-restart' : [null] }
43 return appendJSON(new StringBuilder("{ "), jsonPrefix(modelContext, rpc.getModule()), rpc).append(" }")
48 public String toXML() {
49 // https://www.rfc-editor.org/rfc/rfc8040#page-84:
51 // In XML, the YANG module namespace identifies the module:
54 // xmlns='urn:ietf:params:xml:ns:yang:ietf-system'/>
55 return appendXML(new StringBuilder(), rpc).toString();
59 public String toString() {
60 return MoreObjects.toStringHelper(this).add("rpc", rpc).toString();
64 record Container(EffectiveModelContext modelContext, ImmutableSetMultimap<QNameModule, QName> rpcs)
65 implements OperationsGetResult {
67 requireNonNull(modelContext);
72 public String toJSON() {
73 final var sb = new StringBuilder("""
75 "ietf-restconf:operations" : {\
78 if (!rpcs.isEmpty()) {
79 final var entryIt = rpcs.asMap().entrySet().stream()
80 .map(entry -> Map.entry(jsonPrefix(modelContext, entry.getKey()), entry.getValue()))
81 .sorted(Comparator.comparing(Entry::getKey))
83 var entry = entryIt.next();
84 var nameIt = entry.getValue().iterator();
86 appendJSON(sb.append("\n "), entry.getKey(), nameIt.next());
87 if (nameIt.hasNext()) {
92 if (entryIt.hasNext()) {
94 entry = entryIt.next();
95 nameIt = entry.getValue().iterator();
103 return sb.append("\n }\n}").toString();
107 public String toXML() {
108 // Header with namespace declarations for each module
109 final var sb = new StringBuilder("<operations xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\"");
110 if (rpcs.isEmpty()) {
111 return sb.append("/>").toString();
115 rpcs.asMap().entrySet().stream()
116 .sorted(Comparator.comparing(Entry::getKey))
117 .flatMap(entry -> entry.getValue().stream())
118 .forEach(rpc -> appendXML(sb.append("\n "), rpc));
119 return sb.append("\n</operations>").toString();
123 @NonNull String toJSON();
125 @NonNull String toXML();