Use nio Channels in OpenAPI read 03/109803/8
authorIvan Hrasko <ivan.hrasko@pantheon.tech>
Tue, 16 Jan 2024 14:49:54 +0000 (15:49 +0100)
committerIvan Hrasko <ivan.hrasko@pantheon.tech>
Mon, 29 Jan 2024 11:38:21 +0000 (12:38 +0100)
Override read(byte[], int, int) method using nio Channels
to speed up retrieval of documentation.

JIRA: NETCONF-1234
Change-Id: I3bfc4110cfe828302a08f86756c4535077fe5c5c
Signed-off-by: Ivan Hrasko <ivan.hrasko@pantheon.tech>
Signed-off-by: Yaroslav Lastivka <yaroslav.lastivka@pantheon.tech>
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/impl/ComponentsStream.java
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/impl/InfoStream.java
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/impl/OpenApiInputStream.java
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/impl/OpenApiVersionStream.java
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/impl/PathsStream.java
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/impl/SchemaStream.java
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/impl/SchemasStream.java
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/impl/SecuritySchemesStream.java
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/impl/SecurityStream.java
restconf/restconf-openapi/src/main/java/org/opendaylight/restconf/openapi/impl/ServersStream.java

index b3cbb31f193d13263145008821c96570f3646ab5..5b97b7b52faa3519cac5c45d048bba1bb2295582 100644 (file)
@@ -14,6 +14,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.StandardCharsets;
 import java.util.Iterator;
 import java.util.Map;
 import java.nio.charset.StandardCharsets;
 import java.util.Iterator;
 import java.util.Map;
@@ -36,6 +39,7 @@ public final class ComponentsStream extends InputStream {
     private boolean schemasWritten;
     private boolean securityWritten;
     private Reader reader;
     private boolean schemasWritten;
     private boolean securityWritten;
     private Reader reader;
+    private ReadableByteChannel channel;
 
     public ComponentsStream(final EffectiveModelContext context, final OpenApiBodyWriter writer,
         final JsonGenerator generator, final ByteArrayOutputStream stream,
 
     public ComponentsStream(final EffectiveModelContext context, final OpenApiBodyWriter writer,
         final JsonGenerator generator, final ByteArrayOutputStream stream,
@@ -84,6 +88,35 @@ public final class ComponentsStream extends InputStream {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
-        return super.read(array, off, len);
+        if (channel == null) {
+            generator.writeObjectFieldStart("components");
+            generator.flush();
+            channel = Channels.newChannel(new ByteArrayInputStream(stream.toByteArray()));
+            stream.reset();
+        }
+
+        var read = channel.read(ByteBuffer.wrap(array, off, len));
+        while (read == -1) {
+            if (!schemasWritten) {
+                channel = Channels.newChannel(new SchemasStream(context, writer, generator, stream, iterator,
+                    isForSingleModule));
+                read = channel.read(ByteBuffer.wrap(array));
+                schemasWritten = true;
+                continue;
+            }
+            if (!securityWritten) {
+                channel = Channels.newChannel(new SecuritySchemesStream(writer, Map.of(BASIC_AUTH_NAME,
+                    OPEN_API_BASIC_AUTH)));
+                read = channel.read(ByteBuffer.wrap(array, off, len));
+                securityWritten = true;
+                generator.writeEndObject();
+                continue;
+            }
+            generator.flush();
+            channel = Channels.newChannel(new ByteArrayInputStream(stream.toByteArray()));
+            stream.reset();
+            return channel.read(ByteBuffer.wrap(array, off, len));
+        }
+        return read;
     }
 }
     }
 }
index e41129f9f4aed47bb7d28c8601fae5d6575da577..50eac5752a5e4b2dbc142095f3d40511a5cf288a 100644 (file)
@@ -13,6 +13,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.StandardCharsets;
 import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
 import org.opendaylight.restconf.openapi.model.InfoEntity;
 import java.nio.charset.StandardCharsets;
 import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
 import org.opendaylight.restconf.openapi.model.InfoEntity;
@@ -23,6 +26,7 @@ public final class InfoStream extends InputStream {
     private final OpenApiBodyWriter writer;
 
     private Reader reader;
     private final OpenApiBodyWriter writer;
 
     private Reader reader;
+    private ReadableByteChannel channel;
 
     public InfoStream(final InfoEntity entity, final OpenApiBodyWriter writer) {
         this.entity = entity;
 
     public InfoStream(final InfoEntity entity, final OpenApiBodyWriter writer) {
         this.entity = entity;
@@ -40,7 +44,10 @@ public final class InfoStream extends InputStream {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
-        return super.read(array, off, len);
+        if (channel == null) {
+            channel = Channels.newChannel(new ByteArrayInputStream(writeNextEntity(entity)));
+        }
+        return channel.read(ByteBuffer.wrap(array, off, len));
     }
 
     private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {
     }
 
     private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {
index e39f21d288364e183beac94694f68f5a03ccb76b..6adcc7fa6e41f786bcd0fbd8a2a7be7e5b8c2668 100644 (file)
@@ -16,6 +16,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
 import java.util.Collection;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
 import java.util.Collection;
@@ -37,6 +40,7 @@ public final class OpenApiInputStream extends InputStream {
     private final Deque<InputStream> stack = new ArrayDeque<>();
 
     private Reader reader;
     private final Deque<InputStream> stack = new ArrayDeque<>();
 
     private Reader reader;
+    private ReadableByteChannel channel;
 
     private boolean eof;
 
 
     private boolean eof;
 
@@ -87,6 +91,30 @@ public final class OpenApiInputStream extends InputStream {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
-        return super.read(array, off, len);
+        if (eof) {
+            return -1;
+        }
+        if (channel == null) {
+            generator.writeStartObject();
+            generator.flush();
+            channel = Channels.newChannel(new ByteArrayInputStream(stream.toByteArray()));
+            stream.reset();
+        }
+
+        var read = channel.read(ByteBuffer.wrap(array, off, len));
+        while (read == -1) {
+            if (stack.isEmpty()) {
+                generator.writeEndObject();
+                generator.flush();
+                channel = Channels.newChannel(new ByteArrayInputStream(stream.toByteArray()));
+                stream.reset();
+                eof = true;
+                return channel.read(ByteBuffer.wrap(array, off, len));
+            }
+            channel = Channels.newChannel(stack.pop());
+            read = channel.read(ByteBuffer.wrap(array, off, len));
+        }
+
+        return read;
     }
 }
     }
 }
index 0553d0e6595d09357d23dc8688e03db5b91665f3..e412e542797dad8dacc901d464d1d814085ce770 100644 (file)
@@ -13,6 +13,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.StandardCharsets;
 import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
 import org.opendaylight.restconf.openapi.model.OpenApiEntity;
 import java.nio.charset.StandardCharsets;
 import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
 import org.opendaylight.restconf.openapi.model.OpenApiEntity;
@@ -23,6 +26,7 @@ public final class OpenApiVersionStream extends InputStream {
     private final OpenApiBodyWriter writer;
 
     private Reader reader;
     private final OpenApiBodyWriter writer;
 
     private Reader reader;
+    private ReadableByteChannel channel;
 
     public OpenApiVersionStream(final OpenApiVersionEntity entity, final OpenApiBodyWriter writer) {
         this.entity = entity;
 
     public OpenApiVersionStream(final OpenApiVersionEntity entity, final OpenApiBodyWriter writer) {
         this.entity = entity;
@@ -40,7 +44,10 @@ public final class OpenApiVersionStream extends InputStream {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
-        return super.read(array, off, len);
+        if (channel == null) {
+            channel = Channels.newChannel(new ByteArrayInputStream(writeNextEntity(entity)));
+        }
+        return channel.read(ByteBuffer.wrap(array, off, len));
     }
 
     private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {
     }
 
     private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {
index 2c72fc672e1e27c04054dbd47961b5dbf752b3ad..01ed0346e8affac94a571b8e2422e4a0b972d67e 100644 (file)
@@ -16,6 +16,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
@@ -70,6 +73,7 @@ public final class PathsStream extends InputStream {
     private boolean hasRootPostLink;
     private boolean hasAddedDataStore;
     private Reader reader;
     private boolean hasRootPostLink;
     private boolean hasAddedDataStore;
     private Reader reader;
+    private ReadableByteChannel channel;
 
     public PathsStream(final EffectiveModelContext schemaContext, final OpenApiBodyWriter writer,
             final String deviceName, final String urlPrefix, final boolean isForSingleModule,
 
     public PathsStream(final EffectiveModelContext schemaContext, final OpenApiBodyWriter writer,
             final String deviceName, final String urlPrefix, final boolean isForSingleModule,
@@ -98,7 +102,10 @@ public final class PathsStream extends InputStream {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
-        return super.read(array, off, len);
+        if (channel == null) {
+            channel = Channels.newChannel(new ByteArrayInputStream(writeNextEntity(new PathsEntity(toPaths()))));
+        }
+        return channel.read(ByteBuffer.wrap(array, off, len));
     }
 
     private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {
     }
 
     private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {
index 6036b7e48ca6f7a59da0d8a420264cd4a6fb5443..dc75c6995030f56bd04cf4d15f14396b4fb797d4 100644 (file)
@@ -13,6 +13,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.StandardCharsets;
 import java.util.Deque;
 import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
 import java.nio.charset.StandardCharsets;
 import java.util.Deque;
 import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
@@ -24,6 +27,7 @@ public final class SchemaStream extends InputStream {
     private final OpenApiBodyWriter writer;
 
     private Reader reader;
     private final OpenApiBodyWriter writer;
 
     private Reader reader;
+    private ReadableByteChannel channel;
 
     public SchemaStream(final Deque<SchemaEntity> schemas, final OpenApiBodyWriter writer) {
         this.stack = schemas;
 
     public SchemaStream(final Deque<SchemaEntity> schemas, final OpenApiBodyWriter writer) {
         this.stack = schemas;
@@ -55,7 +59,23 @@ public final class SchemaStream extends InputStream {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
-        return super.read(array, off, len);
+        if (channel == null) {
+            if (stack.isEmpty()) {
+                return -1;
+            }
+            channel = Channels.newChannel(new ByteArrayInputStream(writeNextEntity(stack.pop())));
+        }
+
+        var read = channel.read(ByteBuffer.wrap(array, off, len));
+        while (read == -1) {
+            if (stack.isEmpty()) {
+                return -1;
+            }
+            channel = Channels.newChannel(new ByteArrayInputStream(writeNextEntity(stack.pop())));
+            read = channel.read(ByteBuffer.wrap(array, off, len));
+        }
+
+        return read;
     }
 
     private byte[] writeNextEntity(final OpenApiEntity entity) throws IOException {
     }
 
     private byte[] writeNextEntity(final OpenApiEntity entity) throws IOException {
index c002e6401034bbbecfc23bdead8ed2a4ba42af1d..fa4e8280d461eb0bf2c899010c3fe77ea01b326c 100644 (file)
@@ -15,6 +15,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
@@ -46,6 +49,7 @@ public final class SchemasStream extends InputStream {
     private final boolean isForSingleModule;
 
     private Reader reader;
     private final boolean isForSingleModule;
 
     private Reader reader;
+    private ReadableByteChannel channel;
     private boolean schemesWritten;
 
     public SchemasStream(final EffectiveModelContext context, final OpenApiBodyWriter writer,
     private boolean schemesWritten;
 
     public SchemasStream(final EffectiveModelContext context, final OpenApiBodyWriter writer,
@@ -95,7 +99,33 @@ public final class SchemasStream extends InputStream {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
-        return super.read(array, off, len);
+        if (channel == null) {
+            generator.writeObjectFieldStart("schemas");
+            generator.flush();
+            channel = Channels.newChannel(new ByteArrayInputStream(stream.toByteArray()));
+            stream.reset();
+        }
+
+        var read = channel.read(ByteBuffer.wrap(array, off, len));
+        while (read == -1) {
+            if (iterator.hasNext()) {
+                channel = Channels.newChannel(new SchemaStream(toComponents(iterator.next(), context,
+                    isForSingleModule), writer));
+                read = channel.read(ByteBuffer.wrap(array, off, len));
+                continue;
+            }
+            if (!schemesWritten) {
+                generator.writeEndObject();
+                schemesWritten = true;
+                continue;
+            }
+            generator.flush();
+            channel = Channels.newChannel(new ByteArrayInputStream(stream.toByteArray()));
+            stream.reset();
+            return channel.read(ByteBuffer.wrap(array, off, len));
+        }
+
+        return read;
     }
 
     private static Deque<SchemaEntity> toComponents(final Module module, final EffectiveModelContext context,
     }
 
     private static Deque<SchemaEntity> toComponents(final Module module, final EffectiveModelContext context,
index 73e40c9079e3096fe2667ded75e0c011466d161f..5c7e53b5b2422784290fed65deec78131a23623d 100644 (file)
@@ -13,6 +13,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.StandardCharsets;
 import java.util.Map;
 import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
 import java.nio.charset.StandardCharsets;
 import java.util.Map;
 import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
@@ -25,6 +28,7 @@ public final class SecuritySchemesStream extends InputStream {
     private final SecuritySchemesEntity securitySchemesEntity;
 
     private Reader reader;
     private final SecuritySchemesEntity securitySchemesEntity;
 
     private Reader reader;
+    private ReadableByteChannel channel;
 
     public SecuritySchemesStream(final OpenApiBodyWriter writer,
             final Map<String, SecuritySchemeObject> securitySchemes) {
 
     public SecuritySchemesStream(final OpenApiBodyWriter writer,
             final Map<String, SecuritySchemeObject> securitySchemes) {
@@ -44,7 +48,11 @@ public final class SecuritySchemesStream extends InputStream {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
-        return super.read(array, off, len);
+        if (channel == null) {
+            final var stream = new ByteArrayInputStream(writeNextEntity(securitySchemesEntity));
+            channel = Channels.newChannel(stream);
+        }
+        return channel.read(ByteBuffer.wrap(array, off, len));
     }
 
     private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {
     }
 
     private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {
index 0cea95ff8442d1ea3fa3d6da8753415b963816fe..f3d16505fa145f2ee845ff35e270cc50baf50267 100644 (file)
@@ -13,6 +13,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.StandardCharsets;
 import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
 import org.opendaylight.restconf.openapi.model.OpenApiEntity;
 import java.nio.charset.StandardCharsets;
 import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
 import org.opendaylight.restconf.openapi.model.OpenApiEntity;
@@ -23,6 +26,7 @@ public final class SecurityStream extends InputStream {
     private final SecurityEntity entity;
 
     private Reader reader;
     private final SecurityEntity entity;
 
     private Reader reader;
+    private ReadableByteChannel channel;
 
     public SecurityStream(final OpenApiBodyWriter writer, final SecurityEntity entity) {
         this.writer = writer;
 
     public SecurityStream(final OpenApiBodyWriter writer, final SecurityEntity entity) {
         this.writer = writer;
@@ -40,7 +44,10 @@ public final class SecurityStream extends InputStream {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
-        return super.read(array, off, len);
+        if (channel == null) {
+            channel = Channels.newChannel(new ByteArrayInputStream(writeNextEntity(entity)));
+        }
+        return channel.read(ByteBuffer.wrap(array, off, len));
     }
 
     private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {
     }
 
     private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {
index db8194a862e8379d68398c55cc2f0f63d1035ed8..bff54b2e5481356ec07bb01969eca5d3db739637 100644 (file)
@@ -13,6 +13,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.StandardCharsets;
 import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
 import org.opendaylight.restconf.openapi.model.OpenApiEntity;
 import java.nio.charset.StandardCharsets;
 import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
 import org.opendaylight.restconf.openapi.model.OpenApiEntity;
@@ -23,6 +26,7 @@ public final class ServersStream extends InputStream {
     private final OpenApiBodyWriter writer;
 
     private Reader reader;
     private final OpenApiBodyWriter writer;
 
     private Reader reader;
+    private ReadableByteChannel channel;
 
     public ServersStream(final ServersEntity entity, final OpenApiBodyWriter writer) {
         this.entity = entity;
 
     public ServersStream(final ServersEntity entity, final OpenApiBodyWriter writer) {
         this.entity = entity;
@@ -40,7 +44,10 @@ public final class ServersStream extends InputStream {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
-        return super.read(array, off, len);
+        if (channel == null) {
+            channel = Channels.newChannel(new ByteArrayInputStream(writeNextEntity(entity)));
+        }
+        return channel.read(ByteBuffer.wrap(array, off, len));
     }
 
     private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {
     }
 
     private byte[] writeNextEntity(final OpenApiEntity next) throws IOException {