Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EMF can provide a prepared model #286

Merged
merged 5 commits into from
Dec 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions core/emf-api/dependency-check.bndrun
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
com.fasterxml.jackson.core.jackson-annotations;version='[2.14.0,2.14.1)',\
com.fasterxml.jackson.core.jackson-core;version='[2.14.0,2.14.1)',\
com.fasterxml.jackson.core.jackson-databind;version='[2.14.0,2.14.1)',\
org.apache.felix.configadmin;version='[1.9.24,1.9.25)',\
org.apache.felix.scr;version='[2.2.2,2.2.3)',\
org.eclipse.emf.common;version='[2.28.0,2.28.1)',\
org.eclipse.emf.ecore;version='[2.33.0,2.33.1)',\
Expand All @@ -24,9 +23,7 @@
org.eclipse.sensinact.gateway.core.emf-api;version='[0.0.2,0.0.3)',\
org.eclipse.sensinact.gateway.core.geo-json;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.osgi.service.component;version='[1.5.0,1.5.1)',\
org.osgi.util.converter;version='[1.0.9,1.0.10)',\
org.osgi.util.function;version='[1.1.0,1.1.1)',\
org.osgi.util.promise;version='[1.3.0,1.3.1)'
5 changes: 3 additions & 2 deletions core/impl/integration-test.bndrun
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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()));
}
}
}
Original file line number Diff line number Diff line change
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());
}

}
}
8 changes: 4 additions & 4 deletions core/models/metadata/src/main/resources/model/metadata.ecore
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
<eAnnotations source="http://www.eclipse.org/OCL/Import">
<details key="ecore" value="http://www.eclipse.org/emf/2002/Ecore"/>
</eAnnotations>
<eClassifiers xsi:type="ecore:EClass" name="NexusMetadata" abstract="true" eSuperTypes="../../../../../provider/src/main/resources/model/sensinact.ecore#//Metadata">
<eClassifiers xsi:type="ecore:EClass" name="NexusMetadata" abstract="true" eSuperTypes="../../../../../org.eclipse.sensinact.gateway.core.models.provider/src/main/resources/model/sensinact.ecore#//Metadata">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="locked" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"
defaultValueLiteral="false" unsettable="true"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="originalName" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" unsettable="true"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="AnnotationMetadata" eSuperTypes="#//NexusMetadata"/>
<eClassifiers xsi:type="ecore:EClass" name="ResourceAttribute" eSuperTypes="http://www.eclipse.org/emf/2002/Ecore#//EAttribute #//NexusMetadata">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="resourceType" eType="ecore:EEnum ../../../../../provider/src/main/resources/model/sensinact.ecore#//ResourceType"
<eStructuralFeatures xsi:type="ecore:EAttribute" name="resourceType" eType="ecore:EEnum ../../../../../org.eclipse.sensinact.gateway.core.models.provider/src/main/resources/model/sensinact.ecore#//ResourceType"
defaultValueLiteral="SENSOR"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="valueType" eType="ecore:EEnum ../../../../../provider/src/main/resources/model/sensinact.ecore#//ValueType"
<eStructuralFeatures xsi:type="ecore:EAttribute" name="valueType" eType="ecore:EEnum ../../../../../org.eclipse.sensinact.gateway.core.models.provider/src/main/resources/model/sensinact.ecore#//ValueType"
defaultValueLiteral="MODIFIABLE"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="externalGet" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="externalGetCacheMs" eType="ecore:EDataType ../../../../../org.eclipse.emf.ecore/model/Ecore.ecore#//ELong"
Expand All @@ -30,7 +30,7 @@
<eClassifiers xsi:type="ecore:EClass" name="ServiceReference" eSuperTypes="http://www.eclipse.org/emf/2002/Ecore#//EReference #//NexusMetadata"/>
<eClassifiers xsi:type="ecore:EClass" name="Action" eSuperTypes="http://www.eclipse.org/emf/2002/Ecore#//EOperation #//NexusMetadata"/>
<eClassifiers xsi:type="ecore:EClass" name="ActionParameter" eSuperTypes="http://www.eclipse.org/emf/2002/Ecore#//EParameter">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="timestamp" eType="ecore:EDataType ../../../../../provider/src/main/resources/model/sensinact.ecore#//EInstant"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="timestamp" eType="ecore:EDataType ../../../../../org.eclipse.sensinact.gateway.core.models.provider/src/main/resources/model/sensinact.ecore#//EInstant"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="ResourceMetadata" eSuperTypes="#//NexusMetadata"/>
<eClassifiers xsi:type="ecore:EClass" name="ActionMetadata" eSuperTypes="#//NexusMetadata"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
modelDirectory="/org.eclipse.sensinact.core.model/src/main/java" modelPluginID="org.eclipse.sensinact.core.model"
modelName="sensinact" rootExtendsClass="org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container$Dynamic$Permissive"
importerID="org.eclipse.emf.importer.ecore" complianceLevel="11.0" suppressGenModelAnnotations="false"
copyrightFields="false" usedGenPackages="../../../../../provider/src/main/resources/model/sensinact.genmodel#//provider ../../../../../org.eclipse.emf.ecore/model/Ecore.genmodel#//ecore"
copyrightFields="false" usedGenPackages="../../../../../org.eclipse.emf.ecore/model/Ecore.genmodel#//ecore ../../../../../org.eclipse.sensinact.gateway.core.models.provider/src/main/resources/model/sensinact.genmodel#//provider"
operationReflection="true" importOrganizing="true" oSGiCompatible="true">
<foreignModel>metadata.ecore</foreignModel>
<genPackages prefix="Metadata" basePackage="org.eclipse.sensinact.model.core" disposableProviderFactory="true"
Expand Down
5 changes: 0 additions & 5 deletions core/models/provider/bnd.bnd
Original file line number Diff line number Diff line change
@@ -1,5 +0,0 @@
Provide-Capability: \
org.eclipse.emf.ecore.generated_package;\
class="org.eclipse.sensinact.model.core.SensiNactPackage";\
uri="https://eclipse.org/sensinact/core/1.0";\
genModel="/model/sensinact.genmodel"
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
modelDirectory="/org.eclipse.sensinact.core.model/src" modelPluginID="org.eclipse.sensinact.core.model"
modelName="sensinact" rootExtendsClass="org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container$Dynamic$Permissive"
importerID="org.eclipse.emf.importer.ecore" complianceLevel="11.0" suppressGenModelAnnotations="false"
copyrightFields="false" usedGenPackages="../../../../../org.eclipse.emf.ecore/model/Ecore.genmodel#//ecore"
operationReflection="true" importOrganizing="true" oSGiCompatible="true">
copyrightFields="false" operationReflection="true" importOrganizing="true" oSGiCompatible="true">
<foreignModel>sensinact.ecore</foreignModel>
<genPackages prefix="Provider" basePackage="org.eclipse.sensinact.model.core" resource="XMI"
disposableProviderFactory="true" ecorePackage="sensinact.ecore#/">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
{ "id": "org.eclipse.emf:org.eclipse.emf.ecore:2.33.0" },
{ "id": "org.eclipse.emf:org.eclipse.emf.ecore.xmi:2.18.0" },
{ "id": "org.slf4j:log4j-over-slf4j:1.7.36" },
{ "id": "org.geckoprojects.emf:org.gecko.emf.osgi.api:4.6.2" },
{ "id": "org.geckoprojects.emf:org.gecko.emf.osgi.component:4.6.2" },
{ "id": "org.geckoprojects.emf:org.gecko.emf.osgi.api:5.0.0" },
{ "id": "org.geckoprojects.emf:org.gecko.emf.osgi.component:5.0.0" },
{ "id": "org.apache.aries.component-dsl:org.apache.aries.component-dsl.component-dsl:1.2.2" },
{ "id": "org.apache.aries.typedevent:org.apache.aries.typedevent.bus:0.0.2-SNAPSHOT" },
{ "id": "io.dropwizard.metrics:metrics-core:4.2.19" }
Expand Down
Loading
Loading