--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
+import org.opendaylight.restconf.openapi.model.InfoEntity;
+import org.opendaylight.restconf.openapi.model.OpenApiEntity;
+
+public final class InfoStream extends InputStream {
+ private final InfoEntity entity;
+ private final OpenApiBodyWriter writer;
+
+ private Reader reader;
+
+ public InfoStream(final InfoEntity entity, final OpenApiBodyWriter writer) {
+ this.entity = entity;
+ this.writer = writer;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (reader == null) {
+ reader = new InputStreamReader(new ByteArrayInputStream(writeNextEntity(entity)), StandardCharsets.UTF_8);
+ }
+ return reader.read();
+ }
+
+ @Override
+ public int read(final byte[] array, final int off, final int len) throws IOException {
+ return super.read(array, off, len);
+ }
+
+ private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {
+ writer.writeTo(next, null, null, null, null, null, null);
+ return writer.readFrom();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.impl;
+
+import com.fasterxml.jackson.core.JsonFactoryBuilder;
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.List;
+import java.util.Map;
+import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
+import org.opendaylight.restconf.openapi.model.Info;
+import org.opendaylight.restconf.openapi.model.InfoEntity;
+import org.opendaylight.restconf.openapi.model.OpenApiVersionEntity;
+import org.opendaylight.restconf.openapi.model.Server;
+import org.opendaylight.restconf.openapi.model.ServerEntity;
+import org.opendaylight.restconf.openapi.model.ServersEntity;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+
+public final class OpenApiInputStream extends InputStream {
+ private final ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ private final JsonGenerator generator = new JsonFactoryBuilder().build().createGenerator(stream);
+ private final Deque<InputStream> stack = new ArrayDeque<>();
+
+ private Reader reader;
+
+ private boolean eof;
+
+ public OpenApiInputStream(final EffectiveModelContext context, final String openApiVersion, final Info info,
+ final List<Server> servers, final List<Map<String, List<String>>> security) throws IOException {
+ final OpenApiBodyWriter writer = new OpenApiBodyWriter(generator, stream);
+ stack.add(new OpenApiVersionStream(new OpenApiVersionEntity(), writer));
+ stack.add(new InfoStream(new InfoEntity(info.version(), info.title(), info.description()), writer));
+ stack.add(new ServersStream(new ServersEntity(
+ List.of(new ServerEntity(servers.iterator().next().url()))), writer));
+ stack.add(new PathsSteam(context, writer, generator, stream));
+ stack.add(new SchemasStream(context, writer, generator, stream));
+ stack.add(new SecurityStream(writer));
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (eof) {
+ return -1;
+ }
+ if (reader == null) {
+ generator.writeStartObject();
+ generator.flush();
+ reader = new InputStreamReader(new ByteArrayInputStream(stream.toByteArray()), StandardCharsets.UTF_8);
+ stream.reset();
+ }
+
+ var read = reader.read();
+ while (read == -1) {
+ if (stack.isEmpty()) {
+ generator.writeEndObject();
+ generator.flush();
+ reader = new InputStreamReader(new ByteArrayInputStream(stream.toByteArray()), StandardCharsets.UTF_8);
+ stream.reset();
+ eof = true;
+ return reader.read();
+ }
+ reader = new InputStreamReader(stack.pop(), StandardCharsets.UTF_8);
+ read = reader.read();
+ }
+
+ return read;
+ }
+
+ @Override
+ public int read(final byte[] array, final int off, final int len) throws IOException {
+ return super.read(array, off, len);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
+import org.opendaylight.restconf.openapi.model.OpenApiEntity;
+import org.opendaylight.restconf.openapi.model.OpenApiVersionEntity;
+
+public final class OpenApiVersionStream extends InputStream {
+ private final OpenApiVersionEntity entity;
+ private final OpenApiBodyWriter writer;
+
+ private Reader reader;
+
+ public OpenApiVersionStream(final OpenApiVersionEntity entity, final OpenApiBodyWriter writer) {
+ this.entity = entity;
+ this.writer = writer;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (reader == null) {
+ reader = new InputStreamReader(new ByteArrayInputStream(writeNextEntity(entity)), StandardCharsets.UTF_8);
+ }
+ return reader.read();
+ }
+
+ @Override
+ public int read(final byte[] array, final int off, final int len) throws IOException {
+ return super.read(array, off, len);
+ }
+
+ private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {
+ writer.writeTo(next, null, null, null, null, null, null);
+ return writer.readFrom();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech s.r.o and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.util.Deque;
+import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
+import org.opendaylight.restconf.openapi.model.OpenApiEntity;
+import org.opendaylight.restconf.openapi.model.PathEntity;
+
+public final class PathStream extends InputStream {
+ private final Deque<PathEntity> stack;
+ private final OpenApiBodyWriter writer;
+
+ private Reader reader;
+
+ public PathStream(final Deque<PathEntity> paths, final OpenApiBodyWriter writer) {
+ this.stack = paths;
+ this.writer = writer;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (reader == null) {
+ if (stack.isEmpty()) {
+ return -1;
+ }
+ reader = new InputStreamReader(new ByteArrayInputStream(writeNextEntity(stack.pop())),
+ StandardCharsets.UTF_8);
+ }
+
+ var read = reader.read();
+ while (read == -1) {
+ if (stack.isEmpty()) {
+ return -1;
+ }
+ reader = new InputStreamReader(new ByteArrayInputStream(writeNextEntity(stack.pop())),
+ StandardCharsets.UTF_8);
+ read = reader.read();
+ }
+
+ return read;
+ }
+
+ @Override
+ public int read(final byte[] array, final int off, final int len) throws IOException {
+ return super.read(array, off, len);
+ }
+
+ private byte[] writeNextEntity(final OpenApiEntity entity) throws IOException {
+ writer.writeTo(entity, null, null, null, null, null, null);
+ return writer.readFrom();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.impl;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Iterator;
+import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
+import org.opendaylight.restconf.openapi.model.PathEntity;
+import org.opendaylight.restconf.openapi.model.PostEntity;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.Module;
+
+public final class PathsSteam extends InputStream {
+ private final Iterator<? extends Module> iterator;
+ private final JsonGenerator generator;
+ private final OpenApiBodyWriter writer;
+ private final ByteArrayOutputStream stream;
+
+ private Reader reader;
+ private boolean eof;
+
+ public PathsSteam(final EffectiveModelContext context, final OpenApiBodyWriter writer,
+ final JsonGenerator generator, final ByteArrayOutputStream stream) {
+ iterator = context.getModules().iterator();
+ this.generator = generator;
+ this.writer = writer;
+ this.stream = stream;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (eof) {
+ return -1;
+ }
+ if (reader == null) {
+ generator.writeObjectFieldStart("paths");
+ generator.flush();
+ reader = new InputStreamReader(new ByteArrayInputStream(stream.toByteArray()), StandardCharsets.UTF_8);
+ stream.reset();
+ }
+
+ var read = reader.read();
+ while (read == -1) {
+ if (iterator.hasNext()) {
+ reader = new InputStreamReader(new PathStream(toPaths(iterator.next()), writer),
+ StandardCharsets.UTF_8);
+ read = reader.read();
+ continue;
+ }
+ generator.writeEndObject();
+ generator.flush();
+ reader = new InputStreamReader(new ByteArrayInputStream(stream.toByteArray()), StandardCharsets.UTF_8);
+ stream.reset();
+ eof = true;
+ return reader.read();
+ }
+
+ return read;
+ }
+
+ @Override
+ public int read(final byte[] array, final int off, final int len) throws IOException {
+ return super.read(array, off, len);
+ }
+
+ private static Deque<PathEntity> toPaths(final Module module) {
+ final var result = new ArrayDeque<PathEntity>();
+ // RPC operations (via post) - RPCs have their own path
+ for (final var rpc : module.getRpcs()) {
+ // TODO connect path with payload
+ final var post = new PostEntity(rpc, "controller", module.getName());
+ final String resolvedPath = "rests/operations/" + "/" + module.getName() + ":"
+ + rpc.getQName().getLocalName();
+ final var entity = new PathEntity(resolvedPath, post);
+ result.add(entity);
+ }
+
+ /**
+ * TODO
+ * for (final var container : module.getChildNodes()) {
+ * // get
+ * // post
+ * // put
+ * // patch
+ * // delete
+ *
+ * // add path into deque
+ * }
+ */
+ return result;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.util.Deque;
+import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
+import org.opendaylight.restconf.openapi.model.OpenApiEntity;
+import org.opendaylight.restconf.openapi.model.SchemaEntity;
+
+public final class SchemaStream extends InputStream {
+ private final Deque<SchemaEntity> stack;
+ private final OpenApiBodyWriter writer;
+
+ private Reader reader;
+
+ public SchemaStream(final Deque<SchemaEntity> schemas, final OpenApiBodyWriter writer) {
+ this.stack = schemas;
+ this.writer = writer;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (reader == null) {
+ if (stack.isEmpty()) {
+ return -1;
+ }
+ reader = new InputStreamReader(new ByteArrayInputStream(writeNextEntity(stack.pop())),
+ StandardCharsets.UTF_8);
+ }
+
+ var read = reader.read();
+ while (read == -1) {
+ if (stack.isEmpty()) {
+ return -1;
+ }
+ reader = new InputStreamReader(new ByteArrayInputStream(writeNextEntity(stack.pop())),
+ StandardCharsets.UTF_8);
+ read = reader.read();
+ }
+
+ return read;
+ }
+
+ @Override
+ public int read(final byte[] array, final int off, final int len) throws IOException {
+ return super.read(array, off, len);
+ }
+
+ private byte[] writeNextEntity(final OpenApiEntity entity) throws IOException {
+ writer.writeTo(entity, null, null, null, null, null, null);
+ return writer.readFrom();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.impl;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Iterator;
+import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
+import org.opendaylight.restconf.openapi.model.SchemaEntity;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.Module;
+
+public final class SchemasStream extends InputStream {
+ private final Iterator<? extends Module> iterator;
+ private final OpenApiBodyWriter writer;
+ private final JsonGenerator generator;
+ private final ByteArrayOutputStream stream;
+
+ private Reader reader;
+ private boolean schemesWritten;
+ private boolean eof;
+ private boolean eos;
+
+ public SchemasStream(final EffectiveModelContext context, final OpenApiBodyWriter writer,
+ final JsonGenerator generator, final ByteArrayOutputStream stream) {
+ iterator = context.getModules().iterator();
+ this.writer = writer;
+ this.generator = generator;
+ this.stream = stream;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (reader == null) {
+ generator.writeObjectFieldStart("components");
+ generator.writeObjectFieldStart("schemas");
+ generator.flush();
+ reader = new InputStreamReader(new ByteArrayInputStream(stream.toByteArray()), StandardCharsets.UTF_8);
+ stream.reset();
+ }
+ if (eof) {
+ return -1;
+ }
+ if (eos) {
+ eof = true;
+ return reader.read();
+ }
+
+ var read = reader.read();
+ while (read == -1) {
+ if (iterator.hasNext()) {
+ reader = new InputStreamReader(new SchemaStream(toComponents(iterator.next()), writer),
+ StandardCharsets.UTF_8);
+ read = reader.read();
+ continue;
+ }
+ if (!schemesWritten) {
+ reader = new InputStreamReader(new SecuritySchemesStream(writer), StandardCharsets.UTF_8);
+ read = reader.read();
+ schemesWritten = true;
+ continue;
+ }
+ generator.writeEndObject();
+ generator.writeEndObject();
+ generator.flush();
+ reader = new InputStreamReader(new ByteArrayInputStream(stream.toByteArray()), StandardCharsets.UTF_8);
+ stream.reset();
+ eos = true;
+ return reader.read();
+ }
+
+ return read;
+ }
+
+ @Override
+ public int read(final byte[] array, final int off, final int len) throws IOException {
+ return super.read(array, off, len);
+ }
+
+ private static Deque<SchemaEntity> toComponents(final Module module) {
+ final var result = new ArrayDeque<SchemaEntity>();
+ for (final var rpc : module.getRpcs()) {
+ final var moduleName = module.getName();
+ final var rpcName = rpc.getQName().getLocalName();
+ final var input = new SchemaEntity(rpc.getInput(), moduleName + "_" + rpcName + "_input", "object");
+ result.add(input);
+ final var output = new SchemaEntity(rpc.getOutput(), moduleName + "_" + rpcName + "_output", "object");
+ result.add(output);
+ }
+
+ // actions
+ // child nodes
+ // etc.
+ return result;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
+
+public final class SecuritySchemesStream extends InputStream {
+ public SecuritySchemesStream(final OpenApiBodyWriter writer) {
+ }
+
+ @Override
+ public int read() throws IOException {
+ return -1;
+ }
+
+ @Override
+ public int read(final byte[] array, final int off, final int len) throws IOException {
+ return super.read(array, off, len);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
+
+public final class SecurityStream extends InputStream {
+ public SecurityStream(final OpenApiBodyWriter writer) {
+ }
+
+ @Override
+ public int read() throws IOException {
+ return -1;
+ }
+
+ @Override
+ public int read(final byte[] array, final int off, final int len) throws IOException {
+ return super.read(array, off, len);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
+import org.opendaylight.restconf.openapi.model.OpenApiEntity;
+import org.opendaylight.restconf.openapi.model.ServersEntity;
+
+public final class ServersStream extends InputStream {
+ private ServersEntity entity;
+ private OpenApiBodyWriter writer;
+
+ private Reader reader;
+
+ public ServersStream(final ServersEntity entity, final OpenApiBodyWriter writer) {
+ this.entity = entity;
+ this.writer = writer;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (reader == null) {
+ reader = new InputStreamReader(new ByteArrayInputStream(writeNextEntity(entity)), StandardCharsets.UTF_8);
+ }
+ return reader.read();
+ }
+
+ @Override
+ public int read(final byte[] array, final int off, final int len) throws IOException {
+ return super.read(array, off, len);
+ }
+
+ private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {
+ writer.writeTo(next, null, null, null, null, null, null);
+ return writer.readFrom();
+ }
+}
*/
package org.opendaylight.restconf.openapi.jaxrs;
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonFactoryBuilder;
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
@Provider
@Produces(MediaType.APPLICATION_JSON)
public final class OpenApiBodyWriter implements MessageBodyWriter<OpenApiEntity> {
- private final JsonFactory factory = new JsonFactoryBuilder().build();
+ private final JsonGenerator generator;
+ private final ByteArrayOutputStream stream;
+
+ public OpenApiBodyWriter(final JsonGenerator generator, final ByteArrayOutputStream stream) {
+ this.generator = generator;
+ this.stream = stream;
+ }
@Override
public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations,
return OpenApiEntity.class.isAssignableFrom(type);
}
+ // TODO IMO we can get rid of implementing MessageBodyWriter
@Override
public void writeTo(final OpenApiEntity entity, final Class<?> type, final Type genericType,
final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap<String, Object> httpHeaders,
final OutputStream entityStream) throws IOException {
- try (var generator = factory.createGenerator(entityStream)) {
- entity.generate(generator);
- }
+ entity.generate(generator);
+ generator.flush();
+ }
+
+ public byte[] readFrom() {
+ final var bytes = stream.toByteArray();
+ stream.reset();
+ return bytes;
}
}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.model;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
+
+/**
+ * TODO use this class to simplify SchemasStream.
+ */
+public final class ComponentsEntity extends OpenApiEntity {
+
+ @Override
+ public void generate(final JsonGenerator generator) throws IOException {
+ generator.writeObjectFieldStart("components");
+ generator.writeEndObject();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.model;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
+import org.eclipse.jdt.annotation.NonNull;
+
+public final class InfoEntity extends OpenApiEntity {
+ private final String version;
+ private final String title;
+ private final String description;
+
+ public InfoEntity(final String version, final String title, final String description) {
+ this.version = version;
+ this.title = title;
+ this.description = description;
+ }
+
+ @Override
+ public void generate(@NonNull JsonGenerator generator) throws IOException {
+ generator.writeObjectFieldStart("info");
+ if (version != null) {
+ generator.writeStringField("version", version);
+ }
+ if (title != null) {
+ generator.writeStringField("title", title);
+ }
+ if (description != null) {
+ generator.writeStringField("description", description);
+ }
+ generator.writeEndObject();
+ }
+}
/**
* A response entity for complex generated type.
*/
-public abstract sealed class OpenApiEntity permits SchemaEntity {
+public abstract sealed class OpenApiEntity permits SchemaEntity, ComponentsEntity, InfoEntity, OpenApiVersionEntity,
+ OperationEntity, PathEntity, PathsEntity, ServerEntity, ServersEntity {
/**
* Generate JSON events into specified generator.
*
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech s.r.o and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.model;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
+import org.eclipse.jdt.annotation.NonNull;
+
+public final class OpenApiVersionEntity extends OpenApiEntity {
+ @Override
+ public void generate(@NonNull JsonGenerator generator) throws IOException {
+ generator.writeStringField("openapi", "3.0.3");
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.model;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.OperationDefinition;
+
+/**
+ * Archetype for an Operation.
+ */
+public abstract sealed class OperationEntity extends OpenApiEntity permits PostEntity {
+ private final OperationDefinition schema;
+ private final String deviceName;
+ private final String moduleName;
+
+ protected OperationDefinition schema() {
+ return schema;
+ }
+
+ protected String deviceName() {
+ return deviceName;
+ }
+
+ protected String moduleName() {
+ return moduleName;
+ }
+
+ public OperationEntity(final OperationDefinition schema, final String deviceName, final String moduleName) {
+ this.schema = schema;
+ this.deviceName = deviceName;
+ this.moduleName = moduleName;
+ }
+
+ @Override
+ public void generate(@NonNull JsonGenerator generator) throws IOException {
+ generator.writeObjectFieldStart(operation());
+ final var deprecated = deprecated();
+ if (deprecated != null) {
+ generator.writeBooleanField("deprecated", deprecated);
+ }
+ final var description = description();
+ if (description != null) {
+ generator.writeStringField("description", description);
+ }
+ final var summary = summary();
+ if (summary != null) {
+ generator.writeStringField("summary", summary);
+ }
+ generator.writeEndObject();
+ }
+
+ protected abstract String operation();
+
+ @Nullable Boolean deprecated() {
+ return Boolean.FALSE;
+ }
+
+ @Nullable String description() {
+ return null;
+ }
+
+ @Nullable abstract String summary();
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech s.r.o and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.model;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
+import java.util.Objects;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+
+public final class PathEntity extends OpenApiEntity {
+ private final @NonNull String path;
+ private final @Nullable OperationEntity post;
+
+ public PathEntity(final String path, final OperationEntity post) {
+ this.path = Objects.requireNonNull(path);
+ this.post = post;
+ }
+
+ @Override
+ public void generate(@NonNull JsonGenerator generator) throws IOException {
+ generator.writeObjectFieldStart(path);
+ final var ref = ref();
+ if (ref != null) {
+ generator.writeStringField("$ref", ref);
+ }
+ final var summary = summary();
+ if (summary != null) {
+ generator.writeStringField("summary", summary);
+ }
+ final var description = description();
+ if (ref != null) {
+ generator.writeStringField("description", description);
+ }
+ final var postOperation = post();
+ if (postOperation != null) {
+ postOperation.generate(generator);
+ }
+ final var putOperation = put();
+ if (putOperation != null) {
+ putOperation.generate(generator);
+ }
+ final var patchOperation = patch();
+ if (patchOperation != null) {
+ patchOperation.generate(generator);
+ }
+ generator.writeEndObject();
+ }
+
+ @Nullable String ref() {
+ return null;
+ }
+
+ @Nullable String summary() {
+ return null;
+ }
+
+ @Nullable String description() {
+ return null;
+ }
+
+ @Nullable OperationEntity post() {
+ return post;
+ }
+
+ @Nullable OperationEntity put() {
+ return null;
+ }
+
+ @Nullable OperationEntity patch() {
+ return null;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.model;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
+
+/**
+ * TODO use this class to simplify PathsStream.
+ */
+public final class PathsEntity extends OpenApiEntity {
+
+ @Override
+ public void generate(final JsonGenerator generator) throws IOException {
+ generator.writeObjectFieldStart("paths");
+ generator.writeEndObject();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.model;
+
+import javax.ws.rs.HttpMethod;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.OperationDefinition;
+
+public final class PostEntity extends OperationEntity {
+ private static final String SUMMARY_TEMPLATE = "%s - %s - %s - %s";
+ private static final String INPUT_SUFFIX = "_input";
+
+ public PostEntity(final OperationDefinition schema, final String deviceName, final String moduleName) {
+ super(schema, deviceName, moduleName);
+ }
+
+ protected String operation() {
+ return "post";
+ }
+
+ @Nullable String summary() {
+ final var operationName = schema().getQName().getLocalName() + INPUT_SUFFIX;
+ return SUMMARY_TEMPLATE.formatted(HttpMethod.POST, deviceName(), moduleName(), operationName);
+ }
+}
import java.io.IOException;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
/**
* Archetype for a Schema.
*/
public final class SchemaEntity extends OpenApiEntity {
+ private final @NonNull SchemaNode value;
private final @NonNull String title;
private final @NonNull String type;
- public SchemaEntity(final @NonNull String title, final @NonNull String type) {
+ public SchemaEntity(final @NonNull SchemaNode value, final @NonNull String title, @NonNull final String type) {
+ this.value = requireNonNull(value);
this.title = requireNonNull(title);
this.type = requireNonNull(type);
}
}
private @Nullable String description() {
- return null;
+ return value.getDescription().orElse(null);
}
private @Nullable String reference() {
--- /dev/null
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.model;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
+import org.eclipse.jdt.annotation.NonNull;
+
+public final class ServerEntity extends OpenApiEntity {
+ private final String url;
+
+ public ServerEntity(final String url) {
+ this.url = url;
+ }
+
+ @Override
+ public void generate(@NonNull final JsonGenerator generator) throws IOException {
+ if (url != null) {
+ generator.writeStartObject();
+ generator.writeStringField("url", url);
+ generator.writeEndObject();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.model;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
+import java.util.List;
+import org.eclipse.jdt.annotation.NonNull;
+
+public final class ServersEntity extends OpenApiEntity {
+ private final List<ServerEntity> servers;
+
+ public ServersEntity(final List<ServerEntity> servers) {
+ this.servers = servers;
+ }
+
+ @Override
+ public void generate(@NonNull final JsonGenerator generator) throws IOException {
+ generator.writeArrayFieldStart("servers");
+ for (final var server : servers) {
+ server.generate(generator);
+ }
+ generator.writeEndArray();
+ }
+}