Better handling of extensions in PiPipeconf
Now built using a URL, while input streams are generated on-demand.
Before it could happen that the input stream was completelly read by
someone, leaving it unusable by others.
Change-Id: I61a76bf8b8c1d2f6e2d987661025e0323d59e1c7
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/DefaultPiPipeconf.java b/core/api/src/main/java/org/onosproject/net/pi/model/DefaultPiPipeconf.java
index e457052..e6f9406 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/DefaultPiPipeconf.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/DefaultPiPipeconf.java
@@ -19,12 +19,16 @@
import com.google.common.collect.ImmutableMap;
import org.onosproject.net.driver.Behaviour;
+import java.io.IOException;
import java.io.InputStream;
+import java.net.URL;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.String.format;
/**
* Default pipeconf implementation.
@@ -34,11 +38,11 @@
private final PiPipeconfId id;
private final PiPipelineModel pipelineModel;
private final Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours;
- private final Map<ExtensionType, InputStream> extensions;
+ private final Map<ExtensionType, URL> extensions;
private DefaultPiPipeconf(PiPipeconfId id, PiPipelineModel pipelineModel,
Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours,
- Map<ExtensionType, InputStream> extensions) {
+ Map<ExtensionType, URL> extensions) {
this.id = id;
this.pipelineModel = pipelineModel;
this.behaviours = behaviours;
@@ -72,7 +76,15 @@
@Override
public Optional<InputStream> extension(ExtensionType type) {
- return Optional.ofNullable(extensions.get(type));
+ if (extensions.containsKey(type)) {
+ try {
+ return Optional.of(extensions.get(type).openStream());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ return Optional.empty();
+ }
}
/**
@@ -93,7 +105,7 @@
private PiPipelineModel pipelineModel;
private ImmutableMap.Builder<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviourMapBuilder
= ImmutableMap.builder();
- private ImmutableMap.Builder<ExtensionType, InputStream> extensionMapBuilder = ImmutableMap.builder();
+ private ImmutableMap.Builder<ExtensionType, URL> extensionMapBuilder = ImmutableMap.builder();
/**
* Sets the identifier of this pipeconf.
@@ -134,17 +146,27 @@
/**
* Adds an extension to this pipeconf.
*
- * @param type extension type
- * @param inputStream input stream pointing at the extension
+ * @param type extension type
+ * @param url url pointing at the extension file
* @return this
*/
- public Builder addExtension(ExtensionType type, InputStream inputStream) {
+ public Builder addExtension(ExtensionType type, URL url) {
checkNotNull(type);
- checkNotNull(inputStream);
- extensionMapBuilder.put(type, inputStream);
+ checkNotNull(url);
+ checkArgument(checkUrl(url), format("Extension url %s seems to be empty/non existent", url.toString()));
+ extensionMapBuilder.put(type, url);
return this;
}
+ private boolean checkUrl(URL url) {
+ try {
+ int byteCount = url.openStream().available();
+ return byteCount > 0;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
/**
* Creates a new pipeconf.
*
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java
index f94ae6e..389da5c 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java
@@ -68,9 +68,9 @@
boolean hasBehaviour(Class<? extends Behaviour> behaviourClass);
/**
- * Returns, if present, an input stream of ad device-specific or control
- * protocol-specific extension of this configuration. For example, if requesting a
- * target-specific P4 binary, this will return the same bytes produced by the P4 compiler.
+ * Returns, if present, an input stream pointing at the beginning of a file representing a device-specific or
+ * control protocol-specific extension of this configuration. For example, if requesting a target-specific P4
+ * binary, this will return the same bytes produced by the P4 compiler.
*
* @param type extension type
* @return extension input stream