Skip to content

Commit

Permalink
I/O extensions and functors
Browse files Browse the repository at this point in the history
  • Loading branch information
fvilla committed Dec 17, 2024
1 parent 79a7a4f commit c33e989
Show file tree
Hide file tree
Showing 12 changed files with 296 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import org.integratedmodelling.klab.api.engine.Engine;
import org.integratedmodelling.klab.api.exceptions.KlabIOException;
import org.integratedmodelling.klab.api.exceptions.KlabIllegalStateException;
import org.integratedmodelling.klab.api.knowledge.Resource;
import org.integratedmodelling.klab.api.knowledge.Urn;
import org.integratedmodelling.klab.api.scope.ContextScope;
import org.integratedmodelling.klab.api.scope.Scope;
Expand Down Expand Up @@ -42,9 +41,7 @@
import picocli.shell.jline3.PicocliCommands.PicocliCommandsFactory;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
Expand Down Expand Up @@ -130,7 +127,7 @@ public void importWithSchema(KlabService service, String suggestedUrn, List<Stri
}
} else {
schema = ResourceTransport.INSTANCE.findSchema(arguments.getFirst(),
service.capabilities(user()).getImportSchemata());
service.capabilities(user()).getImportSchemata(), user());
}

if (schema == null) {
Expand Down Expand Up @@ -205,7 +202,7 @@ public void importWithSchema(KlabService service, String suggestedUrn, List<Stri
commandLine.getOut().println(Ansi.AUTO.string("Choose a transport schema:"));
for (String key : schemata.keySet()) {
for (var schema : schemata.get(key)) {
commandLine.getOut().println(Ansi.AUTO.string(" " + (n++) + ": @|green " + key + "." + schema.getSchemaId() + "|@ " +
commandLine.getOut().println(Ansi.AUTO.string(" " + (n++) + ": @|green " + schema.getSchemaId() + "|@ " +
"@|yellow " + schema.getDescription() + "|@"));
choices.add(Pair.of(key, schema));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public interface ServiceInfo extends Serializable {
* @author Ferd
*/
enum FunctionType {
FUNCTION, VERB, ANNOTATION
FUNCTION, VERB, ANNOTATION, IMPORTER, EXPORTER
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.integratedmodelling.klab.api.identities.AuthenticatedIdentity;
import org.integratedmodelling.klab.api.knowledge.Artifact;
import org.integratedmodelling.klab.api.knowledge.KlabAsset;
import org.integratedmodelling.klab.api.scope.Scope;
import org.integratedmodelling.klab.api.utils.Utils;

import java.io.File;
Expand Down Expand Up @@ -342,32 +343,37 @@ private List<Schema> findSchemata(Map<String, List<Schema>> schemata, String sch
*/
ResourceTransport() {

addImport("component", COMPONENT_MAVEN = Schema.create("maven",
Schema.Type.PROPERTIES, KlabAsset.KnowledgeClass.COMPONENT, "Register a component " +
"available on Maven " + "using " + "the component's Maven coordinates").with(
"groupId", Artifact.Type.TEXT, false).with("adapterId", Artifact.Type.TEXT,
false).with("version", Artifact.Type.TEXT, false));

addImport("component.jar", COMPONENT_JAR = Schema.create("jar",
Schema.Type.STREAM, KlabAsset.KnowledgeClass.COMPONENT, "Register a component by directly " +
"submitting a jar file").mediaType("application/java-archive").fileExtensions("jar"));

addImport("project.git", PROJECT_GIT = Schema.create("git", Schema.Type.PROPERTIES,
KlabAsset.KnowledgeClass.PROJECT, "Register a k.LAB project by submitting the URL of a Git "
+ "repository and optional credentials").with("url", Artifact.Type.TEXT, false).with("username", Artifact.Type.TEXT, true).with("password", Artifact.Type.TEXT, true).with("token", Artifact.Type.TEXT, true));

addImport("project.zip", PROJECT_ZIP = Schema.create("zip",
Schema.Type.STREAM,
KlabAsset.KnowledgeClass.PROJECT, "Register a k.LAB by directly submitting a zip archive").mediaType("application/zip", "application/x-zip-compressed").fileExtensions("zip"));
addImport("component",
COMPONENT_MAVEN = Schema.create("component.maven",
Schema.Type.PROPERTIES, KlabAsset.KnowledgeClass.COMPONENT, "Register a component " +
"available on Maven " + "using " + "the component's Maven coordinates").with(
"groupId", Artifact.Type.TEXT, false).with("adapterId", Artifact.Type.TEXT,
false).with("version", Artifact.Type.TEXT, false),
COMPONENT_JAR = Schema.create("component.jar",
Schema.Type.STREAM, KlabAsset.KnowledgeClass.COMPONENT, "Register a component by " +
"directly " +
"submitting a jar file").mediaType("application/java-archive").fileExtensions("jar"));

addImport("project.git",
PROJECT_GIT = Schema.create("project.git", Schema.Type.PROPERTIES,
KlabAsset.KnowledgeClass.PROJECT, "Register a k.LAB project by submitting the URL " +
"of a Git "
+ "repository and optional credentials").with("url", Artifact.Type.TEXT,
false).with("username", Artifact.Type.TEXT, true).with("password",
Artifact.Type.TEXT, true).with("token", Artifact.Type.TEXT, true),
PROJECT_ZIP = Schema.create("project.zip",
Schema.Type.STREAM,
KlabAsset.KnowledgeClass.PROJECT, "Register a k.LAB by directly submitting a zip " +
"archive").mediaType("application/zip", "application/x-zip-compressed").fileExtensions("zip"));

}

// TODO pass scope for permissions
public Schema findSchema(String id, Map<String, List<Schema>> schemata) {
// TODO use the scope for permissions (here or downstream in service controllers)
public Schema findSchema(String id, Map<String, List<Schema>> schemata, Scope scope) {
var list = schemata.get(Utils.Paths.getLeading(id, '.'));
if (list != null) {
for (var schema : list) {
if (schema.getSchemaId().equals(Utils.Paths.getLast(id, '.'))) {
if (schema.getSchemaId().equals(id)) {
return schema;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.integratedmodelling.klab.api.services.resources.adapters;

import org.integratedmodelling.klab.api.knowledge.KlabAsset;
import org.integratedmodelling.klab.api.services.runtime.extension.KlabFunction;

import java.lang.annotation.*;

/**
* Annotates methods that implement (and possibly define) an export schema specified through
* {@link org.integratedmodelling.klab.api.services.resources.ResourceTransport} beans. The methods can be in
* a class annotated with {@link org.integratedmodelling.klab.api.services.runtime.extension.Library} or
* {@link ResourceAdapter}.
* <p>
* Recognized method parameters should include an {@link org.integratedmodelling.klab.api.knowledge.Urn} or
* directly a Resource for resources with parameters, a scope, and possibly a String for a media type that
* should be part of the annotation and established through content negotiation. The method must return an
* {@link org.integratedmodelling.klab.api.knowledge.Urn} or a {@link String} that encodes one.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Exporter {

/**
* The unique ID of the import schema this implements. This is the complete ID as a dot-separated path,
* whose leading path is the "class" of the import and the last element specifies the import source or
* method (e.g. <code>component.jar</code>).
*
* @return
*/
String schema();


KlabAsset.KnowledgeClass knowledgeClass();

/**
* If specified, these define the schema's properties which will be passed as a
* {@link org.integratedmodelling.klab.api.collections.Parameters} object. If not, the schema will expect
* binary content as a File, URL or InputStream.
*
* @return
*/
KlabFunction.Argument[] properties() default {};

/**
* Mandatory media type that will be sent along with the exported byte stream.
*
* @return
*/
String mediaType();

String[] fileExtensions() default {};

String description();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.integratedmodelling.klab.api.services.resources.adapters;

import org.integratedmodelling.klab.api.knowledge.KlabAsset;
import org.integratedmodelling.klab.api.services.runtime.extension.KlabFunction;

import java.lang.annotation.*;

/**
* Annotates methods that implement (and possibly define) an import schema specified through
* {@link org.integratedmodelling.klab.api.services.resources.ResourceTransport} beans. The methods can be in
* a class annotated with {@link org.integratedmodelling.klab.api.services.runtime.extension.Library} or
* {@link ResourceAdapter} (if the latter, the import will be expected to produce a Resource adopting that
* same adapter).
* <p>
* Recognized method parameters can be {@link java.io.File}, {@link java.net.URL} or
* {@link java.io.InputStream} for binary content,
* {@link org.integratedmodelling.klab.api.collections.Parameters} for property-specified content, Resource
* for resources with parameters, and scopes. An {@link org.integratedmodelling.klab.api.knowledge.Urn} may be
* added which will be paired to a suggested URN if the caller has supplied one (the method may modify it).
* The method must return an {@link org.integratedmodelling.klab.api.knowledge.Urn} or a {@link String} that
* encodes one, which will be the final, unique URN.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Importer {

/**
* The unique ID of the import schema this implements. This is the complete ID as a dot-separated path,
* whose leading path is the "class" of the import and the last element specifies the import source or
* method (e.g. <code>component.jar</code>).
*
* @return
*/
String schema();

KlabAsset.KnowledgeClass knowledgeClass();

/**
* If specified, these define the schema's properties which will be passed as a
* {@link org.integratedmodelling.klab.api.collections.Parameters} object. If not, the schema will expect
* binary content as a File, URL or InputStream.
*
* @return
*/
KlabFunction.Argument[] properties() default {};

/**
* Optional media type that will be matched to the input's in case multiple schemata are possible for
* different media types.
*
* @return
*/
String mediaType() default "";

String[] fileExtensions() default {};

String description();

}
Original file line number Diff line number Diff line change
Expand Up @@ -208,20 +208,6 @@ enum LifecyclePhase {

}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Importer {

}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Exporter {

}

/**
* Annotates a method returning {@link Artifact.Type} and taking a {@link Resource} as argument. Only used
* if the type is not specified in the {@link ResourceAdapter} arguments.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,18 @@ void connectToService(KlabService.ServiceCapabilities capabilities, UserIdentity
* @return
*/
boolean isConnected();

/**
* True if the scope is connected to one or more queues and is set up for sending messages.
*
* @return
*/
boolean isSender();

/**
* True if the scope is connected to one or more queues and is set up for receiving messages.
*
* @return
*/
boolean isReceiver();
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import org.integratedmodelling.klab.api.services.runtime.Message;
import org.integratedmodelling.klab.api.services.runtime.MessagingChannel;

import java.io.Closeable;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
Expand Down Expand Up @@ -470,11 +469,12 @@ public void presetMessagingQueue(Message.Queue queue, String s) {
queueNames.put(queue, s + "." + queue.name().toLowerCase());
}


@Override
public boolean isSender() {
return sender;
}

@Override
public boolean isReceiver() {
return receiver;
}
Expand Down
Loading

0 comments on commit c33e989

Please sign in to comment.