diff --git a/kcli/src/main/java/org/integratedmodelling/kcli/engine/Engine.java b/kcli/src/main/java/org/integratedmodelling/kcli/engine/Engine.java index 35298cde6..3f658f148 100644 --- a/kcli/src/main/java/org/integratedmodelling/kcli/engine/Engine.java +++ b/kcli/src/main/java/org/integratedmodelling/kcli/engine/Engine.java @@ -29,205 +29,212 @@ public enum Engine implements Authentication { - INSTANCE; - - /* - * these are set/unset by the user and can be used for substitutions in CLs - */ - Parameters userData = Parameters.create(); - Map authorizedIdentities = new LinkedHashMap<>(); - - UserScope currentUser; - SessionScope currentSession; - ContextScope currentContext; - - Map sessions = new LinkedHashMap<>(); - Map contexts = new LinkedHashMap<>(); - - EngineService engineService; - - private Engine() { - - engineService = new EngineService(); - - /* - * discover and catalog services - */ - - /* - * check for a locally running service for each category; if existing, create a - * client, otherwise create an embedded service - */ - if (Utils.Network.isAlive("http://127.0.0.1:" + ResourcesService.DEFAULT_PORT + " /resources/actuator")) { - engineService - .setResources(new ResourcesClient("http://127.0.0.1:" + Reasoner.DEFAULT_PORT + " /resources")); - } else { - engineService.setResources( - new ResourcesProvider(this, engineService.newServiceScope(ResourcesService.class))); - } - - if (Utils.Network.isAlive("http://127.0.0.1:" + Reasoner.DEFAULT_PORT + " /reasoner/actuator")) { - engineService - .setReasoner(new ReasonerClient("http://127.0.0.1:" + Reasoner.DEFAULT_PORT + " /reasoner")); - } else { - engineService - .setReasoner(new ReasonerService(this, engineService.newServiceScope(Reasoner.class))); - } - - // FIXME mutual dependency between resolver and runtime guarantees screwup - if (Utils.Network.isAlive("http://127.0.0.1:" + Resolver.DEFAULT_PORT + " /resolver/actuator")) { - engineService - .setResolver(new ResolverClient("http://127.0.0.1:" + Resolver.DEFAULT_PORT + " /resolver")); - } else { - engineService - .setResolver(new ResolverService(this, engineService.newServiceScope(Resolver.class))); - } - - if (Utils.Network.isAlive("http://127.0.0.1:" + RuntimeService.DEFAULT_PORT + " /runtime/actuator")) { - engineService - .setRuntime(new RuntimeClient("http://127.0.0.1:" + RuntimeService.DEFAULT_PORT + " /runtime")); - } else { - engineService.setRuntime(new org.integratedmodelling.klab.services.runtime.RuntimeService(this, - engineService.newServiceScope(RuntimeService.class))); - } - - // Boot will initialize all embedded services - engineService.boot(); - - /* - * add the anonymous identity - */ - this.authorizedIdentities.put("anonymous", this.currentUser = getAnonymousScope()); - - } - - @Override - public UserScope authorizeUser(UserIdentity user) { - return engineService.login(user); - } - - @Override - public boolean checkPermissions(ResourcePrivileges permissions, Scope scope) { - // everything is allowed - return true; - } - - /** - * Return the specific service among the various available. The "local" keyword - * returns the service installed as the default in the user scope. The "active" - * keyword should get the currently active service. Anything else will look up - * the service using the discovery mechanism. - * - * @param - * @param name - * @param serviceClass - * @return - */ - public T getServiceNamed(String name, Class serviceClass) { - return "local".equals(name) ? currentUser.getService(serviceClass) : /* TODO */ null; - } - - @Override - public UserScope getAnonymousScope() { - return engineService.login(new AnonymousUser()); - } - - /** - * Get or optionally create the current user. Report using the channel. - * - * @param loginAnonymousIfNull - * @param channel - * @return - */ - public UserScope getCurrentUser(boolean loginAnonymousIfNull, Channel channel) { - return currentUser; - } - - /** - * Use this when you know it's there - * - * @return - */ - public UserScope getCurrentUser() { - return currentUser; - } - - /** - * Get or optionally create the current session. Report using the channel. - * - * @param createIfNull - * @param channel - * @return - */ - public SessionScope getCurrentSession(boolean createIfNull, Channel channel) { - if (currentSession == null) { - currentSession = createSession(NameGenerator.shortUUID(), true); - } - return currentSession; - } - - /** - * Return the current session or null. - * - * @return - */ - public SessionScope getCurrentSession() { - return currentSession; - } - - public ContextScope getCurrentContext(boolean createIfNull) { - - if (currentContext == null) { - if (currentSession == null) { - createSession(NameGenerator.shortUUID(), true); - } - currentContext = currentSession.createContext(NameGenerator.shortUUID(), Geometry.EMPTY); - } - - return currentContext; - } - - public Parameters getUserData() { - return userData; - } - - public Collection getUsers() { - return authorizedIdentities.values(); - } - - public SessionScope getSession(String name) { - return this.sessions.get(name); - } - - public SessionScope createSession(String name, boolean makeCurrent) { - - if (currentUser == null) { - throw new KIllegalStateException("no current user scope: cannot create session " + name); - } - if (this.sessions.containsKey(name)) { - throw new KIllegalStateException("session already exists: cannot create session " + name); - } - - SessionScope ret = currentUser.runSession(name); - this.sessions.put(name, ret); - - if (makeCurrent) { - this.currentSession = ret; - } - return ret; - } - - public void setDefaultSession(SessionScope session) { - this.currentSession = session; - } - - public void setCurrentContext(ContextScope context) { - this.contexts.put(context.getName(), context); - this.currentContext = context; - } - - public ContextScope getContext(String context) { - return this.contexts.get(context); - } + INSTANCE; + + /* + * these are set/unset by the user and can be used for substitutions in CLs + */ + Parameters userData = Parameters.create(); + Map authorizedIdentities = new LinkedHashMap<>(); + + UserScope currentUser; + SessionScope currentSession; + ContextScope currentContext; + + Map sessions = new LinkedHashMap<>(); + Map contexts = new LinkedHashMap<>(); + + EngineService engineService; + + private Engine() { + + engineService = new EngineService(); + + /* + * discover and catalog services + */ + + /* + * check for a locally running service for each category; if existing, create a + * client, otherwise create an embedded service + */ + if (Utils.Network.isAlive("http://127.0.0.1:" + ResourcesService.DEFAULT_PORT + " /resources" + + "/actuator")) { + engineService + .setResources(new ResourcesClient("http://127.0.0.1:" + Reasoner.DEFAULT_PORT + " " + + "/resources")); + } else { + engineService.setResources( + new ResourcesProvider(this, engineService.newServiceScope(ResourcesService.class), + "Embedded resource manager")); + } + + if (Utils.Network.isAlive("http://127.0.0.1:" + Reasoner.DEFAULT_PORT + " /reasoner/actuator")) { + engineService + .setReasoner(new ReasonerClient("http://127.0.0.1:" + Reasoner.DEFAULT_PORT + " " + + "/reasoner")); + } else { + engineService + .setReasoner(new ReasonerService(this, engineService.newServiceScope(Reasoner.class), + "Embedded reasoner")); + } + + // FIXME mutual dependency between resolver and runtime guarantees screwup + if (Utils.Network.isAlive("http://127.0.0.1:" + Resolver.DEFAULT_PORT + " /resolver/actuator")) { + engineService + .setResolver(new ResolverClient("http://127.0.0.1:" + Resolver.DEFAULT_PORT + " " + + "/resolver")); + } else { + engineService + .setResolver(new ResolverService(this, engineService.newServiceScope(Resolver.class), + "Embedded resolver")); + } + + if (Utils.Network.isAlive("http://127.0.0.1:" + RuntimeService.DEFAULT_PORT + " /runtime/actuator")) { + engineService + .setRuntime(new RuntimeClient("http://127.0.0.1:" + RuntimeService.DEFAULT_PORT + " " + + "/runtime")); + } else { + engineService.setRuntime(new org.integratedmodelling.klab.services.runtime.RuntimeService(this, + engineService.newServiceScope(RuntimeService.class), "Embedded runtime")); + } + + // Boot will initialize all embedded services + engineService.boot(); + + /* + * add the anonymous identity + */ + this.authorizedIdentities.put("anonymous", this.currentUser = getAnonymousScope()); + + } + + @Override + public UserScope authorizeUser(UserIdentity user) { + return engineService.login(user); + } + + @Override + public boolean checkPermissions(ResourcePrivileges permissions, Scope scope) { + // everything is allowed + return true; + } + + /** + * Return the specific service among the various available. The "local" keyword returns the service + * installed as the default in the user scope. The "active" keyword should get the currently active + * service. Anything else will look up the service using the discovery mechanism. + * + * @param + * @param name + * @param serviceClass + * @return + */ + public T getServiceNamed(String name, Class serviceClass) { + return "local".equals(name) ? currentUser.getService(serviceClass) : /* TODO */ null; + } + + @Override + public UserScope getAnonymousScope() { + return engineService.login(new AnonymousUser()); + } + + /** + * Get or optionally create the current user. Report using the channel. + * + * @param loginAnonymousIfNull + * @param channel + * @return + */ + public UserScope getCurrentUser(boolean loginAnonymousIfNull, Channel channel) { + return currentUser; + } + + /** + * Use this when you know it's there + * + * @return + */ + public UserScope getCurrentUser() { + return currentUser; + } + + /** + * Get or optionally create the current session. Report using the channel. + * + * @param createIfNull + * @param channel + * @return + */ + public SessionScope getCurrentSession(boolean createIfNull, Channel channel) { + if (currentSession == null) { + currentSession = createSession(NameGenerator.shortUUID(), true); + } + return currentSession; + } + + /** + * Return the current session or null. + * + * @return + */ + public SessionScope getCurrentSession() { + return currentSession; + } + + public ContextScope getCurrentContext(boolean createIfNull) { + + if (currentContext == null) { + if (currentSession == null) { + createSession(NameGenerator.shortUUID(), true); + } + currentContext = currentSession.createContext(NameGenerator.shortUUID(), Geometry.EMPTY); + } + + return currentContext; + } + + public Parameters getUserData() { + return userData; + } + + public Collection getUsers() { + return authorizedIdentities.values(); + } + + public SessionScope getSession(String name) { + return this.sessions.get(name); + } + + public SessionScope createSession(String name, boolean makeCurrent) { + + if (currentUser == null) { + throw new KIllegalStateException("no current user scope: cannot create session " + name); + } + if (this.sessions.containsKey(name)) { + throw new KIllegalStateException("session already exists: cannot create session " + name); + } + + SessionScope ret = currentUser.runSession(name); + this.sessions.put(name, ret); + + if (makeCurrent) { + this.currentSession = ret; + } + return ret; + } + + public void setDefaultSession(SessionScope session) { + this.currentSession = session; + } + + public void setCurrentContext(ContextScope context) { + this.contexts.put(context.getName(), context); + this.currentContext = context; + } + + public ContextScope getContext(String context) { + return this.contexts.get(context); + } } diff --git a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/services/KlabService.java b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/services/KlabService.java index 348393441..584faaa83 100644 --- a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/services/KlabService.java +++ b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/services/KlabService.java @@ -1,9 +1,9 @@ package org.integratedmodelling.klab.api.services; -import java.io.Serializable; - import org.integratedmodelling.klab.api.scope.ServiceScope; +import java.io.Serializable; + /** * Services may be locally implemented or clients to remote services: each service implementation * should provide both forms. The latter ones must publish a URL. In all cases they are added in @@ -19,6 +19,14 @@ */ public interface KlabService extends Service { + enum Type { + REASONER, + RESOURCES, + RESOLVER, + RUNTIME, + COMMUNITY + } + /** * At the very minimum, each service advertises its type and local name. * @@ -27,6 +35,8 @@ public interface KlabService extends Service { */ interface ServiceCapabilities extends Serializable { + Type getType(); + String getLocalName(); String getServiceName(); @@ -54,7 +64,6 @@ interface ServiceCapabilities extends Serializable { */ String getLocalName(); - /** * Each service operates under a root scope that is used to report issues, talk to clients and * derive child scopes for users and when appropriate, sessions and contexts. diff --git a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/services/runtime/Message.java b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/services/runtime/Message.java index f8cb1c23d..09fa25799 100644 --- a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/services/runtime/Message.java +++ b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/services/runtime/Message.java @@ -1,11 +1,11 @@ package org.integratedmodelling.klab.api.services.runtime; -import java.io.Serializable; - import org.integratedmodelling.klab.api.scope.Scope; import org.integratedmodelling.klab.api.services.runtime.impl.MessageImpl; import org.integratedmodelling.klab.api.utils.Utils; +import java.io.Serializable; + /** * Messages exchanged between the engine and its clients. * @@ -46,6 +46,10 @@ enum MessageClass { */ UserContextDefinition, + /** + * Any event referring to a service + */ + ServiceLifecycle, /** * */ @@ -130,6 +134,11 @@ enum MessageType { */ ConsoleCreated, ConsoleClosed, CommandRequest, CommandResponse, + /* + * Service messages, coming with service capabilities + */ + ServiceInitializing, ServiceAvailable, ServiceUnavailable, + /* * UserContextChange-class types. */ @@ -475,7 +484,7 @@ public static MessageImpl create(String identity, Object... o) { ret.setRepeatability((Repeatability) ob); } else if (ob instanceof Notification) { notype = ((Notification) ob).getType(); - ret.setPayload(((Notification) ob).getMessage()); + ret.setPayload(ob); } else if (ob != null) { if (ret.getPayload() == null) { ret.setPayload(ob); @@ -510,7 +519,7 @@ public static MessageImpl create(Notification notification, String identity) { MessageImpl ret = new MessageImpl(); ret.setIdentity(identity); ret.setMessageClass(MessageClass.Notification); - ret.setPayload(notification.getMessage()); + ret.setPayload(notification); ret.setPayloadClass("String"); if (notification.getLevel().equals(Notification.Level.Debug)) { diff --git a/klab.services.authentication/src/main/java/org/integratedmodelling/klab/services/authentication/impl/LocalServiceScope.java b/klab.services.authentication/src/main/java/org/integratedmodelling/klab/services/authentication/impl/LocalServiceScope.java index df6bc34e6..84f3e9f1f 100644 --- a/klab.services.authentication/src/main/java/org/integratedmodelling/klab/services/authentication/impl/LocalServiceScope.java +++ b/klab.services.authentication/src/main/java/org/integratedmodelling/klab/services/authentication/impl/LocalServiceScope.java @@ -7,148 +7,150 @@ import org.integratedmodelling.klab.api.scope.ServiceScope; import org.integratedmodelling.klab.api.services.KlabService; import org.integratedmodelling.klab.api.services.runtime.Channel; +import org.integratedmodelling.klab.api.services.runtime.Message; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; +import java.util.*; +import java.util.function.BiConsumer; public abstract class LocalServiceScope extends Monitor implements ServiceScope { - KlabService service; - Status status; - - class LocalService implements ServiceIdentity { - - Date boot = new Date(); - KlabService service; - Scope delegate; - - public LocalService(KlabService service) { - this.service = service; - } - - @Override - public boolean stop() { - return false; - } - - @Override - public Channel getMonitor() { - return LocalServiceScope.this; - } - - @Override - public Parameters getState() { - return getData(); - } - - @Override - public Type getIdentityType() { - return Type.SERVICE; - } - - @Override - public String getId() { - return service.getLocalName(); - } - - @Override - public Identity getParentIdentity() { - return null; - } - - @Override - public boolean is(Type type) { - return type == Type.SERVICE; - } - - @Override - public T getParentIdentity(Class type) { - return null; - } - - @Override - public String getName() { - return service.getServiceName(); - } - - @Override - public Date getBootTime() { - return boot; - } - - @Override - public Collection getUrls() { - return Collections.singleton(service.getUrl()); - } - - @Override - public boolean isOnline() { - return true; - } - - @Override - public Parameters getData() { - return LocalServiceScope.this.data; - } - - } - - public LocalServiceScope(Class serviceClass) { - this.serviceClass = serviceClass; - } - - private Parameters data = Parameters.create(); - private Identity serviceIdentity; - private Class serviceClass; - - @Override - public Parameters getData() { - return data; - } - - @Override - public boolean isLocal() { - return true; - } - - @Override - public boolean isExclusive() { - return false; - } - - @Override - public boolean isDedicated() { - return true; - } - - @Override - public Status getStatus() { - return status; - } - - @Override - public Collection getServices(Class serviceClass) { - // TODO if a service resolver is available to the service, that should be used. - return Collections.singleton(getService(serviceClass)); - } - - @Override - public Identity getIdentity() { - if (this.serviceIdentity != null) { - this.serviceIdentity = new LocalService(getService(this.serviceClass)); - } - return this.serviceIdentity; - } - - @Override - public void setStatus(Status status) { - this.status = status; - } - - @Override - public void setData(String key, Object value) { - this.data.put(key, value); - } + KlabService service; + Status status; + + class LocalService implements ServiceIdentity { + + Date boot = new Date(); + KlabService service; + Scope delegate; + + public LocalService(KlabService service) { + this.service = service; + } + + @Override + public boolean stop() { + return false; + } + + @Override + public Channel getMonitor() { + return LocalServiceScope.this; + } + + @Override + public Parameters getState() { + return getData(); + } + + @Override + public Type getIdentityType() { + return Type.SERVICE; + } + + @Override + public String getId() { + return service.getLocalName(); + } + + @Override + public Identity getParentIdentity() { + return null; + } + + @Override + public boolean is(Type type) { + return type == Type.SERVICE; + } + + @Override + public T getParentIdentity(Class type) { + return null; + } + + @Override + public String getName() { + return service.getServiceName(); + } + + @Override + public Date getBootTime() { + return boot; + } + + @Override + public Collection getUrls() { + return Collections.singleton(service.getUrl()); + } + + @Override + public boolean isOnline() { + return true; + } + + @Override + public Parameters getData() { + return LocalServiceScope.this.data; + } + + } + + public LocalServiceScope(Class serviceClass, + BiConsumer... listeners) { + super(listeners); + this.serviceClass = serviceClass; + } + + private Parameters data = Parameters.create(); + private Identity serviceIdentity; + private Class serviceClass; + + @Override + public Parameters getData() { + return data; + } + + @Override + public boolean isLocal() { + return true; + } + + @Override + public boolean isExclusive() { + return false; + } + + @Override + public boolean isDedicated() { + return true; + } + + @Override + public Status getStatus() { + return status; + } + + @Override + public Collection getServices(Class serviceClass) { + // TODO if a service resolver is available to the service, that should be used. + return Collections.singleton(getService(serviceClass)); + } + + @Override + public Identity getIdentity() { + if (this.serviceIdentity != null) { + this.serviceIdentity = new LocalService(getService(this.serviceClass)); + } + return this.serviceIdentity; + } + + @Override + public void setStatus(Status status) { + this.status = status; + } + + @Override + public void setData(String key, Object value) { + this.data.put(key, value); + } } diff --git a/klab.services.authentication/src/main/java/org/integratedmodelling/klab/services/authentication/impl/Monitor.java b/klab.services.authentication/src/main/java/org/integratedmodelling/klab/services/authentication/impl/Monitor.java index e371712d0..f02d579a1 100644 --- a/klab.services.authentication/src/main/java/org/integratedmodelling/klab/services/authentication/impl/Monitor.java +++ b/klab.services.authentication/src/main/java/org/integratedmodelling/klab/services/authentication/impl/Monitor.java @@ -12,6 +12,8 @@ import org.integratedmodelling.klab.api.utils.Utils; import org.integratedmodelling.klab.logging.Logging; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BiConsumer; @@ -24,21 +26,24 @@ */ public class Monitor implements Channel { - private BiConsumer notificationConsumer; - - private BiConsumer sendConsumer; - private int errorCount = 0; private AtomicBoolean isInterrupted = new AtomicBoolean(false); private int waitTime; private Identity identity; + private List> eventListeners = new ArrayList<>(); + /** - * FIXME probably this whole messageBus thing can be dealt with using the consumers above + * FIXME probably this whole messageBus thing can be dealt with using just the consumer= */ transient MessageBus messageBus; - protected Monitor() { + protected Monitor(BiConsumer... listeners) { + if (listeners != null) { + for (var listener : listeners) { + this.eventListeners.add(listener); + } + } } public Monitor(Identity identity) { @@ -108,13 +113,12 @@ public void send(Object... o) { if (o != null && o.length > 0) { if (this instanceof Scope scope) { - if (notificationConsumer != null && o[0] instanceof Notification notification) { - notificationConsumer.accept(scope, notification); - } else if (sendConsumer != null) { - sendConsumer.accept(scope, o[0]); + if (!eventListeners.isEmpty()) { + for (var listener : eventListeners) { + listener.accept(scope, Message.create((Notification) o[0], this.identity.getId())); + } } } - if (messageBus != null) { if (o.length == 1 && o[0] instanceof Message) { messageBus.post(message = (Message) o[0]); @@ -240,19 +244,5 @@ public void setWaitTime(int waitTime) { public void setIdentity(Identity identity) { this.identity = identity; } - public BiConsumer getNotificationConsumer() { - return notificationConsumer; - } - - public void setNotificationConsumer(BiConsumer notificationConsumer) { - this.notificationConsumer = notificationConsumer; - } - public BiConsumer getSendConsumer() { - return sendConsumer; - } - - public void setSendConsumer(BiConsumer sendConsumer) { - this.sendConsumer = sendConsumer; - } } diff --git a/klab.services.core/src/main/java/org/integratedmodelling/klab/services/base/BaseService.java b/klab.services.core/src/main/java/org/integratedmodelling/klab/services/base/BaseService.java index a4a48bba7..ec2a70862 100644 --- a/klab.services.core/src/main/java/org/integratedmodelling/klab/services/base/BaseService.java +++ b/klab.services.core/src/main/java/org/integratedmodelling/klab/services/base/BaseService.java @@ -15,16 +15,22 @@ public abstract class BaseService implements KlabService { private static final long serialVersionUID = 1646569587945609013L; protected ServiceScope scope; + protected String localName = "Embedded"; protected List> eventListeners = new ArrayList<>(); - protected BaseService(ServiceScope scope, BiConsumer...eventListeners) { + protected BaseService(ServiceScope scope, String localName, BiConsumer...eventListeners) { this.scope = scope; + this.localName = localName; if (eventListeners != null) { Arrays.stream(eventListeners).map(e -> this.eventListeners.add(e)); } } + public String localName() { + return localName; + } + @Override public ServiceScope scope() { return scope; diff --git a/klab.services.engine/src/main/java/org/integratedmodelling/klab/services/engine/EngineService.java b/klab.services.engine/src/main/java/org/integratedmodelling/klab/services/engine/EngineService.java index e7c433e28..d8467ba1d 100644 --- a/klab.services.engine/src/main/java/org/integratedmodelling/klab/services/engine/EngineService.java +++ b/klab.services.engine/src/main/java/org/integratedmodelling/klab/services/engine/EngineService.java @@ -45,9 +45,18 @@ public class EngineService { private List> eventListeners = new ArrayList<>(); public EngineService(BiConsumer... eventListeners) { + if (eventListeners != null) { - Arrays.stream(eventListeners).map(e -> this.eventListeners.add(e)); + for (var e : eventListeners) { + this.eventListeners.add(e); + } } + + /* + * boot the actor system right away, so that we can call login() before boot(). + */ + this.actorSystem = new ReActorSystem(ReActorSystemConfig.newBuilder().setReactorSystemName("klab").build()) + .initReActorSystem(); } /** @@ -59,11 +68,6 @@ public void boot() { if (!booted) { booted = true; - /* - * boot the actor system - */ - this.actorSystem = new ReActorSystem(ReActorSystemConfig.newBuilder().setReactorSystemName("klab").build()) - .initReActorSystem(); if (defaultReasoner == null || defaultResourcesService == null || defaultResolver == null || defaultRuntime == null) { throw new KIllegalStateException("one or more services are not available: cannot boot the engine"); diff --git a/klab.services.reasoner/src/main/java/org/integratedmodelling/klab/services/reasoner/ReasonerCapabilities.java b/klab.services.reasoner/src/main/java/org/integratedmodelling/klab/services/reasoner/ReasonerCapabilities.java index f8ace898b..6dd524c91 100644 --- a/klab.services.reasoner/src/main/java/org/integratedmodelling/klab/services/reasoner/ReasonerCapabilities.java +++ b/klab.services.reasoner/src/main/java/org/integratedmodelling/klab/services/reasoner/ReasonerCapabilities.java @@ -1,5 +1,6 @@ package org.integratedmodelling.klab.services.reasoner; +import org.integratedmodelling.klab.api.services.KlabService; import org.integratedmodelling.klab.api.services.Reasoner; public class ReasonerCapabilities implements Reasoner.Capabilities { @@ -12,6 +13,11 @@ public class ReasonerCapabilities implements Reasoner.Capabilities { */ private static final long serialVersionUID = -1430274296197650332L; + @Override + public KlabService.Type getType() { + return KlabService.Type.REASONER; + } + public String getLocalName() { return localName; } @@ -28,4 +34,6 @@ public void setServiceName(String serviceName) { this.serviceName = serviceName; } + + } diff --git a/klab.services.reasoner/src/main/java/org/integratedmodelling/klab/services/reasoner/ReasonerService.java b/klab.services.reasoner/src/main/java/org/integratedmodelling/klab/services/reasoner/ReasonerService.java index 680880ba9..e1ab9404c 100644 --- a/klab.services.reasoner/src/main/java/org/integratedmodelling/klab/services/reasoner/ReasonerService.java +++ b/klab.services.reasoner/src/main/java/org/integratedmodelling/klab/services/reasoner/ReasonerService.java @@ -110,7 +110,6 @@ public class ReasonerService extends BaseService implements Reasoner, Reasoner.A static public final int ACCEPT_SUBJECTIVE_OBSERVABLES = 0x10; private String url; - private String localName; private ReasonerConfiguration configuration = new ReasonerConfiguration(); private Map coreConceptPeers = new HashMap<>(); private Map emergent = new HashMap<>(); @@ -249,8 +248,8 @@ private void checkScope(Concept trigger, Map map, Conce } @Autowired - public ReasonerService(Authentication authenticationService, ServiceScope scope, BiConsumer... messageListeners) { - super(scope, messageListeners); + public ReasonerService(Authentication authenticationService, ServiceScope scope, String localName, BiConsumer... messageListeners) { + super(scope, localName,messageListeners); this.authenticationService = authenticationService; this.scope = scope; this.owl = new OWL(scope); @@ -262,6 +261,8 @@ public ReasonerService(Authentication authenticationService, ServiceScope scope, @Override public void initializeService() { + scope().send(Message.MessageClass.ServiceLifecycle, Message.MessageType.ServiceInitializing, capabilities()); + File config = new File(Configuration.INSTANCE.getDataPath() + File.separator + "reasoner.yaml"); if (config.exists()) { configuration = Utils.YAML.load(config, ReasonerConfiguration.class); @@ -273,6 +274,8 @@ public void initializeService() { this.observationReasoner = new ObservationReasoner(this); + scope().send(Message.MessageClass.ServiceLifecycle, Message.MessageType.ServiceAvailable, capabilities()); + } @SuppressWarnings("unchecked") @@ -2407,6 +2410,8 @@ public SemanticSearchResponse semanticSearch(SemanticSearchRequest request) { @Override public boolean shutdown() { + + scope().send(Message.MessageClass.ServiceLifecycle, Message.MessageType.ServiceUnavailable, capabilities()); // TODO Auto-generated method stub return false; } diff --git a/klab.services.reasoner/src/test/java/org/integratedmodelling/tests/services/reasoner/ReasonerTestSetup.java b/klab.services.reasoner/src/test/java/org/integratedmodelling/tests/services/reasoner/ReasonerTestSetup.java index a01a0bc67..099ce0798 100644 --- a/klab.services.reasoner/src/test/java/org/integratedmodelling/tests/services/reasoner/ReasonerTestSetup.java +++ b/klab.services.reasoner/src/test/java/org/integratedmodelling/tests/services/reasoner/ReasonerTestSetup.java @@ -160,8 +160,8 @@ public void stop() { } }; - reasonerService = new ReasonerService(authenticationService, scope); - resourcesService = new ResourcesProvider(authenticationService, scope); + reasonerService = new ReasonerService(authenticationService, scope, "Test reasoner"); + resourcesService = new ResourcesProvider(authenticationService, scope, "Test resources"); resourcesService.initializeService(); reasonerService.initializeService(); // ensure the test worldview is there or set from git repo diff --git a/klab.services.resolver.server/src/main/java/org/integratedmodelling/klab/services/resolver/ResolverService.java b/klab.services.resolver.server/src/main/java/org/integratedmodelling/klab/services/resolver/ResolverService.java index 30ae598a7..3e36e2bad 100644 --- a/klab.services.resolver.server/src/main/java/org/integratedmodelling/klab/services/resolver/ResolverService.java +++ b/klab.services.resolver.server/src/main/java/org/integratedmodelling/klab/services/resolver/ResolverService.java @@ -1,7 +1,5 @@ package org.integratedmodelling.klab.services.resolver; -import java.util.List; - import org.integratedmodelling.klab.api.knowledge.Knowledge; import org.integratedmodelling.klab.api.knowledge.Model; import org.integratedmodelling.klab.api.knowledge.Observable; @@ -15,6 +13,8 @@ import org.integratedmodelling.klab.api.services.resources.ResourceSet; import org.integratedmodelling.klab.api.services.runtime.Dataflow; +import java.util.List; + public class ResolverService implements Resolver, Resolver.Admin { @Override @@ -49,7 +49,6 @@ public boolean loadKnowledge(ResourceSet resources) { @Override public Capabilities capabilities() { - // TODO Auto-generated method stub return null; } diff --git a/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/ResolverService.java b/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/ResolverService.java index 84144a4a9..358730680 100644 --- a/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/ResolverService.java +++ b/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/ResolverService.java @@ -64,8 +64,9 @@ public class ResolverService extends BaseService implements Resolver { Parameters defines = Parameters.createSynchronized(); @Autowired - public ResolverService(Authentication authentication, ServiceScope scope, BiConsumer... messageListeners) { - super(scope, messageListeners); + public ResolverService(Authentication authentication, ServiceScope scope, String localName, + BiConsumer... messageListeners) { + super(scope, localName, messageListeners); } @Override @@ -82,14 +83,33 @@ public String getLocalName() { @Override public boolean shutdown() { + + scope().send(Message.MessageClass.ServiceLifecycle, Message.MessageType.ServiceUnavailable, + capabilities()); + // TODO Auto-generated method stub return false; } @Override public Capabilities capabilities() { - // TODO Auto-generated method stub - return null; +// TODO Auto-generated method stub + return new Capabilities() { + @Override + public Type getType() { + return Type.RESOLVER; + } + + @Override + public String getLocalName() { + return localName; + } + + @Override + public String getServiceName() { + return "Reasoner"; + } + }; } /** @@ -632,6 +652,9 @@ public List queryModels(Observable observable, ContextScope scope, Scale @Override public void initializeService() { + scope().send(Message.MessageClass.ServiceLifecycle, Message.MessageType.ServiceInitializing, + capabilities()); + /* * Components */ @@ -651,6 +674,10 @@ public void initializeService() { Configuration.INSTANCE.scanPackage(pack, Maps.of(Library.class, Configuration.INSTANCE.LIBRARY_LOADER)); } + + scope().send(Message.MessageClass.ServiceLifecycle, Message.MessageType.ServiceAvailable, + capabilities()); + } @Override diff --git a/klab.services.resources/src/main/java/org/integratedmodelling/klab/services/resources/ResourcesProvider.java b/klab.services.resources/src/main/java/org/integratedmodelling/klab/services/resources/ResourcesProvider.java index 26d3d7b51..e001bc24e 100644 --- a/klab.services.resources/src/main/java/org/integratedmodelling/klab/services/resources/ResourcesProvider.java +++ b/klab.services.resources/src/main/java/org/integratedmodelling/klab/services/resources/ResourcesProvider.java @@ -9,6 +9,7 @@ import org.integratedmodelling.kim.model.Kim; import org.integratedmodelling.kim.model.KimLoader; import org.integratedmodelling.kim.model.KimLoader.NamespaceDescriptor; +import org.integratedmodelling.klab.api.authentication.CRUDPermission; import org.integratedmodelling.klab.api.authentication.ResourcePrivileges; import org.integratedmodelling.klab.api.collections.Pair; import org.integratedmodelling.klab.api.collections.Parameters; @@ -36,7 +37,6 @@ import org.integratedmodelling.klab.api.services.resolver.Coverage; import org.integratedmodelling.klab.api.services.resources.ResourceSet; import org.integratedmodelling.klab.api.services.resources.ResourceStatus; -import org.integratedmodelling.klab.api.services.resources.ResourceStatus.Type; import org.integratedmodelling.klab.api.services.runtime.Message; import org.integratedmodelling.klab.configuration.Configuration; import org.integratedmodelling.klab.rest.ResourceReference; @@ -78,8 +78,6 @@ public class ResourcesProvider extends BaseService implements ResourcesService, private static boolean languagesInitialized; private String url; - private String localName; - private KimLoader kimLoader; private ResourcesConfiguration configuration = new ResourcesConfiguration(); private Authentication authenticationService; @@ -124,9 +122,9 @@ public class ResourcesProvider extends BaseService implements ResourcesService, * If this is used, {@link #loadWorkspaces()} must be called explicitly after the service scope is set. */ @SuppressWarnings("unchecked") - public ResourcesProvider(ServiceScope scope, BiConsumer... messageListeners) { - super(scope, messageListeners); - this.localName = "klab.services.resources." + UUID.randomUUID(); + public ResourcesProvider(ServiceScope scope, String localName, + BiConsumer... messageListeners) { + super(scope, localName, messageListeners); // Services.INSTANCE.setResources(this); initializeLanguageServices(); @@ -144,18 +142,23 @@ public ResourcesProvider(ServiceScope scope, BiConsumer... messa } @Autowired - public ResourcesProvider(Authentication authenticationService, ServiceScope scope, BiConsumer... messageListeners) { - this(scope, messageListeners); + public ResourcesProvider(Authentication authenticationService, ServiceScope scope, String localName, BiConsumer... messageListeners) { + this(scope, localName,messageListeners); this.authenticationService = authenticationService; } @Override public void initializeService() { + scope().send(Message.MessageClass.ServiceLifecycle, Message.MessageType.ServiceInitializing, + capabilities()); this.kbox = ModelKbox.create(localName, this.scope); updateProjects(); /* * TODO launch update service */ + scope().send(Message.MessageClass.ServiceLifecycle, Message.MessageType.ServiceAvailable, + capabilities()); } private void saveConfiguration() { @@ -313,9 +316,8 @@ public boolean accept(File pathname) { status.setReviewStatus(level); status.setFileLocation(subdir); status.setType(Utils.Notifications.hasErrors(resource.getNotifications()) ? - Type.OFFLINE - : - Type.AVAILABLE); + ResourceStatus.Type.OFFLINE : + ResourceStatus.Type.AVAILABLE); status.setLegacy(legacy); status.setKnowledgeClass(KnowledgeClass.RESOURCE); // TODO fill in the rest @@ -677,6 +679,10 @@ public boolean shutdown() { } public boolean shutdown(int secondsToWait) { + + scope().send(Message.MessageClass.ServiceLifecycle, Message.MessageType.ServiceUnavailable, + capabilities()); + // try { // projectLoader.awaitTermination(secondsToWait, TimeUnit.SECONDS); return true; @@ -688,8 +694,40 @@ public boolean shutdown(int secondsToWait) { @Override public Capabilities capabilities() { - // TODO Auto-generated method stub - return null; + return new Capabilities() { + @Override + public boolean isWorldviewProvider() { + // TODO + return false; + } + + @Override + public String getAdoptedWorldview() { + // TODO + return null; + } + + @Override + public Set getPermissions() { + // TODO + return EnumSet.noneOf(CRUDPermission.class); + } + + @Override + public Type getType() { + return Type.RESOURCES; + } + + @Override + public String getLocalName() { + return localName; + } + + @Override + public String getServiceName() { + return null; + } + }; } @Override @@ -832,7 +870,8 @@ public String createResource(File resourcePath) { } @Override - public Resource createResource(String projectName, String urnId, String adapter, Parameters resourceData) { + public Resource createResource(String projectName, String urnId, String adapter, + Parameters resourceData) { return null; } diff --git a/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/RuntimeService.java b/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/RuntimeService.java index 8f84edc13..071c1faed 100644 --- a/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/RuntimeService.java +++ b/klab.services.runtime/src/main/java/org/integratedmodelling/klab/services/runtime/RuntimeService.java @@ -1,13 +1,7 @@ package org.integratedmodelling.klab.services.runtime; -import java.io.IOException; -import java.util.*; -import java.util.concurrent.Future; -import java.util.function.BiConsumer; - import org.apache.groovy.util.Maps; import org.integratedmodelling.klab.api.exceptions.KInternalErrorException; -import org.integratedmodelling.klab.api.knowledge.Observable; import org.integratedmodelling.klab.api.knowledge.observation.Observation; import org.integratedmodelling.klab.api.lang.ServiceCall; import org.integratedmodelling.klab.api.scope.ContextScope; @@ -23,6 +17,11 @@ import org.integratedmodelling.klab.services.runtime.digitaltwin.DigitalTwin; import org.integratedmodelling.klab.services.runtime.tasks.ObservationTask; +import java.io.IOException; +import java.util.*; +import java.util.concurrent.Future; +import java.util.function.BiConsumer; + public class RuntimeService extends BaseService implements org.integratedmodelling.klab.api.services.RuntimeService, @@ -34,13 +33,16 @@ public class RuntimeService extends BaseService */ Map digitalTwins = Collections.synchronizedMap(new HashMap<>()); - public RuntimeService(Authentication testAuthentication, ServiceScope scope, BiConsumer... messageListeners) { + public RuntimeService(Authentication testAuthentication, ServiceScope scope, String localName, BiConsumer... messageListeners) { // TODO Auto-generated constructor stub - super(scope, messageListeners); + super(scope, localName,messageListeners); } @Override public void initializeService() { + + scope().send(Message.MessageClass.ServiceLifecycle, Message.MessageType.ServiceInitializing, capabilities()); + /* * Components */ @@ -61,6 +63,8 @@ public void initializeService() { Configuration.INSTANCE.scanPackage(pack, Maps.of(Library.class, Configuration.INSTANCE.LIBRARY_LOADER)); } + scope().send(Message.MessageClass.ServiceLifecycle, Message.MessageType.ServiceAvailable, capabilities()); + } @Override @@ -77,14 +81,31 @@ public String getLocalName() { @Override public boolean shutdown() { + + scope().send(Message.MessageClass.ServiceLifecycle, Message.MessageType.ServiceUnavailable, capabilities()); + // TODO Auto-generated method stub return false; } @Override public Capabilities capabilities() { - // TODO Auto-generated method stub - return null; + return new Capabilities() { + @Override + public Type getType() { + return Type.RUNTIME; + } + + @Override + public String getLocalName() { + return localName; + } + + @Override + public String getServiceName() { + return "Runtime"; + } + }; } @Override