Skip to content

Commit

Permalink
EMF can provide a prepared model
Browse files Browse the repository at this point in the history
Signed-off-by: Juergen Albert <j.albert@data-in-motion.biz>
  • Loading branch information
juergen-albert committed Dec 10, 2023
1 parent 9f9d680 commit ffdeeba
Show file tree
Hide file tree
Showing 15 changed files with 182 additions and 27 deletions.
5 changes: 3 additions & 2 deletions core/impl/integration-test.bndrun
Expand Up @@ -40,12 +40,13 @@
org.eclipse.sensinact.gateway.core.impl-tests;version='[0.0.2,0.0.3)',\
org.eclipse.sensinact.gateway.core.models.metadata;version='[0.0.2,0.0.3)',\
org.eclipse.sensinact.gateway.core.models.provider;version='[0.0.2,0.0.3)',\
org.gecko.emf.osgi.api;version='[4.6.2,4.6.3)',\
org.gecko.emf.osgi.component;version='[4.6.2,4.6.3)',\
org.gecko.emf.osgi.api;version='[5.0.0,5.0.1)',\
org.gecko.emf.osgi.component;version='[5.0.0,5.0.1)',\
org.mockito.junit-jupiter;version='[4.7.0,4.7.1)',\
org.mockito.mockito-core;version='[4.7.0,4.7.1)',\
org.objenesis;version='[3.2.0,3.2.1)',\
org.opentest4j;version='[1.2.0,1.2.1)',\
org.osgi.service.cm;version='[1.6.1,1.6.2)',\
org.osgi.service.component;version='[1.5.0,1.5.1)',\
org.osgi.service.typedevent;version='[1.0.0,1.0.1)',\
org.osgi.test.common;version='[1.2.1,1.2.2)',\
Expand Down
Expand Up @@ -27,19 +27,20 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.sensinact.core.command.AbstractSensinactCommand;
import org.eclipse.sensinact.core.command.GatewayThread;
import org.eclipse.sensinact.core.metrics.IMetricTimer;
import org.eclipse.sensinact.core.metrics.IMetricsManager;
import org.eclipse.sensinact.core.notification.NotificationAccumulator;
import org.eclipse.sensinact.model.core.provider.ProviderPackage;
import org.eclipse.sensinact.core.model.impl.SensinactModelManagerImpl;
import org.eclipse.sensinact.core.model.nexus.ModelNexus;
import org.eclipse.sensinact.core.notification.NotificationAccumulator;
import org.eclipse.sensinact.core.notification.impl.ImmediateNotificationAccumulator;
import org.eclipse.sensinact.core.notification.impl.NotificationAccumulatorImpl;
import org.eclipse.sensinact.core.twin.impl.SensinactDigitalTwinImpl;
import org.eclipse.sensinact.core.whiteboard.impl.SensinactWhiteboard;
import org.eclipse.sensinact.model.core.provider.ProviderPackage;
import org.osgi.service.component.AnyService;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
Expand Down Expand Up @@ -76,14 +77,12 @@ public class GatewayThreadImpl extends Thread implements GatewayThread {
private IMetricsManager metrics;

@Activate
public GatewayThreadImpl(
@Reference IMetricsManager metrics,
@Reference TypedEventBus typedEventBus, @Reference ResourceSet resourceSet,
@Reference ProviderPackage ProviderPackage) {
public GatewayThreadImpl(@Reference IMetricsManager metrics, @Reference TypedEventBus typedEventBus,
@Reference ResourceSet resourceSet, @Reference ProviderPackage providerPackage) {
this.metrics = metrics;
this.typedEventBus = typedEventBus;
this.whiteboard = new SensinactWhiteboard(this, metrics);
nexusImpl = new ModelNexus(resourceSet, ProviderPackage, this::getCurrentAccumulator, whiteboard);
nexusImpl = new ModelNexus(resourceSet, providerPackage, this::getCurrentAccumulator, whiteboard);
start();
}

Expand Down Expand Up @@ -120,6 +119,15 @@ void deactivate() {
}
}

@Reference(cardinality = MULTIPLE, policy = DYNAMIC)
void addEPackage(EPackage ePackage) {
nexusImpl.addEPackage(ePackage);
}

void removeEPackage(EPackage ePackage) {
nexusImpl.removeEPackage(ePackage);
}

@Reference(service = AnyService.class, target = "(sensiNact.whiteboard.resource=true)", cardinality = MULTIPLE, policy = DYNAMIC)
void addWhiteboardService(Object service, Map<String, Object> props) {
whiteboard.addWhiteboardService(service, props);
Expand Down
Expand Up @@ -51,9 +51,15 @@
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.sensinact.core.command.impl.ActionHandler;
import org.eclipse.sensinact.core.command.impl.ResourcePullHandler;
import org.eclipse.sensinact.core.command.impl.ResourcePushHandler;
import org.eclipse.sensinact.core.model.ResourceType;
import org.eclipse.sensinact.core.model.nexus.emf.EMFUtil;
import org.eclipse.sensinact.core.model.nexus.emf.compare.EMFCompareUtil;
import org.eclipse.sensinact.core.notification.NotificationAccumulator;
import org.eclipse.sensinact.core.twin.TimedValue;
import org.eclipse.sensinact.core.whiteboard.impl.SensinactWhiteboard;
import org.eclipse.sensinact.model.core.metadata.Action;
import org.eclipse.sensinact.model.core.metadata.ActionParameter;
import org.eclipse.sensinact.model.core.metadata.AnnotationMetadata;
Expand All @@ -67,12 +73,6 @@
import org.eclipse.sensinact.model.core.provider.ProviderFactory;
import org.eclipse.sensinact.model.core.provider.ProviderPackage;
import org.eclipse.sensinact.model.core.provider.Service;
import org.eclipse.sensinact.core.command.impl.ActionHandler;
import org.eclipse.sensinact.core.command.impl.ResourcePullHandler;
import org.eclipse.sensinact.core.command.impl.ResourcePushHandler;
import org.eclipse.sensinact.core.model.nexus.emf.EMFUtil;
import org.eclipse.sensinact.core.model.nexus.emf.compare.EMFCompareUtil;
import org.eclipse.sensinact.core.whiteboard.impl.SensinactWhiteboard;
import org.osgi.util.promise.Promise;
import org.osgi.util.promise.Promises;
import org.slf4j.Logger;
Expand Down Expand Up @@ -135,7 +135,8 @@ public Promise<Object> act(String model, String provider, String service, String
public <T> Promise<TimedValue<T>> pullValue(String model, String provider, String service, String resource,
Class<T> type, TimedValue<T> cachedValue, Consumer<TimedValue<T>> gatewayUpdate) {
if (resourceValuePullHandler != null) {
return resourceValuePullHandler.pullValue(model, provider, service, resource, type, cachedValue, gatewayUpdate);
return resourceValuePullHandler.pullValue(model, provider, service, resource, type, cachedValue,
gatewayUpdate);
}
throw new RuntimeException("No pullValue handler set");
}
Expand Down Expand Up @@ -898,4 +899,29 @@ public EClass registerModel(EClass modelEClass, Instant timestamp) {
models.put(EMFUtil.getModelName(modelEClass), modelEClass);
return null;
}

/**
* @param ePackage a registered {@link EPackage} to scan for registered
* Provideres
*/
public void addEPackage(EPackage ePackage) {
if (ePackage != providerPackage) {
ePackage.getEClassifiers().stream().filter(EClass.class::isInstance).map(EClass.class::cast)
.filter(ProviderPackage.Literals.PROVIDER::isSuperTypeOf)
.forEach(ec -> models.put(EcoreUtil.getURI(ec).toString(), ec));
}
}

/**
* TODO how do we handle existing Instances of such a model?
*
* @param ePackage a registered {@link EPackage} to remove
*/
public void removeEPackage(EPackage ePackage) {
if (ePackage != providerPackage) {
ePackage.getEClassifiers().stream().filter(EClass.class::isInstance).map(EClass.class::cast)
.filter(ProviderPackage.Literals.PROVIDER::isSuperTypeOf)
.forEach(ec -> models.remove(EcoreUtil.getURI(ec).toString()));
}
}
}
Expand Up @@ -18,6 +18,7 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.IOException;
import java.io.InputStream;
Expand All @@ -33,11 +34,13 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
Expand All @@ -50,14 +53,14 @@
import org.eclipse.emf.ecore.resource.impl.URIMappingRegistryImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.sensinact.core.emf.util.EMFTestUtil;
import org.eclipse.sensinact.core.model.nexus.ModelNexus;
import org.eclipse.sensinact.core.model.nexus.emf.EMFUtil;
import org.eclipse.sensinact.core.notification.NotificationAccumulator;
import org.eclipse.sensinact.model.core.provider.Admin;
import org.eclipse.sensinact.model.core.provider.Provider;
import org.eclipse.sensinact.model.core.provider.ProviderPackage;
import org.eclipse.sensinact.model.core.provider.Service;
import org.eclipse.sensinact.core.emf.util.EMFTestUtil;
import org.eclipse.sensinact.core.model.nexus.ModelNexus;
import org.eclipse.sensinact.core.model.nexus.emf.EMFUtil;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
Expand Down Expand Up @@ -734,4 +737,110 @@ void pushEObjectTestSimpleAttributeChange() throws IOException, InterruptedExcep
assertEquals(testAdminEClass, savedAgain.getAdmin().eClass());
}
}

@Nested
public class EPackageTests {

private ModelNexus nexus;
private EPackage ePackage;

@BeforeEach
public void setup() throws IOException {
URI ProviderPackageURI = URI.createURI(ProviderPackage.eNS_URI);

URIMappingRegistryImpl.INSTANCE.put(
URI.createURI("https://eclipse.org/../../../models/src/main/resources/model/sensinact.ecore"),
ProviderPackageURI);

XMLResource.URIHandler handler = new XMLResource.URIHandler() {

@Override
public URI deresolve(URI arg0) {
return arg0;
}

@Override
public URI resolve(URI arg0) {
if (arg0.lastSegment().equals("sensinact.ecore")) {
return ProviderPackageURI.appendFragment(arg0.fragment());
}
return arg0;
}

@Override
public void setBaseURI(URI arg0) {
// TODO Auto-generated method stub
}
};

nexus = new ModelNexus(resourceSet, ProviderPackage.eINSTANCE, () -> accumulator);

Resource extendedPackageResource = resourceSet
.createResource(URI.createURI("https://eclipse.org/sensinact/test/1.0"));
InputStream ín = getClass().getResourceAsStream("/model/extended.ecore");

assertNotNull(ín);

extendedPackageResource.load(ín, Collections.singletonMap(XMLResource.OPTION_URI_HANDLER, handler));

ePackage = (EPackage) extendedPackageResource.getContents().get(0);

assertNotNull(ePackage);
}

@Test
void addModelEPackage() throws IOException, InterruptedException {
URI uri = EcoreUtil.getURI(ePackage.getEClassifier("TemperatureSensor"));
Optional<EClass> model = nexus.getModel(uri.toString());

assertTrue(model.isEmpty());

nexus.addEPackage(ePackage);

model = nexus.getModel(uri.toString());

assertTrue(model.isPresent());
}

@Test
void removeModelEPackage() throws IOException, InterruptedException {
URI uri = EcoreUtil.getURI(ePackage.getEClassifier("TemperatureSensor"));
Optional<EClass> model = nexus.getModel(uri.toString());

assertTrue(model.isEmpty());

nexus.addEPackage(ePackage);

model = nexus.getModel(uri.toString());

assertTrue(model.isPresent());

nexus.removeEPackage(ePackage);

model = nexus.getModel(uri.toString());

assertTrue(model.isEmpty());
}

@Test
void checkInstance() throws IOException, InterruptedException {
EClassifier eClassifier = ePackage.getEClassifier("TemperatureSensor");
URI uri = EcoreUtil.getURI(ePackage.getEClassifier("TemperatureSensor"));
Optional<EClass> model = nexus.getModel(uri.toString());

assertTrue(model.isEmpty());

nexus.addEPackage(ePackage);

model = nexus.getModel(uri.toString());

assertTrue(model.isPresent());

Provider provider = nexus.createProviderInstance(uri.toString(), "test");

assertNotNull(provider);
assertEquals(eClassifier, provider.eClass());
}

}
}
1 change: 1 addition & 0 deletions northbound/filters/ldap/integration-test.bndrun
Expand Up @@ -46,6 +46,7 @@
org.gecko.emf.osgi.api;version='[4.6.2,4.6.3)',\
org.gecko.emf.osgi.component;version='[4.6.2,4.6.3)',\
org.opentest4j;version='[1.2.0,1.2.1)',\
org.osgi.service.cm;version='[1.6.1,1.6.2)',\
org.osgi.service.component;version='[1.5.0,1.5.1)',\
org.osgi.service.typedevent;version='[1.0.0,1.0.1)',\
org.osgi.test.common;version='[1.2.1,1.2.2)',\
Expand Down
1 change: 1 addition & 0 deletions northbound/query-handler/integration-test.bndrun
Expand Up @@ -43,6 +43,7 @@
org.gecko.emf.osgi.api;version='[4.6.2,4.6.3)',\
org.gecko.emf.osgi.component;version='[4.6.2,4.6.3)',\
org.opentest4j;version='[1.2.0,1.2.1)',\
org.osgi.service.cm;version='[1.6.1,1.6.2)',\
org.osgi.service.component;version='[1.5.0,1.5.1)',\
org.osgi.service.typedevent;version='[1.0.0,1.0.1)',\
org.osgi.test.common;version='[1.2.1,1.2.2)',\
Expand Down
1 change: 1 addition & 0 deletions northbound/rest/integration-test.bndrun
Expand Up @@ -96,6 +96,7 @@
org.glassfish.jersey.media.jersey-media-sse;version='[3.0.8,3.0.9)',\
org.objectweb.asm;version='[9.3.0,9.3.1)',\
org.opentest4j;version='[1.2.0,1.2.1)',\
org.osgi.service.cm;version='[1.6.1,1.6.2)',\
org.osgi.service.component;version='[1.5.0,1.5.1)',\
org.osgi.service.jakartars;version='[2.0.0,2.0.1)',\
org.osgi.service.typedevent;version='[1.0.0,1.0.1)',\
Expand Down
1 change: 1 addition & 0 deletions northbound/security/openid-connect/integration-test.bndrun
Expand Up @@ -45,6 +45,7 @@
org.mockito.mockito-core;version='[4.7.0,4.7.1)',\
org.objenesis;version='[3.2.0,3.2.1)',\
org.opentest4j;version='[1.2.0,1.2.1)',\
org.osgi.service.cm;version='[1.6.1,1.6.2)',\
org.osgi.service.component;version='[1.5.0,1.5.1)',\
org.osgi.test.common;version='[1.2.1,1.2.2)',\
org.osgi.test.junit5;version='[1.2.1,1.2.2)',\
Expand Down
1 change: 1 addition & 0 deletions northbound/sensorthings/mqtt/integration-test.bndrun
Expand Up @@ -57,6 +57,7 @@
org.gecko.emf.osgi.api;version='[4.6.2,4.6.3)',\
org.gecko.emf.osgi.component;version='[4.6.2,4.6.3)',\
org.opentest4j;version='[1.2.0,1.2.1)',\
org.osgi.service.cm;version='[1.6.1,1.6.2)',\
org.osgi.service.component;version='[1.5.0,1.5.1)',\
org.osgi.service.typedevent;version='[1.0.0,1.0.1)',\
org.osgi.test.common;version='[1.2.1,1.2.2)',\
Expand Down
Expand Up @@ -105,6 +105,7 @@
org.objectweb.asm;version='[9.3.0,9.3.1)',\
org.objenesis;version='[3.2.0,3.2.1)',\
org.opentest4j;version='[1.2.0,1.2.1)',\
org.osgi.service.cm;version='[1.6.1,1.6.2)',\
org.osgi.service.component;version='[1.5.0,1.5.1)',\
org.osgi.service.jakartars;version='[2.0.0,2.0.1)',\
org.osgi.service.typedevent;version='[1.0.0,1.0.1)',\
Expand Down
1 change: 1 addition & 0 deletions northbound/websocket/integration-test.bndrun
Expand Up @@ -85,6 +85,7 @@
org.gecko.emf.osgi.component;version='[4.6.2,4.6.3)',\
org.objectweb.asm;version='[9.4.0,9.4.1)',\
org.opentest4j;version='[1.2.0,1.2.1)',\
org.osgi.service.cm;version='[1.6.1,1.6.2)',\
org.osgi.service.component;version='[1.5.0,1.5.1)',\
org.osgi.service.typedevent;version='[1.0.0,1.0.1)',\
org.osgi.test.common;version='[1.2.1,1.2.2)',\
Expand Down
5 changes: 3 additions & 2 deletions southbound/history/timescale-provider/integration-test.bndrun
Expand Up @@ -46,12 +46,13 @@
org.eclipse.sensinact.gateway.southbound.history.history-api;version='[0.0.2,0.0.3)',\
org.eclipse.sensinact.gateway.southbound.history.timescale-provider;version='[0.0.2,0.0.3)',\
org.eclipse.sensinact.gateway.southbound.history.timescale-provider-tests;version='[0.0.2,0.0.3)',\
org.gecko.emf.osgi.api;version='[4.6.2,4.6.3)',\
org.gecko.emf.osgi.component;version='[4.6.2,4.6.3)',\
org.gecko.emf.osgi.api;version='[5.0.0,5.0.1)',\
org.gecko.emf.osgi.component;version='[5.0.0,5.0.1)',\
org.mockito.junit-jupiter;version='[4.7.0,4.7.1)',\
org.mockito.mockito-core;version='[4.7.0,4.7.1)',\
org.objenesis;version='[3.2.0,3.2.1)',\
org.opentest4j;version='[1.2.0,1.2.1)',\
org.osgi.service.cm;version='[1.6.1,1.6.2)',\
org.osgi.service.component;version='[1.5.0,1.5.1)',\
org.osgi.service.typedevent;version='[1.0.0,1.0.1)',\
org.osgi.test.common;version='[1.2.1,1.2.2)',\
Expand Down
5 changes: 3 additions & 2 deletions southbound/http/http-device-factory/integration-test.bndrun
Expand Up @@ -56,9 +56,10 @@
org.eclipse.sensinact.gateway.southbound.device-factory.parser-csv;version='[0.0.2,0.0.3)',\
org.eclipse.sensinact.gateway.southbound.http.http-device-factory;version='[0.0.2,0.0.3)',\
org.eclipse.sensinact.gateway.southbound.http.http-device-factory-tests;version='[0.0.2,0.0.3)',\
org.gecko.emf.osgi.api;version='[4.6.2,4.6.3)',\
org.gecko.emf.osgi.component;version='[4.6.2,4.6.3)',\
org.gecko.emf.osgi.api;version='[5.0.0,5.0.1)',\
org.gecko.emf.osgi.component;version='[5.0.0,5.0.1)',\
org.opentest4j;version='[1.2.0,1.2.1)',\
org.osgi.service.cm;version='[1.6.1,1.6.2)',\
org.osgi.service.component;version='[1.5.0,1.5.1)',\
org.osgi.service.typedevent;version='[1.0.0,1.0.1)',\
org.osgi.test.common;version='[1.2.1,1.2.2)',\
Expand Down
5 changes: 3 additions & 2 deletions southbound/mqtt/mqtt-device-factory/integration-test.bndrun
Expand Up @@ -62,9 +62,10 @@
org.eclipse.sensinact.gateway.southbound.mqtt.mqtt-client;version='[0.0.2,0.0.3)',\
org.eclipse.sensinact.gateway.southbound.mqtt.mqtt-device-factory;version='[0.0.2,0.0.3)',\
org.eclipse.sensinact.gateway.southbound.mqtt.mqtt-device-factory-tests;version='[0.0.2,0.0.3)',\
org.gecko.emf.osgi.api;version='[4.6.2,4.6.3)',\
org.gecko.emf.osgi.component;version='[4.6.2,4.6.3)',\
org.gecko.emf.osgi.api;version='[5.0.0,5.0.1)',\
org.gecko.emf.osgi.component;version='[5.0.0,5.0.1)',\
org.opentest4j;version='[1.2.0,1.2.1)',\
org.osgi.service.cm;version='[1.6.1,1.6.2)',\
org.osgi.service.component;version='[1.5.0,1.5.1)',\
org.osgi.service.typedevent;version='[1.0.0,1.0.1)',\
org.osgi.test.common;version='[1.2.1,1.2.2)',\
Expand Down

0 comments on commit ffdeeba

Please sign in to comment.