Merge branch 'dev' into mkoller/atfxadapter
Conflicts:
build.gradle
Signed-off-by: Matthias Koller <m.koller@peak-solution.de>
diff --git a/build.gradle b/build.gradle
index 8d14f8d..9d4e1dc 100644
--- a/build.gradle
+++ b/build.gradle
@@ -14,7 +14,7 @@
description = 'MDM API - ODSAdapter'
group = 'org.eclipse.mdm'
-version = '5.1.0M8-SNAPSHOT'
+version = '5.1.0M8-ATFX-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'maven'
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java
index f01c859..527a186 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java
@@ -44,6 +44,8 @@
import org.eclipse.mdm.api.base.model.Environment;
import org.eclipse.mdm.api.base.model.MeasuredValues;
import org.eclipse.mdm.api.base.model.StatusAttachable;
+import org.eclipse.mdm.api.base.model.Test;
+import org.eclipse.mdm.api.base.model.TestStep;
import org.eclipse.mdm.api.base.model.User;
import org.eclipse.mdm.api.base.query.DataAccessException;
import org.eclipse.mdm.api.base.query.Filter;
@@ -55,9 +57,12 @@
import org.eclipse.mdm.api.dflt.EntityManager;
import org.eclipse.mdm.api.dflt.model.Classification;
import org.eclipse.mdm.api.dflt.model.Status;
+import org.eclipse.mdm.api.dflt.model.TemplateTest;
+import org.eclipse.mdm.api.dflt.model.TemplateTestStep;
import org.eclipse.mdm.api.odsadapter.filetransfer.Transfer;
import org.eclipse.mdm.api.odsadapter.lookup.EntityLoader;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig.Key;
+import org.eclipse.mdm.api.odsadapter.query.ODSEntityFactory;
import org.eclipse.mdm.api.odsadapter.query.ODSEntityType;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
import org.eclipse.mdm.api.odsadapter.transaction.ODSTransaction;
@@ -443,4 +448,20 @@
return linkMap;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Optional<TemplateTest> loadTemplate(Test test) {
+ return Optional.of(ODSEntityFactory.extract(test).getMutableStore().get(TemplateTest.class));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Optional<TemplateTestStep> loadTemplate(TestStep testStep) {
+ return Optional.of(ODSEntityFactory.extract(testStep).getMutableStore().get(TemplateTestStep.class));
+ }
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/DefaultEntityConfigRepositoryLoader.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/DefaultEntityConfigRepositoryLoader.java
index 6eeed7c..82529f5 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/DefaultEntityConfigRepositoryLoader.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/DefaultEntityConfigRepositoryLoader.java
@@ -39,9 +39,13 @@
import org.eclipse.mdm.api.dflt.model.CatalogAttribute;
import org.eclipse.mdm.api.dflt.model.CatalogComponent;
import org.eclipse.mdm.api.dflt.model.CatalogSensor;
+import org.eclipse.mdm.api.dflt.model.Classification;
+import org.eclipse.mdm.api.dflt.model.Domain;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
+import org.eclipse.mdm.api.dflt.model.ProjectDomain;
import org.eclipse.mdm.api.dflt.model.Role;
+import org.eclipse.mdm.api.dflt.model.Status;
import org.eclipse.mdm.api.dflt.model.TemplateAttribute;
import org.eclipse.mdm.api.dflt.model.TemplateComponent;
import org.eclipse.mdm.api.dflt.model.TemplateRoot;
@@ -148,16 +152,29 @@
templateTestStepConfig.setComparator(Versionable.COMPARATOR);
entityConfigRepository.register(templateTestStepConfig);
- // Status TestStep
- // TODO check MIME type genration
- // entityConfigRepository.register(create(new Key<>(Status.class,
- // TestStep.class), "StatusTestStep", true));
+ // Status
+ entityConfigRepository.register(create(modelManager, new Key<>(Status.class), "Status", false));
+
+ // ProjectDomain
+ entityConfigRepository.register(create(modelManager, new Key<>(ProjectDomain.class), "ProjectDomain", false));
+
+ // Domain
+ entityConfigRepository.register(create(modelManager, new Key<>(Domain.class), "Domain", false));
+
+ // Classification
+ EntityConfig<Classification> classificationConfig = create(modelManager, new Key<>(Classification.class),
+ "Classification", false);
+ classificationConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Status.class)));
+ classificationConfig.addOptional(entityConfigRepository.findRoot(new Key<>(ProjectDomain.class)));
+ classificationConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Domain.class)));
+ entityConfigRepository.register(classificationConfig);
// TestStep
EntityConfig<TestStep> testStepConfig = create(modelManager, new Key<>(TestStep.class), "TestStep", true);
// testStepConfig.addMandatory(entityConfigRepository.findRoot(new
// Key<>(Status.class, TestStep.class)));
testStepConfig.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateTestStep.class)));
+ testStepConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Classification.class)));
testStepConfig.setComparator(Sortable.COMPARATOR);
entityConfigRepository.register(testStepConfig);
@@ -183,6 +200,7 @@
// testConfig.addMandatory(entityConfigRepository.findRoot(new
// Key<>(Status.class, Test.class)));
testConfig.addOptional(entityConfigRepository.findRoot(new Key<>(TemplateTest.class)));
+ testConfig.addOptional(entityConfigRepository.findRoot(new Key<>(Classification.class)));
entityConfigRepository.register(testConfig);
// ContextRoots
@@ -296,7 +314,7 @@
/**
* Creates a new {@link EntityConfig}.
*
- * @param <T> The entity type.
+ * @param <T> The entity type.
* @param key Used as identifier.
* @param typeName Name of the associated {@link EntityType}.
* @param appendName Flag indicates whether to append the entity types base name
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/EventProcessor.java b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/EventProcessor.java
index 25b0f49..010d535 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/EventProcessor.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/EventProcessor.java
@@ -43,7 +43,8 @@
private PeakNotificationManager odsNotificationManager;
private MediaType eventMediaType;
private boolean closeInvoked = false;
-
+ private boolean disconnected = false;
+
public EventProcessor(EventInput eventInput, NotificationListener listener,
PeakNotificationManager odsNotificationManager, MediaType eventMediaType) {
this.eventInput = eventInput;
@@ -64,6 +65,7 @@
odsNotificationManager
.processException(new NotificationException("Inbound event input stream closed!"));
}
+ disconnected = true;
return;
}
@@ -76,9 +78,16 @@
} catch (ProcessingException e) {
odsNotificationManager
.processException(new NotificationException("Cannot deserialize notification event!", e));
+ disconnected = true;
return;
}
}
+
+ disconnected = true;
+ }
+
+ public boolean isDisconnected() {
+ return disconnected;
}
public void stop() {
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/PeakNotificationManager.java b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/PeakNotificationManager.java
index 5c3976d..37a67b7 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/PeakNotificationManager.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/PeakNotificationManager.java
@@ -18,6 +18,7 @@
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.ws.rs.client.Client;
@@ -87,6 +88,8 @@
.build();
endpoint = client.target(url).path("events");
+
+ Executors.newScheduledThreadPool(1).scheduleAtFixedRate(() -> reconnect(), 10, 10, TimeUnit.SECONDS);
} catch (Exception e) {
throw new NotificationException("Could not create " + PeakNotificationManager.class.getName() + "!", e);
}
@@ -123,27 +126,7 @@
"Could not create registration at notification service: " + response.readEntity(String.class));
}
- try {
- LOGGER.info("Requesting event input for {}", registration);
- EventInput eventInput = endpoint.path(registration).request(SseFeature.SERVER_SENT_EVENTS_TYPE)
- .get(EventInput.class);
-
- LOGGER.info("Received event input, starting event processor.");
- EventProcessor processor = new EventProcessor(eventInput, listener, this, MediaType.APPLICATION_JSON_TYPE);
-
- executor.submit(processor);
-
- processors.put(registration, processor);
- LOGGER.info("Event processor started.");
- } catch (Exception e) {
- try {
- deregister(registration);
- } catch (Exception ex) {
- LOGGER.error("Exception upon deregistering!");
- }
- throw new NotificationException("Could not create event input stream!", e);
- }
-
+ recreateEventStream(registration, listener);
}
/*
@@ -177,6 +160,55 @@
}
}
+ /**
+ * Recreates the {@link EventInput}, attaches an {@link EventProcessor} to it
+ * and stores the {@link EventProcessor} in the processors map.
+ *
+ * @param registration
+ * @param listener
+ * @throws NotificationException
+ */
+ private void recreateEventStream(String registration, NotificationListener listener) throws NotificationException {
+ try {
+ LOGGER.info("Requesting event input for {}", registration);
+ EventInput eventInput = endpoint.path(registration).request(SseFeature.SERVER_SENT_EVENTS_TYPE)
+ .get(EventInput.class);
+
+ LOGGER.info("Received event input, starting event processor.");
+ EventProcessor processor = new EventProcessor(eventInput, listener, this, MediaType.APPLICATION_JSON_TYPE);
+
+ executor.submit(processor);
+
+ processors.put(registration, processor);
+ LOGGER.info("Event processor started.");
+ } catch (Exception e) {
+ try {
+ deregister(registration);
+ } catch (Exception ex) {
+ LOGGER.error("Exception upon deregistering!");
+ }
+ throw new NotificationException("Could not create event input stream!", e);
+ }
+ }
+
+ /**
+ * Checks if any registered event processor got disconnected and tries to
+ * recreate the event stream, if necessary.
+ */
+ private void reconnect() {
+
+ for (Map.Entry<String, EventProcessor> entry : processors.entrySet()) {
+ if (entry.getValue().isDisconnected()) {
+ try {
+ LOGGER.trace("Registration '{}' was disconnected and will be recreated.", entry.getKey());
+ recreateEventStream(entry.getKey(), entry.getValue().getListener());
+ } catch (NotificationException e) {
+ LOGGER.warn("Cannot recreate event stream for registration " + entry.getKey(), e);
+ }
+ }
+ }
+ }
+
private void close(String registration) {
if (processors.containsKey(registration)) {
EventProcessor processor = processors.get(registration);
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/search/BaseEntitySearchQuery.java b/src/main/java/org/eclipse/mdm/api/odsadapter/search/BaseEntitySearchQuery.java
index 4f75079..cc2db44 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/search/BaseEntitySearchQuery.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/search/BaseEntitySearchQuery.java
@@ -89,9 +89,10 @@
EntityConfig<?> entityConfig = modelManager.getEntityConfig(new Key<>(entityClass));
EntityType source = entityConfig.getEntityType();
- entityConfig.getOptionalConfigs().stream().map(EntityConfig::getEntityType).forEach(entityType -> {
- joinTree.addNode(source, entityType, true, JoinType.OUTER);
- });
+ entityConfig.getOptionalConfigs().stream().map(EntityConfig::getEntityType)
+ .filter(et -> !"Classification".equals(et.getName())).forEach(entityType -> {
+ joinTree.addNode(source, entityType, true, JoinType.OUTER);
+ });
entityConfig.getMandatoryConfigs().stream().map(EntityConfig::getEntityType).forEach(entityType -> {
joinTree.addNode(source, entityType, true, JoinType.INNER);
@@ -195,9 +196,10 @@
joinTree.addNode(modelManager.getEntityType(joinConfig.source), target, joinConfig.viaParent, JoinType.INNER);
// add target's optional dependencies
- targetEntityConfig.getOptionalConfigs().stream().map(EntityConfig::getEntityType).forEach(entityType -> {
- joinTree.addNode(target, entityType, true, JoinType.OUTER);
- });
+ targetEntityConfig.getOptionalConfigs().stream().map(EntityConfig::getEntityType)
+ .filter(et -> !"Classification".equals(et.getName())).forEach(entityType -> {
+ joinTree.addNode(target, entityType, true, JoinType.OUTER);
+ });
// add target's mandatory dependencies
targetEntityConfig.getMandatoryConfigs().stream().map(EntityConfig::getEntityType).forEach(entityType -> {
diff --git a/src/test/java/org/eclipse/mdm/api/odsadapter/ODSRoleTest.java b/src/test/java/org/eclipse/mdm/api/odsadapter/ODSRoleTest.java
index 4e84e9e..8b2a9da 100644
--- a/src/test/java/org/eclipse/mdm/api/odsadapter/ODSRoleTest.java
+++ b/src/test/java/org/eclipse/mdm/api/odsadapter/ODSRoleTest.java
@@ -36,10 +36,11 @@
import org.eclipse.mdm.api.dflt.model.Role;
import org.junit.AfterClass;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-//@Ignore
+@Ignore
// FIXME 10.7.2017: this test needs a running ODS Server, that is not suitable for continous build in Jenkins.
// Comment this in for local tests only.
public class ODSRoleTest {