Merge branch 'dev'
diff --git a/build.gradle b/build.gradle
index 45038ed..27d74ee 100644
--- a/build.gradle
+++ b/build.gradle
@@ -81,7 +81,7 @@
// testing
testCompile 'junit:junit:4.12'
testRuntime 'org.slf4j:slf4j-simple:1.7.19'
- testCompile 'org.mockito:mockito-core:1.+'
+ testCompile 'org.mockito:mockito-core:2.10.0'
testCompile 'org.assertj:assertj-core:3.6.2'
testCompile(group: 'org.elasticsearch', name: 'elasticsearch', version: '2.3.4')
testCompile(group: 'org.elasticsearch', name: 'elasticsearch', version: '2.3.4', classifier: 'tests')
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContext.java b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContext.java
new file mode 100644
index 0000000..03874c1
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContext.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2017 Peak Solution GmbH and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.mdm.api.odsadapter;
+
+import java.util.Map;
+import java.util.Optional;
+
+import org.asam.ods.AoException;
+import org.asam.ods.AoSession;
+import org.eclipse.mdm.api.base.ConnectionException;
+import org.eclipse.mdm.api.base.adapter.ModelManager;
+import org.eclipse.mdm.api.base.file.FileService;
+import org.eclipse.mdm.api.base.notification.NotificationService;
+import org.eclipse.mdm.api.base.query.DataAccessException;
+import org.eclipse.mdm.api.base.query.QueryService;
+import org.eclipse.mdm.api.base.search.SearchService;
+import org.eclipse.mdm.api.dflt.ApplicationContext;
+import org.eclipse.mdm.api.dflt.EntityManager;
+import org.eclipse.mdm.api.dflt.model.EntityFactory;
+import org.eclipse.mdm.api.odsadapter.filetransfer.CORBAFileService;
+import org.eclipse.mdm.api.odsadapter.filetransfer.Transfer;
+import org.eclipse.mdm.api.odsadapter.lookup.EntityLoader;
+import org.eclipse.mdm.api.odsadapter.notification.ODSNotificationServiceFactory;
+import org.eclipse.mdm.api.odsadapter.query.ODSEntityFactory;
+import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
+import org.eclipse.mdm.api.odsadapter.query.ODSQueryService;
+import org.eclipse.mdm.api.odsadapter.search.ODSSearchService;
+import org.omg.CORBA.ORB;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.highqsoft.corbafileserver.generated.CORBAFileServerIF;
+
+/**
+ * ODSContext encapsulates a session to the ASAM ODS CORBA API and
+ * provides the ODS specific services implementations.
+ *
+ * @since 1.0.0
+ */
+public class ODSContext implements ApplicationContext {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ODSContext.class);
+
+ private Map<String, String> parameters;
+ private final Transfer transfer = Transfer.SOCKET;
+
+ private CORBAFileServerIF fileServer;
+ private ODSModelManager modelManager;
+ private ODSQueryService queryService;
+ private EntityLoader entityLoader;
+ private ODSEntityManager entityManager;
+ private ODSSearchService searchService;
+
+ /**
+ * Creates a new ODS application context.
+ * @param orb the CORBA ORB used to connect to the ODS API
+ * @param aoSession
+ * @param fileServer
+ * @param parameters
+ * @throws AoException
+ */
+ ODSContext(ORB orb, AoSession aoSession, CORBAFileServerIF fileServer, Map<String, String> parameters) throws AoException {
+ this.fileServer = fileServer;
+ this.parameters = parameters;
+
+ this.modelManager = new ODSModelManager(orb, aoSession);
+ this.queryService = new ODSQueryService(this.modelManager);
+ this.entityManager = new ODSEntityManager(this);
+ this.entityLoader = new EntityLoader(modelManager, queryService);
+ this.searchService = new ODSSearchService(this, queryService, entityLoader);
+ LOGGER.debug("ODSContext initialized.");
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Optional<EntityManager> getEntityManager() {
+ return Optional.of(entityManager);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Optional<EntityFactory> getEntityFactory() {
+ try {
+ return Optional.of(new ODSEntityFactory(modelManager, entityManager.loadLoggedOnUser().get()));
+ } catch (DataAccessException e) {
+ throw new IllegalStateException("Unable to load instance of the logged in user.");
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Optional<ModelManager> getModelManager() {
+ return Optional.of(modelManager);
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Optional<QueryService> getQueryService() {
+ // TODO
+ // java docs: cache this service for ONE request!
+ return Optional.of(new ODSQueryService(modelManager));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Optional<SearchService> getSearchService() {
+ return Optional.of(searchService);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Optional<FileService> getFileService() {
+ if (fileServer == null) {
+ return Optional.empty();
+ }
+ return Optional.of(new CORBAFileService(this, transfer));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Optional<NotificationService> getNotificationService() {
+ try {
+ return Optional.of(new ODSNotificationServiceFactory().create(this, parameters));
+ } catch (ConnectionException e) {
+ throw new IllegalStateException("Unable to create notification manager.", e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Map<String, String> getParameters() {
+ return parameters;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void close() {
+ try {
+ modelManager.close();
+ } catch (AoException e) {
+ LOGGER.warn("Unable to close sesssion due to: " + e.reason, e);
+ }
+ }
+
+ /**
+ * Returns the {@link ODSModelManager} used for this context.
+ * @return the {@link ODSModelManager}
+ */
+ public ODSModelManager getODSModelManager() {
+ return modelManager;
+ }
+
+ /**
+ * Returns the {@link AoSession} used for this context.
+ * @return {@link AoSession} used for this context.
+ */
+ public AoSession getAoSession() {
+ return modelManager.getAoSession();
+ }
+
+ /**
+ * Returns the ORB used for this context
+ * @return ORB used for this context
+ */
+ public ORB getORB() {
+ return modelManager.getORB();
+ }
+
+ /**
+ * Returns the {@link CORBAFileServerIF}.
+ *
+ * @return The {@code CORBAFileServerIF} is returned or null, if missing.
+ */
+ public CORBAFileServerIF getFileServer() {
+ return fileServer;
+ }
+
+ /**
+ * Returns a new {@link ODSContext} with a new ODS co-session.
+ *
+ * @return The created {@code ODSContext} is returned.
+ * @throws AoException
+ * Thrown on errors.
+ */
+ public ODSContext newContext() throws AoException {
+ return new ODSContext(modelManager.getORB(), getAoSession().createCoSession(), fileServer, parameters);
+ }
+}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManagerFactory.java b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContextFactory.java
similarity index 91%
rename from src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManagerFactory.java
rename to src/main/java/org/eclipse/mdm/api/odsadapter/ODSContextFactory.java
index 056655a..3ec55f7 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManagerFactory.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSContextFactory.java
@@ -1,259 +1,257 @@
-/*
- * Copyright (c) 2016 Gigatronik Ingolstadt GmbH
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.eclipse.mdm.api.odsadapter;
-
-import java.util.Map;
-
-import org.asam.ods.AoException;
-import org.asam.ods.AoFactory;
-import org.asam.ods.AoFactoryHelper;
-import org.asam.ods.AoSession;
-import org.eclipse.mdm.api.base.ConnectionException;
-import org.eclipse.mdm.api.base.EntityManagerFactory;
-import org.eclipse.mdm.api.dflt.EntityManager;
-import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
-import org.omg.CORBA.ORB;
-import org.omg.CORBA.Object;
-import org.omg.CosNaming.NameComponent;
-import org.omg.CosNaming.NamingContextExt;
-import org.omg.CosNaming.NamingContextExtHelper;
-import org.omg.CosNaming.NamingContextPackage.CannotProceed;
-import org.omg.CosNaming.NamingContextPackage.InvalidName;
-import org.omg.CosNaming.NamingContextPackage.NotFound;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.highqsoft.corbafileserver.generated.CORBAFileServerIF;
-import com.highqsoft.corbafileserver.generated.CORBAFileServerIFHelper;
-
-/**
- * ASAM ODS implementation of the {@link EntityManagerFactory} interface.
- *
- * @since 1.0.0
- * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
- */
-public class ODSEntityManagerFactory implements EntityManagerFactory<EntityManager> {
-
- // ======================================================================
- // Class variables
- // ======================================================================
-
- public static final String PARAM_NAMESERVICE = "nameservice";
-
- public static final String PARAM_SERVICENAME = "servicename";
-
- public static final String PARAM_USER = "user";
-
- public static final String PARAM_PASSWORD = "password";
-
- public static final String PARAM_ELASTIC_SEARCH_URL = "elasticsearch.url";
-
- private static final String AUTH_TEMPLATE = "USER=%s,PASSWORD=%s,CREATE_COSESSION_ALLOWED=TRUE";
-
- private static final Logger LOGGER = LoggerFactory.getLogger(ODSEntityManagerFactory.class);
-
- // ======================================================================
- // Instance variables
- // ======================================================================
-
- private final ORB orb = ORB.init(new String[] {}, System.getProperties());
-
- // ======================================================================
- // Public methods
- // ======================================================================
-
- public ODSEntityManagerFactory() {
- LOGGER.debug("Default constructor called.");
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>
- * <b>Note:</b> Given parameters {@code Map} must contain values for each of
- * the following keys:
- *
- * <ul>
- * <li>{@value #PARAM_NAMESERVICE}</li>
- * <li>{@value #PARAM_SERVICENAME}</li>
- * <li>{@value #PARAM_USER}</li>
- * <li>{@value #PARAM_PASSWORD}</li>
- * <li>{@value #PARAM_ELASTIC_SEARCH_URL}</li>
- * </ul>
- *
- * Listed names are available via public fields of this class.
- */
- @Override
- public EntityManager connect(Map<String, String> parameters) throws ConnectionException {
- AoSession aoSession = null;
- try (ServiceLocator serviceLocator = new ServiceLocator(orb, getParameter(parameters, PARAM_NAMESERVICE))) {
- String nameOfService = getParameter(parameters, PARAM_SERVICENAME).replace(".ASAM-ODS", "");
-
- AoFactory aoFactory = serviceLocator.resolveFactory(nameOfService);
- LOGGER.info("Connecting to ODS Server ...");
-
- LOGGER.info("AoFactory name: {}", aoFactory.getName());
- LOGGER.info("AoFactory description: {}", aoFactory.getDescription());
- LOGGER.info("AoFactory interface version: {}", aoFactory.getInterfaceVersion());
- LOGGER.info("AoFactory type: {}", aoFactory.getType());
-
- aoSession = aoFactory.newSession(String.format(AUTH_TEMPLATE, getParameter(parameters, PARAM_USER),
- getParameter(parameters, PARAM_PASSWORD)));
- LOGGER.info("Connection to ODS server established.");
-
- CORBAFileServerIF fileServer = serviceLocator.resolveFileServer(nameOfService);
- return new ODSEntityManager(new ODSModelManager(orb, aoSession, fileServer),
- parameters.get(PARAM_ELASTIC_SEARCH_URL));
- } catch (AoException e) {
- closeSession(aoSession);
- throw new ConnectionException("Unablte to connect to ODS server due to: " + e.reason, e);
- }
- }
-
- // ======================================================================
- // Private methods
- // ======================================================================
-
- /**
- * Closes given {@link AoSession} with catching and logging errors.
- *
- * @param aoSession
- * The {@code AoSession} that shall be closed.
- */
- private static void closeSession(AoSession aoSession) {
- if (aoSession == null) {
- return;
- }
-
- try {
- aoSession.close();
- } catch (AoException e) {
- LOGGER.warn("Unable to close sesssion due to: " + e.reason, e);
- }
- }
-
- /**
- * Reads the property identified by given property name.
- *
- * @param parameters
- * The properties {@code Map}.
- * @param name
- * The property name.
- * @return The property value is returned.
- * @throws ConnectionException
- * Thrown if property does not exist or is empty.
- */
- private static String getParameter(Map<String, String> parameters, String name) throws ConnectionException {
- String value = parameters.get(name);
- if (value == null || value.isEmpty()) {
- throw new ConnectionException("Connection parameter with name '" + name + "' is either missing or empty.");
- }
-
- return value;
- }
-
- // ======================================================================
- // Inner classes
- // ======================================================================
-
- /**
- * Used to resolve CORBA service object by ID and kind.
- */
- private static final class ServiceLocator implements AutoCloseable {
-
- // ======================================================================
- // Instance variables
- // ======================================================================
-
- private NamingContextExt namingContext;
-
- // ======================================================================
- // Constructors
- // ======================================================================
-
- /**
- * Constructor.
- *
- * @param orb
- * The {@link ORB} singleton instance.
- * @param path
- * The naming context path.
- * @throws ConnectionException
- * Thrown if unable to resolve the naming context.
- */
- public ServiceLocator(ORB orb, String path) throws ConnectionException {
- namingContext = NamingContextExtHelper.narrow(orb.string_to_object(path));
- if (namingContext == null) {
- throw new ConnectionException("Unable to resolve NameService '" + path + "'.");
- }
- }
-
- // ======================================================================
- // Public methods
- // ======================================================================
-
- /**
- * Resolves and returns the {@link AoFactory} service for given ID.
- *
- * @param id
- * Used as identifier.
- * @return The {@code AoFactory} is returned.
- * @throws ConnectionException
- * Thrown if unable to resolve the {@code
- * AoFactory}.
- */
- public AoFactory resolveFactory(String id) throws ConnectionException {
- return AoFactoryHelper.narrow(resolve(id, "ASAM-ODS"));
- }
-
- /**
- * Resolves and returns the {@link CORBAFileServerIF} service for given
- * ID.
- *
- * @param id
- * Used as identifier.
- * @return The {@code CORBAFileServerIF} or null, if none found, is
- * returned.
- */
- public CORBAFileServerIF resolveFileServer(String id) {
- try {
- return CORBAFileServerIFHelper.narrow(resolve(id, "CORBA-FT"));
- } catch (ConnectionException e) {
- LOGGER.warn(e.getMessage());
- return null;
- }
- }
-
- /**
- * Resolves a CORBA service object for given id and kind.
- *
- * @param id
- * Used as identifier.
- * @param kind
- * Used as qualifier.
- * @return The resolved CORBA service object is returned.
- * @throws ConnectionException
- * Thrown in case of errors.
- */
- public Object resolve(String id, String kind) throws ConnectionException {
- try {
- return namingContext.resolve(new NameComponent[] { new NameComponent(id, kind) });
- } catch (NotFound | CannotProceed | InvalidName e) {
- throw new ConnectionException("Unable to resolve service '" + id + "." + kind + "'.", e);
- }
- }
-
- @Override
- public void close() throws ConnectionException {
- namingContext._release();
- }
-
- }
-
-}
+/*
+ * Copyright (c) 2016 Gigatronik Ingolstadt GmbH and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.eclipse.mdm.api.odsadapter;
+
+import java.util.Map;
+
+import org.asam.ods.AoException;
+import org.asam.ods.AoFactory;
+import org.asam.ods.AoFactoryHelper;
+import org.asam.ods.AoSession;
+import org.eclipse.mdm.api.base.ConnectionException;
+import org.eclipse.mdm.api.dflt.ApplicationContext;
+import org.eclipse.mdm.api.dflt.ApplicationContextFactory;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.Object;
+import org.omg.CosNaming.NameComponent;
+import org.omg.CosNaming.NamingContextExt;
+import org.omg.CosNaming.NamingContextExtHelper;
+import org.omg.CosNaming.NamingContextPackage.CannotProceed;
+import org.omg.CosNaming.NamingContextPackage.InvalidName;
+import org.omg.CosNaming.NamingContextPackage.NotFound;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.highqsoft.corbafileserver.generated.CORBAFileServerIF;
+import com.highqsoft.corbafileserver.generated.CORBAFileServerIFHelper;
+
+/**
+ * ASAM ODS implementation of the {@link ApplicationContextFactory} interface.
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ */
+public class ODSContextFactory implements ApplicationContextFactory {
+
+ // ======================================================================
+ // Class variables
+ // ======================================================================
+
+ public static final String PARAM_NAMESERVICE = "nameservice";
+
+ public static final String PARAM_SERVICENAME = "servicename";
+
+ public static final String PARAM_USER = "user";
+
+ public static final String PARAM_PASSWORD = "password";
+
+ public static final String PARAM_ELASTIC_SEARCH_URL = "elasticsearch.url";
+
+ private static final String AUTH_TEMPLATE = "USER=%s,PASSWORD=%s,CREATE_COSESSION_ALLOWED=TRUE";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ODSContextFactory.class);
+
+ // ======================================================================
+ // Instance variables
+ // ======================================================================
+
+ private final ORB orb = ORB.init(new String[] {}, System.getProperties());
+
+ // ======================================================================
+ // Public methods
+ // ======================================================================
+
+ public ODSContextFactory() {
+ LOGGER.debug("Default constructor called.");
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>
+ * <b>Note:</b> Given parameters {@code Map} must contain values for each of
+ * the following keys:
+ *
+ * <ul>
+ * <li>{@value #PARAM_NAMESERVICE}</li>
+ * <li>{@value #PARAM_SERVICENAME}</li>
+ * <li>{@value #PARAM_USER}</li>
+ * <li>{@value #PARAM_PASSWORD}</li>
+ * <li>{@value #PARAM_ELASTIC_SEARCH_URL}</li>
+ * </ul>
+ *
+ * Listed names are available via public fields of this class.
+ */
+ @Override
+ public ApplicationContext connect(Map<String, String> parameters) throws ConnectionException {
+ AoSession aoSession = null;
+ try (ServiceLocator serviceLocator = new ServiceLocator(orb, getParameter(parameters, PARAM_NAMESERVICE))) {
+ String nameOfService = getParameter(parameters, PARAM_SERVICENAME).replace(".ASAM-ODS", "");
+
+ AoFactory aoFactory = serviceLocator.resolveFactory(nameOfService);
+ LOGGER.info("Connecting to ODS Server ...");
+
+ LOGGER.info("AoFactory name: {}", aoFactory.getName());
+ LOGGER.info("AoFactory description: {}", aoFactory.getDescription());
+ LOGGER.info("AoFactory interface version: {}", aoFactory.getInterfaceVersion());
+ LOGGER.info("AoFactory type: {}", aoFactory.getType());
+
+ aoSession = aoFactory.newSession(String.format(AUTH_TEMPLATE, getParameter(parameters, PARAM_USER),
+ getParameter(parameters, PARAM_PASSWORD)));
+ LOGGER.info("Connection to ODS server established.");
+
+ CORBAFileServerIF fileServer = serviceLocator.resolveFileServer(nameOfService);
+ return new ODSContext(orb, aoSession, fileServer, parameters);
+ } catch (AoException e) {
+ closeSession(aoSession);
+ throw new ConnectionException("Unable to connect to ODS server due to: " + e.reason, e);
+ }
+ }
+
+ // ======================================================================
+ // Private methods
+ // ======================================================================
+
+ /**
+ * Closes given {@link AoSession} with catching and logging errors.
+ *
+ * @param aoSession
+ * The {@code AoSession} that shall be closed.
+ */
+ private static void closeSession(AoSession aoSession) {
+ if (aoSession == null) {
+ return;
+ }
+
+ try {
+ aoSession.close();
+ } catch (AoException e) {
+ LOGGER.warn("Unable to close sesssion due to: " + e.reason, e);
+ }
+ }
+
+ /**
+ * Reads the property identified by given property name.
+ *
+ * @param parameters
+ * The properties {@code Map}.
+ * @param name
+ * The property name.
+ * @return The property value is returned.
+ * @throws ConnectionException
+ * Thrown if property does not exist or is empty.
+ */
+ private static String getParameter(Map<String, String> parameters, String name) throws ConnectionException {
+ String value = parameters.get(name);
+ if (value == null || value.isEmpty()) {
+ throw new ConnectionException("Connection parameter with name '" + name + "' is either missing or empty.");
+ }
+
+ return value;
+ }
+
+ // ======================================================================
+ // Inner classes
+ // ======================================================================
+
+ /**
+ * Used to resolve CORBA service object by ID and kind.
+ */
+ private static final class ServiceLocator implements AutoCloseable {
+
+ // ======================================================================
+ // Instance variables
+ // ======================================================================
+
+ private NamingContextExt namingContext;
+
+ // ======================================================================
+ // Constructors
+ // ======================================================================
+
+ /**
+ * Constructor.
+ *
+ * @param orb
+ * The {@link ORB} singleton instance.
+ * @param path
+ * The naming context path.
+ * @throws ConnectionException
+ * Thrown if unable to resolve the naming context.
+ */
+ public ServiceLocator(ORB orb, String path) throws ConnectionException {
+ namingContext = NamingContextExtHelper.narrow(orb.string_to_object(path));
+ if (namingContext == null) {
+ throw new ConnectionException("Unable to resolve NameService '" + path + "'.");
+ }
+ }
+
+ // ======================================================================
+ // Public methods
+ // ======================================================================
+
+ /**
+ * Resolves and returns the {@link AoFactory} service for given ID.
+ *
+ * @param id
+ * Used as identifier.
+ * @return The {@code AoFactory} is returned.
+ * @throws ConnectionException
+ * Thrown if unable to resolve the {@code
+ * AoFactory}.
+ */
+ public AoFactory resolveFactory(String id) throws ConnectionException {
+ return AoFactoryHelper.narrow(resolve(id, "ASAM-ODS"));
+ }
+
+ /**
+ * Resolves and returns the {@link CORBAFileServerIF} service for given
+ * ID.
+ *
+ * @param id
+ * Used as identifier.
+ * @return The {@code CORBAFileServerIF} or null, if none found, is
+ * returned.
+ */
+ public CORBAFileServerIF resolveFileServer(String id) {
+ try {
+ return CORBAFileServerIFHelper.narrow(resolve(id, "CORBA-FT"));
+ } catch (ConnectionException e) {
+ LOGGER.warn(e.getMessage());
+ return null;
+ }
+ }
+
+ /**
+ * Resolves a CORBA service object for given id and kind.
+ *
+ * @param id
+ * Used as identifier.
+ * @param kind
+ * Used as qualifier.
+ * @return The resolved CORBA service object is returned.
+ * @throws ConnectionException
+ * Thrown in case of errors.
+ */
+ public Object resolve(String id, String kind) throws ConnectionException {
+ try {
+ return namingContext.resolve(new NameComponent[] { new NameComponent(id, kind) });
+ } catch (NotFound | CannotProceed | InvalidName e) {
+ throw new ConnectionException("Unable to resolve service '" + id + "." + kind + "'.", e);
+ }
+ }
+
+ @Override
+ public void close() throws ConnectionException {
+ namingContext._release();
+ }
+
+ }
+
+}
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 b62782e..20fd266 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSEntityManager.java
@@ -21,8 +21,9 @@
import org.asam.ods.AoException;
import org.asam.ods.InstanceElement;
import org.eclipse.mdm.api.base.ConnectionException;
-import org.eclipse.mdm.api.base.FileService;
+import org.eclipse.mdm.api.base.ServiceNotProvidedException;
import org.eclipse.mdm.api.base.Transaction;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.massdata.ReadRequest;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
@@ -34,23 +35,17 @@
import org.eclipse.mdm.api.base.model.MeasuredValues;
import org.eclipse.mdm.api.base.model.User;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.JoinType;
-import org.eclipse.mdm.api.base.query.ModelManager;
import org.eclipse.mdm.api.base.query.Query;
+import org.eclipse.mdm.api.base.query.QueryService;
import org.eclipse.mdm.api.base.query.Record;
import org.eclipse.mdm.api.base.query.Result;
-import org.eclipse.mdm.api.base.query.SearchService;
import org.eclipse.mdm.api.dflt.EntityManager;
-import org.eclipse.mdm.api.dflt.model.EntityFactory;
-import org.eclipse.mdm.api.odsadapter.filetransfer.CORBAFileService;
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.ODSModelManager;
-import org.eclipse.mdm.api.odsadapter.search.ODSSearchService;
import org.eclipse.mdm.api.odsadapter.transaction.ODSTransaction;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;
@@ -74,12 +69,12 @@
// ======================================================================
// Instance variables
// ======================================================================
-
- private final ODSModelManager modelManager;
- private final EntityLoader entityLoader;
-
private final Transfer transfer = Transfer.SOCKET;
- private String esHost;
+
+ private final ODSContext context;
+ private final ODSModelManager odsModelManager;
+ private final QueryService queryService;
+ private final EntityLoader entityLoader;
// ======================================================================
// Constructors
@@ -88,59 +83,21 @@
/**
* Constructor.
*
- * @param modelManager
- * The {@link ODSModelManager}.
+ * @param context
+ * The {@link ODSContext}.
*/
- public ODSEntityManager(ODSModelManager modelManager, String esHost) {
- this.modelManager = modelManager;
- this.esHost = esHost;
- entityLoader = new EntityLoader(modelManager);
+ public ODSEntityManager(ODSContext context) {
+ this.context = context;
+ this.odsModelManager = context.getODSModelManager();
+ this.queryService = context.getQueryService()
+ .orElseThrow(() -> new ServiceNotProvidedException(QueryService.class));
+ entityLoader = new EntityLoader(odsModelManager, queryService);
}
// ======================================================================
// Public methods
// ======================================================================
- /**
- * {@inheritDoc}
- */
- @Override
- public Optional<EntityFactory> getEntityFactory() {
- try {
- return Optional.of(new ODSEntityFactory(modelManager, loadLoggedOnUser().get()));
- } catch (DataAccessException e) {
- throw new IllegalStateException("Unable to load instance of the logged in user.");
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Optional<ModelManager> getModelManager() {
- return Optional.of(modelManager);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Optional<SearchService> getSearchService() {
- // TODO
- // java docs: cache this service for ONE request!
- return Optional.of(new ODSSearchService(modelManager, entityLoader, esHost));
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Optional<FileService> getFileService() {
- if (modelManager.getFileServer() == null) {
- return Optional.empty();
- }
- return Optional.of(new CORBAFileService(modelManager, transfer));
- }
/**
* {@inheritDoc}
@@ -162,7 +119,7 @@
public Optional<User> loadLoggedOnUser() throws DataAccessException {
InstanceElement ieUser = null;
try {
- ieUser = modelManager.getAoSession().getUser();
+ ieUser = odsModelManager.getAoSession().getUser();
return Optional.of(
entityLoader.load(new Key<>(User.class), Long.toString(ODSConverter.fromODSLong(ieUser.getId()))));
} catch (AoException e) {
@@ -202,14 +159,14 @@
*/
@Override
public <T extends Entity> Optional<T> loadParent(Entity child, Class<T> entityClass) throws DataAccessException {
- EntityType parentEntityType = modelManager.getEntityType(entityClass);
- EntityType childEntityType = modelManager.getEntityType(child);
- Query query = modelManager.createQuery().selectID(parentEntityType);
+ EntityType parentEntityType = odsModelManager.getEntityType(entityClass);
+ EntityType childEntityType = odsModelManager.getEntityType(child);
+ Query query = queryService.createQuery().selectID(parentEntityType);
if (child instanceof Channel && ChannelGroup.class.equals(entityClass)) {
// this covers the gap between channel and channel group via local
// column
- EntityType localColumnEntityType = modelManager.getEntityType("LocalColumn");
+ EntityType localColumnEntityType = odsModelManager.getEntityType("LocalColumn");
query.join(childEntityType, localColumnEntityType).join(localColumnEntityType, parentEntityType);
} else {
query.join(childEntityType, parentEntityType);
@@ -277,14 +234,14 @@
@Override
public <T extends Entity> List<T> loadChildren(Entity parent, Class<T> entityClass, String pattern)
throws DataAccessException {
- EntityType parentEntityType = modelManager.getEntityType(parent);
- EntityType childEntityType = modelManager.getEntityType(entityClass);
- Query query = modelManager.createQuery();
+ EntityType parentEntityType = odsModelManager.getEntityType(parent);
+ EntityType childEntityType = odsModelManager.getEntityType(entityClass);
+ Query query = queryService.createQuery();
if (parent instanceof ChannelGroup && Channel.class.equals(entityClass)) {
// this covers the gap between channel and channel group via local
// column
- EntityType localColumnEntityType = modelManager.getEntityType("LocalColumn");
+ EntityType localColumnEntityType = odsModelManager.getEntityType("LocalColumn");
query.join(childEntityType, localColumnEntityType).join(localColumnEntityType, parentEntityType);
} else {
query.join(childEntityType, parentEntityType);
@@ -326,12 +283,12 @@
*/
@Override
public List<ContextType> loadContextTypes(ContextDescribable contextDescribable) throws DataAccessException {
- EntityType contextDescribableEntityType = modelManager.getEntityType(contextDescribable);
- Query query = modelManager.createQuery();
+ EntityType contextDescribableEntityType = odsModelManager.getEntityType(contextDescribable);
+ Query query = queryService.createQuery();
Map<ContextType, EntityType> contextRootEntityTypes = new EnumMap<>(ContextType.class);
for (ContextType contextType : ContextType.values()) {
- EntityType entityType = modelManager.getEntityType(ContextRoot.class, contextType);
+ EntityType entityType = odsModelManager.getEntityType(ContextRoot.class, contextType);
contextRootEntityTypes.put(contextType, entityType);
query.join(contextDescribableEntityType.getRelation(entityType), JoinType.OUTER).selectID(entityType);
}
@@ -359,12 +316,12 @@
@Override
public Map<ContextType, ContextRoot> loadContexts(ContextDescribable contextDescribable,
ContextType... contextTypes) throws DataAccessException {
- EntityType contextDescribableEntityType = modelManager.getEntityType(contextDescribable);
- Query query = modelManager.createQuery();
+ EntityType contextDescribableEntityType = odsModelManager.getEntityType(contextDescribable);
+ Query query = queryService.createQuery();
Map<ContextType, EntityType> contextRootEntityTypes = new EnumMap<>(ContextType.class);
for (ContextType contextType : contextTypes.length == 0 ? ContextType.values() : contextTypes) {
- EntityType entityType = modelManager.getEntityType(ContextRoot.class, contextType);
+ EntityType entityType = odsModelManager.getEntityType(ContextRoot.class, contextType);
contextRootEntityTypes.put(contextType, entityType);
query.join(contextDescribableEntityType.getRelation(entityType), JoinType.OUTER).selectID(entityType);
}
@@ -392,7 +349,7 @@
*/
@Override
public List<MeasuredValues> readMeasuredValues(ReadRequest readRequest) throws DataAccessException {
- return new ReadRequestHandler(modelManager).execute(readRequest);
+ return new ReadRequestHandler(odsModelManager).execute(readRequest);
}
/**
@@ -401,22 +358,10 @@
@Override
public Transaction startTransaction() throws DataAccessException {
try {
- return new ODSTransaction(modelManager, loadEnvironment(), transfer);
+ return new ODSTransaction(context, loadEnvironment(), transfer);
} catch (AoException e) {
throw new DataAccessException("Unable to start transaction due to: " + e.reason, e);
}
}
- /**
- * {@inheritDoc}
- */
- @Override
- public void close() throws ConnectionException {
- try {
- modelManager.close();
- } catch (AoException e) {
- throw new ConnectionException("Unable to close the connection to the data source due to: " + e.reason, e);
- }
- }
-
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSNotificationManagerFactory.java b/src/main/java/org/eclipse/mdm/api/odsadapter/ODSNotificationManagerFactory.java
deleted file mode 100644
index 7053bd4..0000000
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/ODSNotificationManagerFactory.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.eclipse.mdm.api.odsadapter;
-
-import java.util.Map;
-import java.util.Optional;
-
-import javax.ejb.LocalBean;
-import javax.ejb.Stateful;
-
-import org.eclipse.mdm.api.base.BaseEntityManager;
-import org.eclipse.mdm.api.base.ConnectionException;
-import org.eclipse.mdm.api.base.NotificationManagerFactory;
-import org.eclipse.mdm.api.base.model.BaseEntityFactory;
-import org.eclipse.mdm.api.base.notification.NotificationException;
-import org.eclipse.mdm.api.base.notification.NotificationManager;
-import org.eclipse.mdm.api.base.query.ModelManager;
-import org.eclipse.mdm.api.odsadapter.notification.avalon.AvalonNotificationManager;
-import org.eclipse.mdm.api.odsadapter.notification.peak.PeakNotificationManager;
-import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Factory for creating a notification manager.
- *
- * Currently only supports creating a notification manager for server type
- * 'peak'.
- *
- * @since 1.0.0
- * @author Matthias Koller, Peak Solution GmbH
- *
- */
-@Stateful
-@LocalBean
-public class ODSNotificationManagerFactory implements NotificationManagerFactory {
- private static final Logger LOGGER = LoggerFactory.getLogger(ODSNotificationManagerFactory.class);
-
- public static final String PARAM_SERVER_TYPE = "serverType";
- public static final String PARAM_URL = "url";
- public static final String PARAM_EVENT_MEDIATYPE = "eventMimetype";
- public static final String PARAM_POLLING_INTERVAL = "pollingInterval";
-
- public static final String SERVER_TYPE_PEAK = "peak";
- public static final String SERVER_TYPE_AVALON = "avalon";
-
- public static final String PARAM_NAMESERVICE_URL = "nameserviceURL";
-
- public NotificationManager create(BaseEntityManager<? extends BaseEntityFactory> entityManager,
- Map<String, String> parameters) throws ConnectionException {
- String type = getParameter(parameters, PARAM_SERVER_TYPE);
-
- Optional<ModelManager> mm = entityManager.getModelManager();
- if (!mm.isPresent()) {
- throw new ConnectionException("EntityManager has no ModelManager!");
- }
- if (!ODSModelManager.class.isInstance(mm.get())) {
- throw new ConnectionException("ModelManager is not a ODSModelManager!");
- }
-
- if (SERVER_TYPE_PEAK.equalsIgnoreCase(type)) {
- String url = getParameter(parameters, PARAM_URL);
- String eventMediaType = getParameter(parameters, PARAM_EVENT_MEDIATYPE);
-
- LOGGER.info("Connecting to Peak Notification Server ...");
- LOGGER.info("URL: {}", url);
- LOGGER.info("Event MediaType: {}", eventMediaType);
-
- try {
- return new PeakNotificationManager((ODSModelManager) mm.get(), url, eventMediaType, true);
- } catch (NotificationException e) {
- throw new ConnectionException("Could not connect to notification service!", e);
- }
- } else if (SERVER_TYPE_AVALON.equalsIgnoreCase(type)) {
-
- String serviceName = getParameter(parameters, ODSEntityManagerFactory.PARAM_SERVICENAME);
- serviceName = serviceName.replace(".ASAM-ODS", "");
- String nameServiceURL = getParameter(parameters, ODSEntityManagerFactory.PARAM_NAMESERVICE);
-
- LOGGER.info("Connecting to Avalon Notification Server ...");
- LOGGER.info("Name service URL: {}", nameServiceURL);
- LOGGER.info("Service name: {}", serviceName);
-
- long pollingInterval = 500L;
- try {
- pollingInterval = Long.parseLong(getParameter(parameters, PARAM_POLLING_INTERVAL));
- } catch (NumberFormatException | ConnectionException e) {
- LOGGER.warn("Could not parse parse parameter pollingInterval. Using default value: " + pollingInterval,
- e);
- }
-
- return new AvalonNotificationManager((ODSModelManager) mm.get(), serviceName, nameServiceURL, true,
- pollingInterval);
- } else {
- throw new ConnectionException("Invalid server type. Expected on of: 'peak'");
- }
-
- }
-
- private String getParameter(Map<String, String> parameters, String name) throws ConnectionException {
- String value = parameters.get(name);
- if (value == null || value.isEmpty()) {
- throw new ConnectionException("Connection parameter with name '" + name + "' is either missing or empty.");
- }
-
- return value;
- }
-}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/filetransfer/CORBAFileServer.java b/src/main/java/org/eclipse/mdm/api/odsadapter/filetransfer/CORBAFileServer.java
index 13c9d19..c7cdb3c 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/filetransfer/CORBAFileServer.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/filetransfer/CORBAFileServer.java
@@ -18,7 +18,10 @@
import org.asam.ods.AoSession;
import org.asam.ods.ElemId;
+import org.eclipse.mdm.api.base.ServiceNotProvidedException;
+import org.eclipse.mdm.api.base.adapter.ModelManager;
import org.eclipse.mdm.api.base.model.FileLink;
+import org.eclipse.mdm.api.odsadapter.ODSContext;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
import org.omg.CORBA.ORB;
import org.omg.CORBA.ORBPackage.InvalidName;
@@ -80,10 +83,15 @@
* @param transfer
* The transfer type for up- and downloads.
*/
- CORBAFileServer(ODSModelManager modelManager, Transfer transfer) {
- fileServer = modelManager.getFileServer();
- aoSession = modelManager.getAoSession();
- orb = modelManager.getORB();
+ CORBAFileServer(ODSContext context, Transfer transfer) {
+ ModelManager mm = context.getModelManager().orElseThrow(() -> new ServiceNotProvidedException(ModelManager.class));
+ if (!(mm instanceof ODSModelManager)) {
+ throw new IllegalArgumentException("The supplied ModelManager must be an ODSModelManager!");
+ }
+
+ fileServer = context.getFileServer();
+ aoSession = context.getAoSession();
+ orb = context.getORB();
this.transfer = transfer;
bufferSize = getBufferSize();
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/filetransfer/CORBAFileService.java b/src/main/java/org/eclipse/mdm/api/odsadapter/filetransfer/CORBAFileService.java
index 0ab1058..960eb4c 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/filetransfer/CORBAFileService.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/filetransfer/CORBAFileService.java
@@ -32,11 +32,13 @@
import java.util.stream.Collectors;
import org.asam.ods.ElemId;
-import org.eclipse.mdm.api.base.FileService;
+import org.eclipse.mdm.api.base.ServiceNotProvidedException;
+import org.eclipse.mdm.api.base.adapter.ModelManager;
+import org.eclipse.mdm.api.base.file.FileService;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.FileLink;
+import org.eclipse.mdm.api.odsadapter.ODSContext;
import org.eclipse.mdm.api.odsadapter.query.ODSEntityType;
-import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -62,8 +64,7 @@
// ======================================================================
private final CORBAFileServer fileServer;
- private final ODSModelManager modelManager;
-
+ private final ModelManager modelManager;
// ======================================================================
// Constructors
// ======================================================================
@@ -71,14 +72,15 @@
/**
* Constructor.
*
- * @param modelManager
+ * @param context
* Used for {@link Entity} to {@link ElemId} conversion.
* @param transfer
* The transfer type for up- and downloads.
*/
- public CORBAFileService(ODSModelManager modelManager, Transfer transfer) {
- this.modelManager = modelManager;
- fileServer = new CORBAFileServer(modelManager, transfer);
+ public CORBAFileService(ODSContext context, Transfer transfer) {
+ this.modelManager = context.getModelManager().orElseThrow(() -> new ServiceNotProvidedException(ModelManager.class));
+
+ fileServer = new CORBAFileServer(context, transfer);
}
// ======================================================================
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/filetransfer/TracedInputStream.java b/src/main/java/org/eclipse/mdm/api/odsadapter/filetransfer/TracedInputStream.java
index 7f1901f..0da2e73 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/filetransfer/TracedInputStream.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/filetransfer/TracedInputStream.java
@@ -11,7 +11,7 @@
import java.io.IOException;
import java.io.InputStream;
-import org.eclipse.mdm.api.base.FileService.ProgressListener;
+import org.eclipse.mdm.api.base.file.FileService.ProgressListener;
/**
* This is an {@link InputStream} wrapper implementation to trace the progress
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/ChildRequest.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/ChildRequest.java
index 7baa3b5..66e1cc1 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/ChildRequest.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/ChildRequest.java
@@ -6,15 +6,15 @@
import java.util.List;
import java.util.Optional;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.Deletable;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.ComparisonOperator;
import org.eclipse.mdm.api.base.query.Query;
import org.eclipse.mdm.api.base.query.Record;
-import org.eclipse.mdm.api.base.query.Relation;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;
/**
@@ -69,7 +69,7 @@
Relation parentRelation = entityConfig.getEntityType().getRelation(parent.entityConfig.getEntityType());
Relation reflexiveRelation = entityConfig.isReflexive() ? entityType.getRelation(entityType) : null;
- Query query = modelManager.createQuery()
+ Query query = queryService.createQuery()
// select entity attributes
.selectAll(entityConfig.getEntityType())
// select parent entity ID
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityLoader.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityLoader.java
index 6179bbb..e8a0916 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityLoader.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityLoader.java
@@ -6,6 +6,7 @@
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.query.DataAccessException;
+import org.eclipse.mdm.api.base.query.QueryService;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig.Key;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
@@ -23,7 +24,7 @@
// ======================================================================
private final ODSModelManager modelManager;
-
+ private final QueryService queryService;
// ======================================================================
// Constructors
// ======================================================================
@@ -34,8 +35,9 @@
* @param modelManager
* The {@link ODSModelManager}.
*/
- public EntityLoader(ODSModelManager modelManager) {
+ public EntityLoader(ODSModelManager modelManager, QueryService queryService) {
this.modelManager = modelManager;
+ this.queryService = queryService;
}
// ======================================================================
@@ -116,7 +118,7 @@
/*
* TODO: add custom request implementations here!
*/
- return new EntityRequest<>(modelManager, modelManager.getEntityConfig(key));
+ return new EntityRequest<>(modelManager, queryService, key);
}
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityRecord.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityRecord.java
index f1ede3f..4c5b243 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityRecord.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityRecord.java
@@ -1,6 +1,6 @@
package org.eclipse.mdm.api.odsadapter.lookup;
-import org.eclipse.mdm.api.base.model.Core;
+import org.eclipse.mdm.api.base.adapter.Core;
import org.eclipse.mdm.api.base.model.Entity;
/**
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityRequest.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityRequest.java
index 6407bb4..c6b53dc 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityRequest.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityRequest.java
@@ -11,24 +11,26 @@
import java.util.Set;
import java.util.stream.Stream;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.ModelManager;
+import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.ContextComponent;
import org.eclipse.mdm.api.base.model.ContextSensor;
import org.eclipse.mdm.api.base.model.ContextType;
import org.eclipse.mdm.api.base.model.Deletable;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.Filter;
-import org.eclipse.mdm.api.base.query.ModelManager;
import org.eclipse.mdm.api.base.query.ComparisonOperator;
import org.eclipse.mdm.api.base.query.Query;
+import org.eclipse.mdm.api.base.query.QueryService;
import org.eclipse.mdm.api.base.query.Record;
-import org.eclipse.mdm.api.base.query.Relation;
import org.eclipse.mdm.api.base.query.Result;
import org.eclipse.mdm.api.dflt.model.TemplateAttribute;
import org.eclipse.mdm.api.dflt.model.TemplateComponent;
import org.eclipse.mdm.api.dflt.model.TemplateSensor;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;
+import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig.Key;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
/**
@@ -46,8 +48,8 @@
// Instance variables
// ======================================================================
- final ModelManager modelManager;
-
+ final ODSModelManager odsModelManager;
+ final QueryService queryService;
final EntityConfig<T> entityConfig;
final EntityResult<T> entityResult = new EntityResult<>(this);
@@ -67,9 +69,10 @@
* @param config
* The {@link EntityConfig}.
*/
- public EntityRequest(ModelManager modelManager, EntityConfig<T> config) {
- this.modelManager = modelManager;
- this.entityConfig = config;
+ public EntityRequest(ODSModelManager modelManager, QueryService queryService, Key<T> key) {
+ this.odsModelManager = modelManager;
+ this.queryService = queryService;
+ this.entityConfig = modelManager.getEntityConfig(key);
cache = new Cache();
}
@@ -82,7 +85,8 @@
* The {@link EntityConfig}.
*/
protected EntityRequest(EntityRequest<?> parentRequest, EntityConfig<T> entityConfig) {
- modelManager = parentRequest.modelManager;
+ odsModelManager = parentRequest.odsModelManager;
+ queryService = parentRequest.queryService;
cache = parentRequest.cache;
this.entityConfig = entityConfig;
}
@@ -123,6 +127,10 @@
return load(Filter.idsOnly(entityConfig.getEntityType(), instanceIDs)).getSortedEntities();
}
+
+ public ODSModelManager getODSModelManager() {
+ return odsModelManager;
+ }
// ======================================================================
// Protected methods
@@ -252,7 +260,7 @@
EntityType entityType = entityConfig.getEntityType();
Relation reflexiveRelation = entityConfig.isReflexive() ? entityType.getRelation(entityType) : null;
- Query query = modelManager.createQuery().selectAll(entityConfig.getEntityType());
+ Query query = queryService.createQuery().selectAll(entityConfig.getEntityType());
if (entityConfig.isReflexive()) {
query.select(reflexiveRelation.getAttribute());
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityResult.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityResult.java
index 0ad1498..c1ab377 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityResult.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/EntityResult.java
@@ -1,11 +1,9 @@
package org.eclipse.mdm.api.odsadapter.lookup;
-import static org.eclipse.mdm.api.dflt.model.CatalogAttribute.VATTR_ENUMERATION_CLASS;
+import static org.eclipse.mdm.api.dflt.model.CatalogAttribute.VATTR_ENUMERATION_NAME;
import static org.eclipse.mdm.api.dflt.model.CatalogAttribute.VATTR_SCALAR_TYPE;
import static org.eclipse.mdm.api.dflt.model.CatalogAttribute.VATTR_SEQUENCE;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -15,19 +13,20 @@
import java.util.Optional;
import java.util.stream.Collectors;
-import org.eclipse.mdm.api.base.model.Core;
+import org.eclipse.mdm.api.base.adapter.Attribute;
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.adapter.DefaultCore;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.Deletable;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.EnumRegistry;
import org.eclipse.mdm.api.base.model.Enumeration;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.model.ValueType;
-import org.eclipse.mdm.api.base.query.Attribute;
-import org.eclipse.mdm.api.base.query.DefaultCore;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.Record;
import org.eclipse.mdm.api.dflt.model.CatalogAttribute;
import org.eclipse.mdm.api.dflt.model.CatalogComponent;
+import org.eclipse.mdm.api.odsadapter.query.ODSEntityFactory;
/**
* Container for entities by executing an {@link EntityRequest}.
@@ -91,7 +90,7 @@
/**
* Creates an {@link EntityRecord} for given {@link Record} using given
- * parent {@code EntityRecord} and mapps it internally by its instance ID.
+ * parent {@code EntityRecord} and maps it internally by its instance ID.
*
* @param parentRecord
* The created {@code EntityRecord} will be related as a child
@@ -165,14 +164,14 @@
* The {@code CatalogAttribute} {@code Core}.
*/
private void adjustCatalogAttributeCore(Entity catalogComponent, Core catalogAttributeCore) {
- EntityType entityType = request.modelManager.getEntityType(catalogComponent.getName());
+ EntityType entityType = request.odsModelManager.getEntityType(catalogComponent.getName());
Attribute attribute = entityType.getAttribute(catalogAttributeCore.getValues().get(Entity.ATTR_NAME).extract());
Map<String, Value> values = catalogAttributeCore.getValues();
- Value enumerationClass = ValueType.STRING.create(VATTR_ENUMERATION_CLASS);
- values.put(VATTR_ENUMERATION_CLASS, enumerationClass);
+ Value enumerationName = ValueType.STRING.create(VATTR_ENUMERATION_NAME);
+ values.put(VATTR_ENUMERATION_NAME, enumerationName);
if (attribute.getValueType().isEnumerationType()) {
- enumerationClass.set(attribute.getEnumObj().getName());
+ enumerationName.set(attribute.getEnumObj().getName());
}
Enumeration<?> scalarTypeObj=EnumRegistry.getInstance().get("ScalarType");
@@ -192,24 +191,12 @@
* @return The created {@link EntityRecord} is returned.
*/
private EntityRecord<T> create(Core core) {
- Constructor<T> constructor = null;
- boolean isAccessible = false;
- try {
- constructor = request.entityConfig.getEntityClass().getDeclaredConstructor(Core.class);
- isAccessible = constructor.isAccessible();
- constructor.setAccessible(true);
- EntityRecord<T> entityRecord = new EntityRecord<>(constructor.newInstance(core), core);
- entityRecords.put(core.getID(), entityRecord);
- entities.add(entityRecord.entity);
- return entityRecord;
- } catch (InstantiationException | IllegalAccessException | NoSuchMethodException
- | InvocationTargetException e) {
- throw new IllegalStateException(e.getMessage(), e);
- } finally {
- if (constructor != null) {
- constructor.setAccessible(isAccessible);
- }
- }
+ ODSEntityFactory odsEntityFactory = new ODSEntityFactory(request.getODSModelManager(), null);
+ EntityRecord<T> entityRecord = new EntityRecord<>(
+ odsEntityFactory.createEntity(request.entityConfig.getEntityClass(), core), core);
+ entityRecords.put(core.getID(), entityRecord);
+ entities.add(entityRecord.entity);
+ return entityRecord;
}
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/RelationConfig.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/RelationConfig.java
index 8df3de6..a2dee0d 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/RelationConfig.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/RelationConfig.java
@@ -6,10 +6,10 @@
import java.util.Map;
import java.util.Optional;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.Entity;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.Record;
-import org.eclipse.mdm.api.base.query.Relation;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;
/**
@@ -69,7 +69,7 @@
if (relatedEntityID.isPresent()) {
dependants.computeIfAbsent(relatedEntityID.get(), k -> new ArrayList<>()).add(entityRecord);
} else if (mandatory) {
- throw new IllegalStateException("Mandatory relation unsatisfied.");
+ throw new IllegalStateException("Mandatory relation unsatisfied for relation "+relation.getName());
}
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/EntityConfig.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/EntityConfig.java
index fdb39a9..29683eb 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/EntityConfig.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/EntityConfig.java
@@ -7,11 +7,11 @@
import java.util.Objects;
import java.util.Optional;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.ContextType;
import org.eclipse.mdm.api.base.model.Deletable;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.StatusAttachable;
-import org.eclipse.mdm.api.base.query.EntityType;
/**
* Describes the composition of an {@link Entity} with its mandatory, optional
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/EntityConfigRepository.java b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/EntityConfigRepository.java
index 4bec31a..b48f46a 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/EntityConfigRepository.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/lookup/config/EntityConfigRepository.java
@@ -4,10 +4,10 @@
import java.util.Map;
import java.util.Optional;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.ContextComponent;
import org.eclipse.mdm.api.base.model.ContextRoot;
import org.eclipse.mdm.api.base.model.Entity;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig.Key;
/**
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/NotificationEntityLoader.java b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/NotificationEntityLoader.java
index c976faa..63f5d41 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/NotificationEntityLoader.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/NotificationEntityLoader.java
@@ -5,6 +5,7 @@
import java.util.List;
import java.util.stream.Collectors;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.ContextComponent;
import org.eclipse.mdm.api.base.model.ContextDescribable;
import org.eclipse.mdm.api.base.model.ContextRoot;
@@ -12,9 +13,9 @@
import org.eclipse.mdm.api.base.model.Measurement;
import org.eclipse.mdm.api.base.model.TestStep;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.JoinType;
+import org.eclipse.mdm.api.base.query.QueryService;
import org.eclipse.mdm.api.base.query.ComparisonOperator;
import org.eclipse.mdm.api.base.query.Record;
import org.eclipse.mdm.api.odsadapter.lookup.EntityLoader;
@@ -29,13 +30,15 @@
private static final Logger LOGGER = LoggerFactory.getLogger(NotificationEntityLoader.class);
private final ODSModelManager modelManager;
+ private final QueryService queryService;
private final EntityLoader loader;
private boolean loadContextDescribable;
- public NotificationEntityLoader(ODSModelManager modelManager, boolean loadContextDescribable) {
+ public NotificationEntityLoader(ODSModelManager modelManager, QueryService queryService, boolean loadContextDescribable) {
this.modelManager = modelManager;
- this.loader = new EntityLoader(modelManager);
+ this.queryService = queryService;
+ this.loader = new EntityLoader(modelManager, queryService);
this.loadContextDescribable = loadContextDescribable;
}
@@ -101,12 +104,12 @@
final EntityType testStep = modelManager.getEntityType(TestStep.class);
final EntityType measurement = modelManager.getEntityType(Measurement.class);
- List<String> testStepIDs = modelManager.createQuery().selectID(testStep)
+ List<String> testStepIDs = queryService.createQuery().selectID(testStep)
.join(testStep.getRelation(contextRoot), JoinType.OUTER)
.fetch(Filter.and().add(ComparisonOperator.IN_SET.create(contextRoot.getIDAttribute(), ids)))
.stream().map(r -> r.getRecord(testStep)).map(Record::getID).collect(Collectors.toList());
- List<String> measurementIDs = modelManager.createQuery().selectID(measurement)
+ List<String> measurementIDs = queryService.createQuery().selectID(measurement)
.join(measurement.getRelation(contextRoot), JoinType.OUTER)
.fetch(Filter.and().add(ComparisonOperator.IN_SET.create(contextRoot.getIDAttribute(), ids)))
.stream().map(r -> r.getRecord(measurement)).map(Record::getID).collect(Collectors.toList());
@@ -138,13 +141,13 @@
final EntityType testStep = modelManager.getEntityType(TestStep.class);
final EntityType measurement = modelManager.getEntityType(Measurement.class);
- List<String> testStepIDs = modelManager.createQuery().selectID(testStep)
+ List<String> testStepIDs = queryService.createQuery().selectID(testStep)
.join(testStep.getRelation(contextRoot), JoinType.OUTER)
.join(contextRoot.getRelation(contextComponent), JoinType.OUTER)
.fetch(Filter.and().add(ComparisonOperator.IN_SET.create(contextComponent.getIDAttribute(), ids)))
.stream().map(r -> r.getRecord(testStep)).map(Record::getID).collect(Collectors.toList());
- List<String> measurementIDs = modelManager.createQuery().selectID(measurement)
+ List<String> measurementIDs = queryService.createQuery().selectID(measurement)
.join(measurement.getRelation(contextRoot), JoinType.OUTER)
.join(contextRoot.getRelation(contextComponent), JoinType.OUTER)
.fetch(Filter.and().add(ComparisonOperator.IN_SET.create(contextComponent.getIDAttribute(), ids)))
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/ODSNotificationServiceFactory.java b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/ODSNotificationServiceFactory.java
new file mode 100644
index 0000000..3f64d9b
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/ODSNotificationServiceFactory.java
@@ -0,0 +1,96 @@
+package org.eclipse.mdm.api.odsadapter.notification;
+
+import java.util.Map;
+
+import org.eclipse.mdm.api.base.ConnectionException;
+import org.eclipse.mdm.api.base.ServiceNotProvidedException;
+import org.eclipse.mdm.api.base.adapter.ModelManager;
+import org.eclipse.mdm.api.base.notification.NotificationException;
+import org.eclipse.mdm.api.base.notification.NotificationService;
+import org.eclipse.mdm.api.base.query.QueryService;
+import org.eclipse.mdm.api.dflt.ApplicationContext;
+import org.eclipse.mdm.api.odsadapter.ODSContextFactory;
+import org.eclipse.mdm.api.odsadapter.notification.avalon.AvalonNotificationManager;
+import org.eclipse.mdm.api.odsadapter.notification.peak.PeakNotificationManager;
+import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Factory for creating a notification service.
+ *
+ * @since 1.0.0
+ * @author Matthias Koller, Peak Solution GmbH
+ *
+ */
+public class ODSNotificationServiceFactory {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ODSNotificationServiceFactory.class);
+
+ public static final String PARAM_SERVER_TYPE = "freetext.notificationType";
+ public static final String PARAM_URL = "freetext.notificationUrl";
+ public static final String PARAM_POLLING_INTERVAL = "freetext.pollingInterval";
+
+ public static final String SERVER_TYPE_PEAK = "peak";
+ public static final String SERVER_TYPE_AVALON = "avalon";
+
+ public static final String PARAM_NAMESERVICE_URL = "nameserviceURL";
+
+ public NotificationService create(ApplicationContext context, Map<String, String> parameters) throws ConnectionException {
+ String type = getParameter(parameters, PARAM_SERVER_TYPE);
+
+ ModelManager mm = context.getModelManager()
+ .orElseThrow(() -> new ServiceNotProvidedException(ModelManager.class));
+
+ QueryService queryService = context.getQueryService()
+ .orElseThrow(() -> new ServiceNotProvidedException(QueryService.class));
+
+ if (!ODSModelManager.class.isInstance(mm)) {
+ throw new ConnectionException("ModelManager is not a ODSModelManager!");
+ }
+
+ if (SERVER_TYPE_PEAK.equalsIgnoreCase(type)) {
+ String url = getParameter(parameters, PARAM_URL);
+
+ LOGGER.info("Connecting to Peak Notification Server ...");
+ LOGGER.info("URL: {}", url);
+
+ try {
+ return new PeakNotificationManager((ODSModelManager) mm, queryService, url, true);
+ } catch (NotificationException e) {
+ throw new ConnectionException("Could not connect to notification service!", e);
+ }
+ } else if (SERVER_TYPE_AVALON.equalsIgnoreCase(type)) {
+
+ String serviceName = getParameter(parameters, ODSContextFactory.PARAM_SERVICENAME);
+ serviceName = serviceName.replace(".ASAM-ODS", "");
+ String nameServiceURL = getParameter(parameters, ODSContextFactory.PARAM_NAMESERVICE);
+
+ LOGGER.info("Connecting to Avalon Notification Server ...");
+ LOGGER.info("Name service URL: {}", nameServiceURL);
+ LOGGER.info("Service name: {}", serviceName);
+
+ long pollingInterval = 500L;
+ try {
+ pollingInterval = Long.parseLong(getParameter(parameters, PARAM_POLLING_INTERVAL));
+ } catch (NumberFormatException | ConnectionException e) {
+ LOGGER.warn("Could not parse parse parameter pollingInterval. Using default value: " + pollingInterval,
+ e);
+ }
+
+ return new AvalonNotificationManager((ODSModelManager) mm, queryService, serviceName, nameServiceURL, true,
+ pollingInterval);
+ } else {
+ throw new ConnectionException("Invalid server type. Expected on of: 'peak'");
+ }
+
+ }
+
+ private String getParameter(Map<String, String> parameters, String name) throws ConnectionException {
+ String value = parameters.get(name);
+ if (value == null || value.isEmpty()) {
+ throw new ConnectionException("Connection parameter with name '" + name + "' is either missing or empty.");
+ }
+
+ return value;
+ }
+}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/avalon/AvalonNotificationManager.java b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/avalon/AvalonNotificationManager.java
index ba66a74..6233afc 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/avalon/AvalonNotificationManager.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/avalon/AvalonNotificationManager.java
@@ -12,6 +12,7 @@
import java.util.stream.Collectors;
import org.asam.ods.T_LONGLONG;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.ContextComponent;
import org.eclipse.mdm.api.base.model.ContextDescribable;
import org.eclipse.mdm.api.base.model.ContextRoot;
@@ -20,9 +21,9 @@
import org.eclipse.mdm.api.base.notification.NotificationFilter;
import org.eclipse.mdm.api.base.notification.NotificationFilter.ModificationType;
import org.eclipse.mdm.api.base.notification.NotificationListener;
-import org.eclipse.mdm.api.base.notification.NotificationManager;
+import org.eclipse.mdm.api.base.notification.NotificationService;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
+import org.eclipse.mdm.api.base.query.QueryService;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig.Key;
import org.eclipse.mdm.api.odsadapter.notification.NotificationEntityLoader;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
@@ -46,7 +47,7 @@
* @author Matthias Koller, Peak Solution GmbH
*
*/
-public class AvalonNotificationManager implements NotificationManager {
+public class AvalonNotificationManager implements NotificationService {
private static final Logger LOGGER = LoggerFactory.getLogger(AvalonNotificationManager.class);
@@ -78,13 +79,13 @@
* @param pollingInterval
* polling interval in milleseconds
*/
- public AvalonNotificationManager(ODSModelManager modelManager, String serviceName, String nameServiceURL,
+ public AvalonNotificationManager(ODSModelManager modelManager, QueryService queryService, String serviceName, String nameServiceURL,
boolean loadContextDescribable, long pollingInterval) {
this.modelManager = modelManager;
this.serviceName = serviceName;
this.nameServiceURL = nameServiceURL;
this.pollingInterval = pollingInterval;
- loader = new NotificationEntityLoader(modelManager, loadContextDescribable);
+ loader = new NotificationEntityLoader(modelManager, queryService, loadContextDescribable);
}
@Override
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 68b41cf..42ec47c 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
@@ -13,12 +13,13 @@
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.User;
import org.eclipse.mdm.api.base.notification.NotificationException;
import org.eclipse.mdm.api.base.notification.NotificationFilter;
import org.eclipse.mdm.api.base.notification.NotificationListener;
-import org.eclipse.mdm.api.base.notification.NotificationManager;
-import org.eclipse.mdm.api.base.query.EntityType;
+import org.eclipse.mdm.api.base.notification.NotificationService;
+import org.eclipse.mdm.api.base.query.QueryService;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig.Key;
import org.eclipse.mdm.api.odsadapter.notification.NotificationEntityLoader;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
@@ -28,7 +29,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Strings;
import com.peaksolution.ods.notification.protobuf.NotificationProtos.Notification;
/**
@@ -39,7 +39,7 @@
* @author Matthias Koller, Peak Solution GmbH
*
*/
-public class PeakNotificationManager implements NotificationManager {
+public class PeakNotificationManager implements NotificationService {
private static final Logger LOGGER = LoggerFactory.getLogger(PeakNotificationManager.class);
@@ -50,7 +50,6 @@
private final ExecutorService executor = Executors.newCachedThreadPool();
- private final MediaType eventMediaType;
private final ODSModelManager modelManager;
private final NotificationEntityLoader loader;
@@ -59,8 +58,6 @@
* @param modelManager
* @param url
* URL of the notification plugin
- * @param eventMediaType
- * MediaType to use.
* @param loadContextDescribable
* if true, the corresponding context describable is loaded if a
* notification for a context root or context component is
@@ -69,19 +66,13 @@
* Thrown if the manager cannot connect to the notification
* server.
*/
- public PeakNotificationManager(ODSModelManager modelManager, String url, String eventMediaType,
+ public PeakNotificationManager(ODSModelManager modelManager, QueryService queryService, String url,
boolean loadContextDescribable) throws NotificationException {
this.modelManager = modelManager;
- loader = new NotificationEntityLoader(modelManager, loadContextDescribable);
+ loader = new NotificationEntityLoader(modelManager, queryService, loadContextDescribable);
try {
- if (Strings.isNullOrEmpty(eventMediaType) || MediaType.APPLICATION_JSON.equalsIgnoreCase(eventMediaType)) {
- this.eventMediaType = MediaType.APPLICATION_JSON_TYPE;
- } else {
- this.eventMediaType = ProtobufMessageBodyProvider.APPLICATION_PROTOBUF_TYPE;
- }
-
- client = ClientBuilder.newBuilder().register(SseFeature.class).register(ProtobufMessageBodyProvider.class)
+ client = ClientBuilder.newBuilder().register(SseFeature.class)
.register(JsonMessageBodyProvider.class).build();
endpoint = client.target(url).path("events");
@@ -101,14 +92,16 @@
@Override
public void register(String registration, NotificationFilter filter, NotificationListener listener)
throws NotificationException {
- LOGGER.info("Starting registration for with name: " + registration);
+ LOGGER.info("Starting registration for with name: {}", registration);
Response response = endpoint.path(registration).request().post(javax.ws.rs.client.Entity
- .entity(ProtobufConverter.from(filter), ProtobufMessageBodyProvider.APPLICATION_PROTOBUF_TYPE));
+ .entity(ProtobufConverter.from(filter), MediaType.APPLICATION_JSON_TYPE));
if (response.getStatusInfo().getStatusCode() == Status.CONFLICT.getStatusCode()) {
- LOGGER.info("A registration with the name already exists: " + response.readEntity(String.class));
- LOGGER.info("Trying to reregister...");
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info("A registration with the name already exists: {}", response.readEntity(String.class));
+ LOGGER.info("Trying to reregister...");
+ }
deregister(registration);
LOGGER.info("Deregisteration successful.");
register(registration, filter, listener);
@@ -121,13 +114,13 @@
}
try {
- LOGGER.info("Requesting event input for " + registration);
+ 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, eventMediaType);
+ EventProcessor processor = new EventProcessor(eventInput, listener, this, MediaType.APPLICATION_JSON_TYPE);
executor.submit(processor);
@@ -166,10 +159,10 @@
for (String registration : processors.keySet()) {
if (isDeregisterAll) {
- LOGGER.debug("Deregistering '" + registration + "'.");
+ LOGGER.debug("Deregistering '{}'.", registration);
deregister(registration);
} else {
- LOGGER.debug("Disconnecting '" + registration + "'.");
+ LOGGER.debug("Disconnecting '{}'.", registration);
close(registration);
}
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/ProtobufMessageBodyProvider.java b/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/ProtobufMessageBodyProvider.java
deleted file mode 100644
index 4fc177e..0000000
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/notification/peak/ProtobufMessageBodyProvider.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package org.eclipse.mdm.api.odsadapter.notification.peak;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyReader;
-import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Provider;
-
-import com.google.protobuf.GeneratedMessage;
-import com.google.protobuf.Message;
-
-/**
- * MessageBodyProvider for handling protobuf payloads.
- *
- * @since 1.0.0
- * @author Matthias Koller, Peak Solution GmbH
- *
- */
-@Provider
-@Consumes(ProtobufMessageBodyProvider.APPLICATION_PROTOBUF)
-@Produces(ProtobufMessageBodyProvider.APPLICATION_PROTOBUF)
-public class ProtobufMessageBodyProvider implements MessageBodyReader<Message>, MessageBodyWriter<Message> {
- /**
- * application/x-protobuf
- */
- public final static String APPLICATION_PROTOBUF = "application/x-protobuf";
-
- /**
- * application/x-protobuf
- */
- public final static MediaType APPLICATION_PROTOBUF_TYPE = new MediaType("application", "x-protobuf");
-
- @Override
- public boolean isReadable(final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType) {
- return Message.class.isAssignableFrom(type);
- }
-
- @Override
- public Message readFrom(final Class<Message> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType, final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream)
- throws IOException {
-
- try {
- final Method newBuilder = type.getMethod("newBuilder");
- final GeneratedMessage.Builder<?> builder = (GeneratedMessage.Builder<?>) newBuilder.invoke(type);
-
- return builder.mergeFrom(entityStream).build();
- } catch (Exception e) {
- throw new WebApplicationException(e);
- }
- }
-
- @Override
- public long getSize(final Message m, final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType) {
- return m.getSerializedSize();
- }
-
- @Override
- public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType) {
- return Message.class.isAssignableFrom(type);
- }
-
- @Override
- public void writeTo(final Message m, final Class<?> type, final Type genericType, final Annotation[] annotations,
- final MediaType mediaType, final MultivaluedMap<String, Object> httpHeaders,
- final OutputStream entityStream) throws IOException {
- m.writeTo(entityStream);
- }
-}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSAttribute.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSAttribute.java
index ca8a946..769aaef 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSAttribute.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSAttribute.java
@@ -14,11 +14,11 @@
import org.asam.ods.ApplAttr;
import org.eclipse.mdm.api.base.model.Value;
+import org.eclipse.mdm.api.base.adapter.Attribute;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.Enumeration;
import org.eclipse.mdm.api.base.model.ValueType;
-import org.eclipse.mdm.api.base.query.Attribute;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.Relation;
import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;
/**
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityFactory.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityFactory.java
index 3f093b5..f609cd8 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityFactory.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityFactory.java
@@ -8,19 +8,26 @@
package org.eclipse.mdm.api.odsadapter.query;
-import static org.eclipse.mdm.api.dflt.model.CatalogAttribute.VATTR_ENUMERATION_CLASS;
+import static org.eclipse.mdm.api.dflt.model.CatalogAttribute.VATTR_ENUMERATION_NAME;
import static org.eclipse.mdm.api.dflt.model.CatalogAttribute.VATTR_SCALAR_TYPE;
import static org.eclipse.mdm.api.dflt.model.CatalogAttribute.VATTR_SEQUENCE;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
+import org.eclipse.mdm.api.base.adapter.ChildrenStore;
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.adapter.DefaultCore;
+import org.eclipse.mdm.api.base.adapter.EntityStore;
import org.eclipse.mdm.api.base.model.AxisType;
+import org.eclipse.mdm.api.base.model.BaseEntity;
import org.eclipse.mdm.api.base.model.ContextType;
-import org.eclipse.mdm.api.base.model.Core;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.EnumRegistry;
+import org.eclipse.mdm.api.base.model.Enumeration;
import org.eclipse.mdm.api.base.model.EnumerationValue;
import org.eclipse.mdm.api.base.model.Interpolation;
import org.eclipse.mdm.api.base.model.ScalarType;
@@ -29,7 +36,6 @@
import org.eclipse.mdm.api.base.model.User;
import org.eclipse.mdm.api.base.model.ValueType;
import org.eclipse.mdm.api.base.model.VersionState;
-import org.eclipse.mdm.api.base.query.DefaultCore;
import org.eclipse.mdm.api.dflt.model.CatalogAttribute;
import org.eclipse.mdm.api.dflt.model.EntityFactory;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;
@@ -81,6 +87,55 @@
this.modelManager = modelManager;
this.loggedInUser = loggedInUser;
}
+
+ // ======================================================================
+ // Public methods
+ // ======================================================================
+
+ /**
+ * Extracts the {@link Core} from an {@link Entity} instance. This method
+ * effectively makes access to the Core of a BaseEntity publicly
+ * available (by calling the corresponding protected method of
+ * BaseEntityFactory, which is this class's superclass) to users of
+ * ODSEntityFactory.
+ *
+ * @param entity
+ * The {@link Entity} from which to extract the {@link Core}.
+ * @return The entity's {@link Core}.
+ */
+ public static Core extract(Entity entity) {
+ if (entity instanceof BaseEntity) {
+ return getCore((BaseEntity) entity);
+ } else {
+ throw new IllegalArgumentException("Entity of type '" + entity.getClass().getSimpleName()
+ + "' does not extend '" + BaseEntity.class.getName() + "'");
+ }
+ }
+
+ /**
+ * Create an instance of a class implementing the {@link Entity} interface with
+ * core as the instance's {@link Core}. This method effectively makes the
+ * protected BaseEntity constructor publicly available (by calling the
+ * corresponding protected method of BaseEntityFactory, which is this class's
+ * superclass) to users of ODSEntityFactory.
+ *
+ * @param clazz
+ * The class to instantiate, must implement the {@link Entity}
+ * interface.
+ * @param core
+ * The {@link Core} to use for the newly created instance.
+ * @return The newly created instance.
+ */
+ @SuppressWarnings("unchecked")
+ public <T extends Entity> T createEntity(Class<T> clazz, Core core) {
+ if (BaseEntity.class.isAssignableFrom(clazz)) {
+ return (T) createBaseEntity(clazz.asSubclass(BaseEntity.class), core);
+ } else {
+ throw new IllegalArgumentException(
+ "Class '" + clazz.getSimpleName() + "' does not extend '" + BaseEntity.class.getName() + "'");
+ }
+
+ }
// ======================================================================
// Protected methods
@@ -109,6 +164,27 @@
protected <T extends Entity> Core createCore(Class<T> entityClass, ContextType contextType) {
return createCore(new Key<>(entityClass, contextType));
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public static final EntityStore getMutableStore(BaseEntity entity) {
+ return EntityFactory.getMutableStore(entity);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public static final EntityStore getPermanentStore(BaseEntity entity) {
+ return EntityFactory.getPermanentStore(entity);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public static final ChildrenStore getChildrenStore(BaseEntity entity) {
+ return EntityFactory.getChildrenStore(entity);
+ }
/**
* {@inheritDoc}
@@ -130,16 +206,29 @@
* {@inheritDoc}
*/
@Override
- protected void validateEnum(Class<? extends EnumerationValue> enumClass) {
- if (ENUM_CLASSES.contains(enumClass)) {
- // given enumeration class is a default one, which is always
- // supported
- return;
+ protected void validateEnum(Enumeration<?> enumerationObj) {
+ EnumRegistry er = EnumRegistry.getInstance();
+ // check if enum is properly registered
+ if (er.get(enumerationObj.getName())==null) {
+ throw new IllegalArgumentException("Given enum class '" + enumerationObj.getName() + "' is not supported.");
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected <T extends BaseEntity> T createBaseEntity(Class<T> clazz, Core core) {
+ try {
+ Constructor<T> constructor = clazz.getDeclaredConstructor(Core.class);
+ try {
+ return constructor.newInstance(core);
+ } catch (IllegalAccessException exc) {
+ return super.createBaseEntity(clazz, core);
+ }
+ } catch (NoSuchMethodException | InvocationTargetException | InstantiationException exc) {
+ throw new IllegalStateException(exc.getMessage(), exc);
}
-
- // TODO check here for other enumeration classes introduced by modules
-
- throw new IllegalArgumentException("Given enum class '" + enumClass.getSimpleName() + "' is not supported.");
}
// ======================================================================
@@ -161,12 +250,11 @@
core.getValues().get(Entity.ATTR_MIMETYPE).set(entityConfig.getMimeType());
if (CatalogAttribute.class.equals(entityConfig.getEntityClass())) {
- core.getValues().put(VATTR_ENUMERATION_CLASS, ValueType.STRING.create(VATTR_ENUMERATION_CLASS));
+ core.getValues().put(VATTR_ENUMERATION_NAME, ValueType.STRING.create(VATTR_ENUMERATION_NAME));
core.getValues().put(VATTR_SCALAR_TYPE, ValueType.ENUMERATION.create(EnumRegistry.getInstance().get("ScalarType"), VATTR_SCALAR_TYPE));
core.getValues().put(VATTR_SEQUENCE, ValueType.BOOLEAN.create(VATTR_SEQUENCE));
}
return core;
}
-
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityType.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityType.java
index 6fc22c6..44cdb96 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityType.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSEntityType.java
@@ -26,11 +26,11 @@
import org.asam.ods.ApplElem;
import org.asam.ods.T_LONGLONG;
+import org.eclipse.mdm.api.base.adapter.Attribute;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.Relation;
+import org.eclipse.mdm.api.base.adapter.RelationType;
import org.eclipse.mdm.api.base.model.Enumeration;
-import org.eclipse.mdm.api.base.query.Attribute;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.Relation;
-import org.eclipse.mdm.api.base.query.RelationType;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
/**
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSModelManager.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSModelManager.java
index 4d26e93..4a2df93 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSModelManager.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSModelManager.java
@@ -39,6 +39,9 @@
import org.asam.ods.SelItem;
import org.asam.ods.SelOrder;
import org.asam.ods.T_LONGLONG;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.ModelManager;
+import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.ContextComponent;
@@ -59,10 +62,6 @@
import org.eclipse.mdm.api.base.model.TestStep;
import org.eclipse.mdm.api.base.model.Unit;
import org.eclipse.mdm.api.base.model.User;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.ModelManager;
-import org.eclipse.mdm.api.base.query.Query;
-import org.eclipse.mdm.api.base.query.Relation;
import org.eclipse.mdm.api.dflt.model.CatalogAttribute;
import org.eclipse.mdm.api.dflt.model.CatalogComponent;
import org.eclipse.mdm.api.dflt.model.CatalogSensor;
@@ -89,8 +88,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.highqsoft.corbafileserver.generated.CORBAFileServerIF;
-
/**
* ODS implementation of the {@link ModelManager} interface.
*
@@ -99,19 +96,11 @@
*/
public class ODSModelManager implements ModelManager {
- // ======================================================================
- // Class variables
- // ======================================================================
-
private static final Logger LOGGER = LoggerFactory.getLogger(ODSModelManager.class);
- // ======================================================================
- // Instance variables
- // ======================================================================
-
private final Map<String, EntityType> entityTypesByName = new HashMap<>();
- private final CORBAFileServerIF fileServer;
+
private final ORB orb;
private final Lock write;
@@ -122,10 +111,6 @@
private ApplElemAccess applElemAccess;
private AoSession aoSession;
- // ======================================================================
- // Constructors
- // ======================================================================
-
/**
* Constructor.
*
@@ -133,13 +118,10 @@
* Used to activate CORBA service objects.
* @param aoSession
* The underlying ODS session.
- * @param fileServer
- * Used for file transfers.
* @throws AoException
* Thrown on errors.
*/
- public ODSModelManager(ORB orb, AoSession aoSession, CORBAFileServerIF fileServer) throws AoException {
- this.fileServer = fileServer;
+ public ODSModelManager(ORB orb, AoSession aoSession) throws AoException {
this.aoSession = aoSession;
this.orb = orb;
applElemAccess = aoSession.getApplElemAccess();
@@ -149,34 +131,9 @@
write = reentrantReadWriteLock.writeLock();
read = reentrantReadWriteLock.readLock();
- // initialization
initialize();
}
- // ======================================================================
- // Public methods
- // ======================================================================
-
- /**
- * Returns a new {@link ODSModelManager} with a new ODS co-session.
- *
- * @return The created {@code ODSModelManager} is returned.
- * @throws AoException
- * Thrown on errors.
- */
- public ODSModelManager newSession() throws AoException {
- return new ODSModelManager(orb, getAoSession().createCoSession(), fileServer);
- }
-
- /**
- * Returns the {@link CORBAFileServerIF}.
- *
- * @return The {@code CORBAFileServerIF} is returned or null, if missing.
- */
- public CORBAFileServerIF getFileServer() {
- return fileServer;
- }
-
/**
* Returns the {@link ORB}.
*
@@ -246,20 +203,6 @@
* {@inheritDoc}
*/
@Override
- public Query createQuery() {
- read.lock();
-
- try {
- return new ODSQuery(getApplElemAccess());
- } finally {
- read.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
public List<EntityType> listEntityTypes() {
read.lock();
@@ -405,10 +348,6 @@
}
}
- // ======================================================================
- // Private methods
- // ======================================================================
-
/**
* Initializes this model manager by caching the application model and
* loading the {@link EntityConfig}s.
@@ -440,10 +379,9 @@
Enumeration<ODSEnum> enumdyn = new Enumeration<>(ODSEnum.class, eas.enumName);
EnumerationDefinition enumdef = applicationStructure.getEnumerationDefinition(eas.enumName);
String[] listItemNames = enumdef.listItemNames();
- int ordinal = 0;
for (String item : listItemNames) {
+ int ordinal=enumdef.getItem(item);
enumdyn.addValue(new ODSEnum(item, ordinal));
- ordinal++;
}
er.add(eas.enumName, enumdyn);
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQuery.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQuery.java
index 0571d24..507265e 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQuery.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQuery.java
@@ -34,18 +34,18 @@
import org.asam.ods.SelOrder;
import org.asam.ods.SelValueExt;
import org.asam.ods.T_LONGLONG;
+import org.eclipse.mdm.api.base.adapter.Attribute;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.query.Aggregation;
-import org.eclipse.mdm.api.base.query.Attribute;
import org.eclipse.mdm.api.base.query.Condition;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.FilterItem;
import org.eclipse.mdm.api.base.query.JoinType;
import org.eclipse.mdm.api.base.query.Query;
import org.eclipse.mdm.api.base.query.Record;
-import org.eclipse.mdm.api.base.query.Relation;
import org.eclipse.mdm.api.base.query.Result;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQueryService.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQueryService.java
new file mode 100644
index 0000000..9e3a607
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSQueryService.java
@@ -0,0 +1,21 @@
+package org.eclipse.mdm.api.odsadapter.query;
+
+import org.eclipse.mdm.api.base.query.Query;
+import org.eclipse.mdm.api.base.query.QueryService;
+
+public class ODSQueryService implements QueryService {
+
+ private ODSModelManager modelManager;
+
+ public ODSQueryService(ODSModelManager modelManager) {
+ this.modelManager = modelManager;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Query createQuery() {
+ return new ODSQuery(modelManager.getApplElemAccess());
+ }
+}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSRelation.java b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSRelation.java
index e200a1a..4da0adc 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSRelation.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/query/ODSRelation.java
@@ -13,10 +13,10 @@
import org.asam.ods.ApplAttr;
import org.asam.ods.ApplRel;
import org.asam.ods.DataType;
-import org.eclipse.mdm.api.base.query.Attribute;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.Relation;
-import org.eclipse.mdm.api.base.query.RelationType;
+import org.eclipse.mdm.api.base.adapter.Attribute;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.Relation;
+import org.eclipse.mdm.api.base.adapter.RelationType;
import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;
/**
@@ -25,7 +25,7 @@
* @since 1.0.0
* @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
*/
-final class ODSRelation implements Relation {
+public final class ODSRelation implements Relation {
// ======================================================================
// Instance variables
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 b0e74f8..d299469 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
@@ -19,6 +19,9 @@
import java.util.function.Function;
import java.util.stream.Collectors;
+import org.eclipse.mdm.api.base.adapter.Attribute;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.ContextRoot;
import org.eclipse.mdm.api.base.model.ContextType;
import org.eclipse.mdm.api.base.model.Entity;
@@ -26,17 +29,15 @@
import org.eclipse.mdm.api.base.model.TestStep;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.query.Aggregation;
-import org.eclipse.mdm.api.base.query.Attribute;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.FilterItem;
import org.eclipse.mdm.api.base.query.JoinType;
import org.eclipse.mdm.api.base.query.Query;
-import org.eclipse.mdm.api.base.query.Relation;
+import org.eclipse.mdm.api.base.query.QueryService;
import org.eclipse.mdm.api.base.query.Result;
-import org.eclipse.mdm.api.base.query.SearchQuery;
-import org.eclipse.mdm.api.base.query.Searchable;
+import org.eclipse.mdm.api.base.search.SearchQuery;
+import org.eclipse.mdm.api.base.search.Searchable;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig.Key;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
@@ -60,7 +61,7 @@
private final Class<? extends Entity> entityClass;
private final ODSModelManager modelManager;
-
+ private final QueryService queryService;
// ======================================================================
// Constructors
// ======================================================================
@@ -75,9 +76,10 @@
* @param rootEntityClass
* The root entity class of this search query.
*/
- protected BaseEntitySearchQuery(ODSModelManager modelManager, Class<? extends Entity> entityClass,
+ protected BaseEntitySearchQuery(ODSModelManager modelManager, QueryService queryService, Class<? extends Entity> entityClass,
Class<? extends Entity> rootEntityClass) {
this.modelManager = modelManager;
+ this.queryService = queryService;
this.entityClass = entityClass;
this.rootEntityClass = rootEntityClass;
@@ -131,7 +133,7 @@
*/
@Override
public final List<Value> getFilterValues(Attribute attribute, Filter filter) throws DataAccessException {
- Query query = modelManager.createQuery().select(attribute, Aggregation.DISTINCT).group(attribute);
+ Query query = queryService.createQuery().select(attribute, Aggregation.DISTINCT).group(attribute);
// add required joins
filter.stream().filter(FilterItem::isCondition).map(FilterItem::getCondition).forEach(c -> {
@@ -146,7 +148,7 @@
*/
@Override
public final List<Result> fetchComplete(List<EntityType> entityTypes, Filter filter) throws DataAccessException {
- Query query = modelManager.createQuery().selectID(modelManager.getEntityType(entityClass));
+ Query query = queryService.createQuery().selectID(modelManager.getEntityType(entityClass));
// add required joins
entityTypes.stream().forEach(entityType -> {
@@ -162,7 +164,7 @@
*/
@Override
public final List<Result> fetch(List<Attribute> attributes, Filter filter) throws DataAccessException {
- Query query = modelManager.createQuery().selectID(modelManager.getEntityType(entityClass));
+ Query query = queryService.createQuery().selectID(modelManager.getEntityType(entityClass));
// add required joins
attributes.stream().forEach(attribute -> {
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/search/ChannelGroupSearchQuery.java b/src/main/java/org/eclipse/mdm/api/odsadapter/search/ChannelGroupSearchQuery.java
index b551c55..4dc8110 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/search/ChannelGroupSearchQuery.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/search/ChannelGroupSearchQuery.java
@@ -8,13 +8,14 @@
package org.eclipse.mdm.api.odsadapter.search;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.Measurement;
import org.eclipse.mdm.api.base.model.Test;
import org.eclipse.mdm.api.base.model.TestStep;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.SearchQuery;
+import org.eclipse.mdm.api.base.query.QueryService;
+import org.eclipse.mdm.api.base.search.SearchQuery;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
@@ -37,8 +38,8 @@
* @param contextState
* The {@link ContextState}.
*/
- ChannelGroupSearchQuery(ODSModelManager modelManager, ContextState contextState) {
- super(modelManager, ChannelGroup.class, Project.class);
+ ChannelGroupSearchQuery(ODSModelManager modelManager, QueryService queryService, ContextState contextState) {
+ super(modelManager, queryService, ChannelGroup.class, Project.class);
// layers
addJoinConfig(JoinConfig.up(Pool.class, Project.class));
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/search/ChannelSearchQuery.java b/src/main/java/org/eclipse/mdm/api/odsadapter/search/ChannelSearchQuery.java
index c8e22fa..320be56 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/search/ChannelSearchQuery.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/search/ChannelSearchQuery.java
@@ -8,13 +8,14 @@
package org.eclipse.mdm.api.odsadapter.search;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.Measurement;
import org.eclipse.mdm.api.base.model.Test;
import org.eclipse.mdm.api.base.model.TestStep;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.SearchQuery;
+import org.eclipse.mdm.api.base.query.QueryService;
+import org.eclipse.mdm.api.base.search.SearchQuery;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
@@ -36,8 +37,8 @@
* @param contextState
* The {@link ContextState}.
*/
- ChannelSearchQuery(ODSModelManager modelManager, ContextState contextState) {
- super(modelManager, Channel.class, Project.class);
+ ChannelSearchQuery(ODSModelManager modelManager, QueryService queryService, ContextState contextState) {
+ super(modelManager, queryService, Channel.class, Project.class);
// layers
addJoinConfig(JoinConfig.up(Pool.class, Project.class));
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/search/JoinTree.java b/src/main/java/org/eclipse/mdm/api/odsadapter/search/JoinTree.java
index 8c8e885..1918b80 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/search/JoinTree.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/search/JoinTree.java
@@ -8,10 +8,10 @@
import java.util.Map;
import java.util.Set;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.Entity;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.JoinType;
-import org.eclipse.mdm.api.base.query.SearchQuery;
+import org.eclipse.mdm.api.base.search.SearchQuery;
/**
* This class spans a dependency tree for conditional join statements is
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/search/MeasurementSearchQuery.java b/src/main/java/org/eclipse/mdm/api/odsadapter/search/MeasurementSearchQuery.java
index 538be58..298e20e 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/search/MeasurementSearchQuery.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/search/MeasurementSearchQuery.java
@@ -8,13 +8,14 @@
package org.eclipse.mdm.api.odsadapter.search;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.Measurement;
import org.eclipse.mdm.api.base.model.Test;
import org.eclipse.mdm.api.base.model.TestStep;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.SearchQuery;
+import org.eclipse.mdm.api.base.query.QueryService;
+import org.eclipse.mdm.api.base.search.SearchQuery;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
@@ -37,8 +38,8 @@
* @param contextState
* The {@link ContextState}.
*/
- MeasurementSearchQuery(ODSModelManager modelManager, ContextState contextState) {
- super(modelManager, Measurement.class, Project.class);
+ MeasurementSearchQuery(ODSModelManager modelManager, QueryService queryService, ContextState contextState) {
+ super(modelManager, queryService, Measurement.class, Project.class);
// layers
addJoinConfig(JoinConfig.up(Pool.class, Project.class));
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/search/MergedSearchQuery.java b/src/main/java/org/eclipse/mdm/api/odsadapter/search/MergedSearchQuery.java
index 1dc797d..a67e365 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/search/MergedSearchQuery.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/search/MergedSearchQuery.java
@@ -17,14 +17,14 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.eclipse.mdm.api.base.adapter.Attribute;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.Value;
-import org.eclipse.mdm.api.base.query.Attribute;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.Result;
-import org.eclipse.mdm.api.base.query.SearchQuery;
-import org.eclipse.mdm.api.base.query.Searchable;
+import org.eclipse.mdm.api.base.search.SearchQuery;
+import org.eclipse.mdm.api.base.search.Searchable;
/**
* Merges 2 distinct search queries, where one queries context data as ordered
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/search/ODSSearchService.java b/src/main/java/org/eclipse/mdm/api/odsadapter/search/ODSSearchService.java
index 2edaaf6..af80d3a 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/search/ODSSearchService.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/search/ODSSearchService.java
@@ -15,6 +15,8 @@
import java.util.Map;
import java.util.function.Function;
+import org.eclipse.mdm.api.base.adapter.Attribute;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.Entity;
@@ -23,16 +25,16 @@
import org.eclipse.mdm.api.base.model.Test;
import org.eclipse.mdm.api.base.model.TestStep;
import org.eclipse.mdm.api.base.model.Value;
-import org.eclipse.mdm.api.base.query.Attribute;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.Filter;
+import org.eclipse.mdm.api.base.query.QueryService;
import org.eclipse.mdm.api.base.query.Result;
-import org.eclipse.mdm.api.base.query.SearchQuery;
-import org.eclipse.mdm.api.base.query.SearchService;
-import org.eclipse.mdm.api.base.query.Searchable;
+import org.eclipse.mdm.api.base.search.SearchQuery;
+import org.eclipse.mdm.api.base.search.SearchService;
+import org.eclipse.mdm.api.base.search.Searchable;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
+import org.eclipse.mdm.api.odsadapter.ODSContext;
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.ODSModelManager;
@@ -50,31 +52,33 @@
private final Map<Class<? extends Entity>, SearchQuery> searchQueries = new HashMap<>();
- private final ODSModelManager modelManager;
+ private final ODSContext context;
private final EntityLoader entityLoader;
private final String esHost;
private ODSFreeTextSearch freeTextSearch;
+ public static final String PARAM_ELASTIC_SEARCH_URL = "elasticsearch.url";
+
/**
* Constructor.
*
- * @param modelManager
- * Used to retrieve {@link EntityType}s.
+ * @param context
+ * Used to retrieve {@link ODSModelManager}.
* @param entityLoader
* Used to load complete {@link Entity}s.
*/
- public ODSSearchService(ODSModelManager modelManager, EntityLoader entityLoader, String host) {
- this.modelManager = modelManager;
+ public ODSSearchService(ODSContext context, QueryService queryService, EntityLoader entityLoader) {
+ this.context = context;
this.entityLoader = entityLoader;
- esHost = host;
-
- registerMergedSearchQuery(Project.class, c -> new ProjectSearchQuery(modelManager, c));
- registerMergedSearchQuery(Pool.class, c -> new PoolSearchQuery(modelManager, c));
- registerMergedSearchQuery(Test.class, c -> new TestSearchQuery(modelManager, c));
- registerMergedSearchQuery(TestStep.class, c -> new TestStepSearchQuery(modelManager, c));
- registerMergedSearchQuery(Measurement.class, c -> new MeasurementSearchQuery(modelManager, c));
- registerMergedSearchQuery(ChannelGroup.class, c -> new ChannelGroupSearchQuery(modelManager, c));
- registerMergedSearchQuery(Channel.class, c -> new ChannelSearchQuery(modelManager, c));
+ esHost = context.getParameters().get(PARAM_ELASTIC_SEARCH_URL);
+
+ registerMergedSearchQuery(Project.class, c -> new ProjectSearchQuery(context.getODSModelManager(), queryService, c));
+ registerMergedSearchQuery(Pool.class, c -> new PoolSearchQuery(context.getODSModelManager(), queryService, c));
+ registerMergedSearchQuery(Test.class, c -> new TestSearchQuery(context.getODSModelManager(), queryService, c));
+ registerMergedSearchQuery(TestStep.class, c -> new TestStepSearchQuery(context.getODSModelManager(), queryService, c));
+ registerMergedSearchQuery(Measurement.class, c -> new MeasurementSearchQuery(context.getODSModelManager(), queryService, c));
+ registerMergedSearchQuery(ChannelGroup.class, c -> new ChannelGroupSearchQuery(context.getODSModelManager(), queryService, c));
+ registerMergedSearchQuery(Channel.class, c -> new ChannelSearchQuery(context.getODSModelManager(), queryService, c));
}
/**
@@ -114,7 +118,7 @@
* {@inheritDoc}
*/
@Override
- public <T extends Entity> Map<T, Result> fetchComplete(Class<T> entityClass, List<EntityType> entityTypes,
+ public <T extends Entity> List<T> fetchComplete(Class<T> entityClass, List<EntityType> entityTypes,
Filter filter) throws DataAccessException {
return createResult(entityClass, findSearchQuery(entityClass).fetchComplete(entityTypes, filter));
}
@@ -123,7 +127,7 @@
* {@inheritDoc}
*/
@Override
- public <T extends Entity> Map<T, Result> fetch(Class<T> entityClass, List<Attribute> attributes, Filter filter)
+ public <T extends Entity> List<T> fetch(Class<T> entityClass, List<Attribute> attributes, Filter filter)
throws DataAccessException {
return createResult(entityClass, findSearchQuery(entityClass).fetch(attributes, filter));
}
@@ -139,7 +143,7 @@
return Collections.emptyList();
}
- EntityType entityType = modelManager.getEntityType(entityClass);
+ EntityType entityType = context.getODSModelManager().getEntityType(entityClass);
Map<String, Result> recordsByEntityID = new HashMap<>();
for (Result result : findSearchQuery(entityClass).fetch(attributes, mergedFilter)) {
recordsByEntityID.put(result.getRecord(entityType).getID(), result);
@@ -229,7 +233,7 @@
Filter freeTextResultsFilter = Filter.or();
for (Map.Entry<Class<? extends Entity>, List<String>> entry : fetchIds(query).entrySet()) {
if (!entry.getValue().isEmpty()) {
- freeTextResultsFilter.ids(modelManager.getEntityType(entry.getKey()), entry.getValue());
+ freeTextResultsFilter.ids(context.getODSModelManager().getEntityType(entry.getKey()), entry.getValue());
}
}
@@ -245,14 +249,13 @@
* Entity class of the loaded {@code Entity}s.
* @param results
* The queried {@code Result}s.
- * @return All Results are returned in a Map, which maps entities to the
- * corresponding results.
+ * @return All loaded entities are returned as a {@link List}.
* @throws DataAccessException
* Thrown if unable to load the {@code Entity}s.
*/
- private <T extends Entity> Map<T, Result> createResult(Class<T> entityClass, List<Result> results)
+ private <T extends Entity> List<T> createResult(Class<T> entityClass, List<Result> results)
throws DataAccessException {
- EntityType entityType = modelManager.getEntityType(entityClass);
+ EntityType entityType = context.getODSModelManager().getEntityType(entityClass);
Map<String, Result> recordsByEntityID = new HashMap<>();
for (Result result : results) {
recordsByEntityID.put(result.getRecord(entityType).getID(), result);
@@ -263,7 +266,7 @@
resultsByEntity.put(entity, recordsByEntityID.get(entity.getID()));
}
- return resultsByEntity;
+ return new ArrayList<>(resultsByEntity.keySet());
}
/**
@@ -293,7 +296,7 @@
*/
private void registerMergedSearchQuery(Class<? extends Entity> entityClass,
Function<ContextState, BaseEntitySearchQuery> factory) {
- searchQueries.put(entityClass, new MergedSearchQuery(modelManager.getEntityType(entityClass), factory));
+ searchQueries.put(entityClass, new MergedSearchQuery(context.getODSModelManager().getEntityType(entityClass), factory));
}
private void initFreetextSearch() throws DataAccessException {
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/search/PoolSearchQuery.java b/src/main/java/org/eclipse/mdm/api/odsadapter/search/PoolSearchQuery.java
index 4878e2f..b31d952 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/search/PoolSearchQuery.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/search/PoolSearchQuery.java
@@ -8,13 +8,14 @@
package org.eclipse.mdm.api.odsadapter.search;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.Measurement;
import org.eclipse.mdm.api.base.model.Test;
import org.eclipse.mdm.api.base.model.TestStep;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.SearchQuery;
+import org.eclipse.mdm.api.base.query.QueryService;
+import org.eclipse.mdm.api.base.search.SearchQuery;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
@@ -36,8 +37,8 @@
* @param contextState
* The {@link ContextState}.
*/
- PoolSearchQuery(ODSModelManager modelManager, ContextState contextState) {
- super(modelManager, Pool.class, Project.class);
+ PoolSearchQuery(ODSModelManager modelManager, QueryService queryService, ContextState contextState) {
+ super(modelManager, queryService, Pool.class, Project.class);
// layers
addJoinConfig(JoinConfig.up(Pool.class, Project.class));
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/search/ProjectSearchQuery.java b/src/main/java/org/eclipse/mdm/api/odsadapter/search/ProjectSearchQuery.java
index 54e3a74..6a2c0fa 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/search/ProjectSearchQuery.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/search/ProjectSearchQuery.java
@@ -8,13 +8,14 @@
package org.eclipse.mdm.api.odsadapter.search;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.Measurement;
import org.eclipse.mdm.api.base.model.Test;
import org.eclipse.mdm.api.base.model.TestStep;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.SearchQuery;
+import org.eclipse.mdm.api.base.query.QueryService;
+import org.eclipse.mdm.api.base.search.SearchQuery;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
@@ -36,8 +37,8 @@
* @param contextState
* The {@link ContextState}.
*/
- ProjectSearchQuery(ODSModelManager modelManager, ContextState contextState) {
- super(modelManager, Project.class, Project.class);
+ ProjectSearchQuery(ODSModelManager modelManager, QueryService queryService, ContextState contextState) {
+ super(modelManager, queryService, Project.class, Project.class);
// layers
addJoinConfig(JoinConfig.down(Project.class, Pool.class));
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/search/SearchableNode.java b/src/main/java/org/eclipse/mdm/api/odsadapter/search/SearchableNode.java
index 72218f6..0756cbf 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/search/SearchableNode.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/search/SearchableNode.java
@@ -13,8 +13,8 @@
import java.util.List;
import java.util.stream.Collectors;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.Searchable;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.search.Searchable;
/**
* Implementation of the {@link Searchable} interface for use in search queries
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/search/TestSearchQuery.java b/src/main/java/org/eclipse/mdm/api/odsadapter/search/TestSearchQuery.java
index 8208d4a..c3fef23 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/search/TestSearchQuery.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/search/TestSearchQuery.java
@@ -8,13 +8,14 @@
package org.eclipse.mdm.api.odsadapter.search;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.Measurement;
import org.eclipse.mdm.api.base.model.Test;
import org.eclipse.mdm.api.base.model.TestStep;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.SearchQuery;
+import org.eclipse.mdm.api.base.query.QueryService;
+import org.eclipse.mdm.api.base.search.SearchQuery;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
@@ -36,8 +37,8 @@
* @param contextState
* The {@link ContextState}.
*/
- TestSearchQuery(ODSModelManager modelManager, ContextState contextState) {
- super(modelManager, Test.class, Project.class);
+ TestSearchQuery(ODSModelManager modelManager, QueryService queryService, ContextState contextState) {
+ super(modelManager, queryService, Test.class, Project.class);
// layers
addJoinConfig(JoinConfig.up(Pool.class, Project.class));
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/search/TestStepSearchQuery.java b/src/main/java/org/eclipse/mdm/api/odsadapter/search/TestStepSearchQuery.java
index aeb91e7..7ffe2c0 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/search/TestStepSearchQuery.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/search/TestStepSearchQuery.java
@@ -8,13 +8,14 @@
package org.eclipse.mdm.api.odsadapter.search;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ChannelGroup;
import org.eclipse.mdm.api.base.model.Measurement;
import org.eclipse.mdm.api.base.model.Test;
import org.eclipse.mdm.api.base.model.TestStep;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.SearchQuery;
+import org.eclipse.mdm.api.base.query.QueryService;
+import org.eclipse.mdm.api.base.search.SearchQuery;
import org.eclipse.mdm.api.dflt.model.Pool;
import org.eclipse.mdm.api.dflt.model.Project;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
@@ -37,8 +38,8 @@
* @param contextState
* The {@link ContextState}.
*/
- TestStepSearchQuery(ODSModelManager modelManager, ContextState contextState) {
- super(modelManager, TestStep.class, Project.class);
+ TestStepSearchQuery(ODSModelManager modelManager, QueryService queryService, ContextState contextState) {
+ super(modelManager, queryService, TestStep.class, Project.class);
// layers
addJoinConfig(JoinConfig.up(Pool.class, Project.class));
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/BaseStatement.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/BaseStatement.java
index 4322cfd..74eb9b8 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/BaseStatement.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/BaseStatement.java
@@ -9,17 +9,15 @@
package org.eclipse.mdm.api.odsadapter.transaction;
import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.util.Collection;
import org.asam.ods.AoException;
import org.asam.ods.ApplElemAccess;
-import org.eclipse.mdm.api.base.model.BaseEntity;
-import org.eclipse.mdm.api.base.model.Core;
+import org.eclipse.mdm.api.base.ServiceNotProvidedException;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
+import org.eclipse.mdm.api.base.query.QueryService;
import org.eclipse.mdm.api.odsadapter.query.ODSEntityType;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
@@ -32,22 +30,6 @@
abstract class BaseStatement {
// ======================================================================
- // Class variables
- // ======================================================================
-
- private static final Method GET_CORE_METHOD;
-
- static {
- try {
- GET_CORE_METHOD = BaseEntity.class.getDeclaredMethod("getCore");
- GET_CORE_METHOD.setAccessible(true);
- } catch (NoSuchMethodException | SecurityException e) {
- throw new IllegalStateException(
- "Unable to load 'getCore()' in class '" + BaseEntity.class.getSimpleName() + "'.", e);
- }
- }
-
- // ======================================================================
// Instance variables
// ======================================================================
@@ -94,22 +76,6 @@
// ======================================================================
/**
- * Returns the {@link Core} of given {@link Entity}.
- *
- * @param entity
- * The {@code Entity} whose {@code Core} will be returned.
- * @return The {@code Core} is returned.
- */
- protected Core extract(Entity entity) {
- try {
- return (Core) GET_CORE_METHOD.invoke(entity);
- } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
- throw new IllegalArgumentException("Entity of type '" + entity.getClass().getSimpleName()
- + "' does not extend '" + BaseEntity.class.getName() + "'", e);
- }
- }
-
- /**
* Returns the {@link ODSTransaction}.
*
* @return The {@code ODSTransaction} is returned.
@@ -128,6 +94,16 @@
}
/**
+ * Returns the {@link QueryService}.
+ *
+ * @return The {@code QueryService} is returned.
+ */
+ protected QueryService getQueryService() {
+ return transaction.getContext().getQueryService()
+ .orElseThrow(() -> new ServiceNotProvidedException(QueryService.class));
+ }
+
+ /**
* Returns the {@link ApplElemAccess}.
*
* @return The {@code ApplElemAccess} is returned.
@@ -135,9 +111,11 @@
* Thrown in case of errors.
*/
protected ApplElemAccess getApplElemAccess() throws AoException {
- return transaction.getModelManager().getApplElemAccess();
+ return transaction.getContext().getODSModelManager().getApplElemAccess();
}
+
+
/**
* Returns the associated {@link EntityType}.
*
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/CatalogManager.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/CatalogManager.java
index 6d688ed..af8b2ee 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/CatalogManager.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/CatalogManager.java
@@ -26,14 +26,16 @@
import org.asam.ods.BaseStructure;
import org.asam.ods.DataType;
import org.asam.ods.RelationRange;
+import org.eclipse.mdm.api.base.ServiceNotProvidedException;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.model.ContextType;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.Unit;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.ComparisonOperator;
import org.eclipse.mdm.api.base.query.Query;
+import org.eclipse.mdm.api.base.query.QueryService;
import org.eclipse.mdm.api.base.query.Result;
import org.eclipse.mdm.api.dflt.model.CatalogAttribute;
import org.eclipse.mdm.api.dflt.model.CatalogComponent;
@@ -536,7 +538,9 @@
EntityType source = entry.getKey();
EntityType target = transaction.getModelManager().getEntityType(source.getName().replace("Cat", "Tpl"));
- Query query = transaction.getModelManager().createQuery().selectID(target).join(source, target);
+ Query query = transaction.getContext().getQueryService()
+ .orElseThrow(() -> new ServiceNotProvidedException(QueryService.class))
+ .createQuery().selectID(target).join(source, target);
List<Result> results = query.fetch(Filter.and()
.add(ComparisonOperator.IN_SET.create(source.getIDAttribute(), collectInstanceIDs(entry.getValue()))));
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/DeleteStatement.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/DeleteStatement.java
index 12ae06e..56f146a 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/DeleteStatement.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/DeleteStatement.java
@@ -22,6 +22,8 @@
import org.asam.ods.AoException;
import org.asam.ods.T_LONGLONG;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ContextRoot;
import org.eclipse.mdm.api.base.model.ContextType;
@@ -33,11 +35,9 @@
import org.eclipse.mdm.api.base.model.TestStep;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.JoinType;
import org.eclipse.mdm.api.base.query.Query;
-import org.eclipse.mdm.api.base.query.Relation;
import org.eclipse.mdm.api.base.query.Result;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;
import org.eclipse.mdm.api.odsadapter.query.ODSEntityType;
@@ -128,7 +128,7 @@
return 0;
}
- Query query = getModelManager().createQuery().selectID(entityType);
+ Query query = getQueryService().createQuery().selectID(entityType);
for (Relation relation : entityType.getChildRelations()) {
if (useAutoDelete && AUTO_DELETABLE.contains(relation.getTarget().getName())) {
continue;
@@ -208,7 +208,7 @@
continue;
}
- Query contextQuery = getModelManager().createQuery();
+ Query contextQuery = getQueryService().createQuery();
contextQuery.selectID(contextRoot, measurement);
contextQuery.join(contextRoot, measurement);
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/InsertStatement.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/InsertStatement.java
index 6bb58ad..798b92b 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/InsertStatement.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/InsertStatement.java
@@ -21,7 +21,10 @@
import org.asam.ods.AoException;
import org.asam.ods.ElemId;
import org.asam.ods.T_LONGLONG;
-import org.eclipse.mdm.api.base.model.Core;
+import org.eclipse.mdm.api.base.adapter.Attribute;
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.Deletable;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.FileLink;
@@ -30,14 +33,12 @@
import org.eclipse.mdm.api.base.model.TestStep;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.query.Aggregation;
-import org.eclipse.mdm.api.base.query.Attribute;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.base.query.Filter;
import org.eclipse.mdm.api.base.query.Query;
import org.eclipse.mdm.api.base.query.Record;
-import org.eclipse.mdm.api.base.query.Relation;
import org.eclipse.mdm.api.base.query.Result;
+import org.eclipse.mdm.api.odsadapter.query.ODSEntityFactory;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;
import org.slf4j.Logger;
@@ -93,7 +94,7 @@
*/
@Override
public void execute(Collection<Entity> entities) throws AoException, DataAccessException, IOException {
- entities.stream().map(this::extract).forEach(this::readEntityCore);
+ entities.stream().map(ODSEntityFactory::extract).forEach(this::readEntityCore);
execute();
}
@@ -264,7 +265,7 @@
EntityType test = getModelManager().getEntityType(Test.class);
Relation parentRelation = testStep.getRelation(test);
- Query query = getModelManager().createQuery().select(parentRelation.getAttribute())
+ Query query = getQueryService().createQuery().select(parentRelation.getAttribute())
.select(testStep.getAttribute(Sortable.ATTR_SORT_INDEX), Aggregation.MAXIMUM)
.group(parentRelation.getAttribute());
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/ODSTransaction.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/ODSTransaction.java
index 989771e..7a56c1f 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/ODSTransaction.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/ODSTransaction.java
@@ -22,10 +22,11 @@
import org.asam.ods.AoException;
import org.eclipse.mdm.api.base.Transaction;
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.massdata.WriteRequest;
import org.eclipse.mdm.api.base.model.Channel;
import org.eclipse.mdm.api.base.model.ContextRoot;
-import org.eclipse.mdm.api.base.model.Core;
import org.eclipse.mdm.api.base.model.Deletable;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.FileLink;
@@ -35,11 +36,11 @@
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.model.ValueType;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
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.TemplateAttribute;
+import org.eclipse.mdm.api.odsadapter.ODSContext;
import org.eclipse.mdm.api.odsadapter.filetransfer.Transfer;
import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;
@@ -54,10 +55,6 @@
*/
public final class ODSTransaction implements Transaction {
- // ======================================================================
- // Class variables
- // ======================================================================
-
// TODO: it should be possible to a attach a progress listener
// -> progress notification updates while uploading files
// -> any other useful informations?!
@@ -65,17 +62,13 @@
private static final Logger LOGGER = LoggerFactory.getLogger(ODSTransaction.class);
- // ======================================================================
- // Instance variables
- // ======================================================================
-
// this one is stored in case of application model modifications
- private final ODSModelManager parentModelManager;
-
+ private final ODSContext parentContext;
+
// this one is used to access the application model and execute queries
// instance is decoupled from its parent
- private final ODSModelManager modelManager;
-
+ private final ODSContext context;
+
// only for logging
private final String id = UUID.randomUUID().toString();
@@ -95,10 +88,6 @@
private CatalogManager catalogManager;
- // ======================================================================
- // Constructors
- // ======================================================================
-
/**
* Constructor.
*
@@ -111,19 +100,15 @@
* @throws AoException
* Thrown if unable to start a co-session.
*/
- public ODSTransaction(ODSModelManager parentModelManager, Entity entity, Transfer transfer) throws AoException {
- this.parentModelManager = parentModelManager;
+ public ODSTransaction(ODSContext parentContext, Entity entity, Transfer transfer) throws AoException {
+ this.parentContext = parentContext;
this.entity = entity;
this.transfer = transfer;
- modelManager = parentModelManager.newSession();
- modelManager.getAoSession().startTransaction();
+ context = parentContext.newContext();
+ context.getAoSession().startTransaction();
LOGGER.debug("Transaction '{}' started.", id);
}
- // ======================================================================
- // Public methods
- // ======================================================================
-
/**
* {@inheritDoc}
*/
@@ -336,7 +321,7 @@
@Override
public void commit() throws DataAccessException {
try {
- modelManager.getAoSession().commitTransaction();
+ context.getAoSession().commitTransaction();
// commit succeed -> apply changes in entity cores
modified.forEach(Core::apply);
@@ -348,7 +333,7 @@
if (catalogManager != null) {
// application model has been modified -> reload
- parentModelManager.reloadApplicationModel();
+ parentContext.getODSModelManager().reloadApplicationModel();
}
LOGGER.debug("Transaction '{}' committed.", id);
@@ -375,7 +360,7 @@
String virtualID = "0";
created.forEach(c -> c.setID(virtualID));
- modelManager.getAoSession().abortTransaction();
+ context.getAoSession().abortTransaction();
LOGGER.debug("Transaction '{}' aborted.", id);
} catch (AoException e) {
@@ -385,10 +370,6 @@
}
}
- // ======================================================================
- // Package methods
- // ======================================================================
-
/**
* Once {@link #abort()} is called instance ID of given {@link Core} will be
* reset to {@code 0} which indicates a virtual {@link Entity}, not yet
@@ -413,14 +394,23 @@
}
/**
+ * Returns the {@link ODSContext}.
+ *
+ * @return The {@code ODSContext} is returned.
+ */
+ ODSContext getContext() {
+ return context;
+ }
+
+ /**
* Returns the {@link ODSModelManager}.
*
* @return The {@code ODSModelManager} is returned.
*/
ODSModelManager getModelManager() {
- return modelManager;
+ return context.getODSModelManager();
}
-
+
/**
* Returns the {@link UploadService}.
*
@@ -430,22 +420,18 @@
*/
UploadService getUploadService() throws DataAccessException {
if (uploadService == null) {
- if (modelManager.getFileServer() == null) {
+ if (context.getFileServer() == null) {
throw new DataAccessException("CORBA file server is not available.");
}
// upload service starts a periodic session refresh task -> lazy
// instantiation
- uploadService = new UploadService(modelManager, entity, transfer);
+ uploadService = new UploadService(context, entity, transfer);
}
return uploadService;
}
- // ======================================================================
- // Private methods
- // ======================================================================
-
/**
* Returns the {@link CatalogManager}.
*
@@ -494,7 +480,7 @@
private <T extends Entity> void executeStatements(Function<EntityType, BaseStatement> statementFactory,
Collection<T> entities) throws AoException, DataAccessException, IOException {
Map<EntityType, List<Entity>> entitiesByType = entities.stream()
- .collect(Collectors.groupingBy(modelManager::getEntityType));
+ .collect(Collectors.groupingBy(context.getODSModelManager()::getEntityType));
for (Entry<EntityType, List<Entity>> entry : entitiesByType.entrySet()) {
statementFactory.apply(entry.getKey()).execute(entry.getValue());
}
@@ -503,17 +489,13 @@
/**
* Closes the co-session of this transaction.
*/
- private void closeSession() {
- try {
- if (catalogManager != null) {
- catalogManager.clear();
- }
-
- modelManager.close();
- LOGGER.debug("Transaction '{}' closed.", id);
- } catch (AoException e) {
- LOGGER.error("Unable to close transaction '" + id + "' due to: " + e.reason, e);
+ private void closeSession() {
+ if (catalogManager != null) {
+ catalogManager.clear();
}
+
+ context.close();
+ LOGGER.debug("Transaction '{}' closed.", id);
}
}
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/UpdateStatement.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/UpdateStatement.java
index d2ecb04..ea597b6 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/UpdateStatement.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/UpdateStatement.java
@@ -21,18 +21,19 @@
import org.asam.ods.AIDNameValueSeqUnitId;
import org.asam.ods.AoException;
import org.asam.ods.T_LONGLONG;
-import org.eclipse.mdm.api.base.model.Core;
-import org.eclipse.mdm.api.base.model.Core.EntityStore;
+import org.eclipse.mdm.api.base.adapter.Attribute;
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.adapter.EntityStore;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.Relation;
import org.eclipse.mdm.api.base.model.Deletable;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.FileLink;
import org.eclipse.mdm.api.base.model.FilesAttachable;
import org.eclipse.mdm.api.base.model.Value;
-import org.eclipse.mdm.api.base.query.Attribute;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.Relation;
import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig;
+import org.eclipse.mdm.api.odsadapter.query.ODSEntityFactory;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
import org.eclipse.mdm.api.odsadapter.utils.ODSUtils;
import org.slf4j.Logger;
@@ -101,7 +102,7 @@
@Override
public void execute(Collection<Entity> entities) throws AoException, DataAccessException, IOException {
for (Entity entity : entities) {
- readEntityCore(extract(entity));
+ readEntityCore(ODSEntityFactory.extract(entity));
}
// TODO tracing progress in this method...
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/UploadService.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/UploadService.java
index bd441ce..ebb9880 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/UploadService.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/UploadService.java
@@ -13,14 +13,14 @@
import java.util.concurrent.TimeUnit;
import org.asam.ods.AoException;
-import org.eclipse.mdm.api.base.FileService.ProgressListener;
+import org.eclipse.mdm.api.base.file.FileService.ProgressListener;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.FileLink;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.dflt.model.TemplateAttribute;
+import org.eclipse.mdm.api.odsadapter.ODSContext;
import org.eclipse.mdm.api.odsadapter.filetransfer.CORBAFileService;
import org.eclipse.mdm.api.odsadapter.filetransfer.Transfer;
-import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
/**
* Manages new or removed externally linked files.
@@ -51,20 +51,20 @@
/**
* Constructor.
*
- * @param modelManager
+ * @param context
* Used for setup.
* @param entity
* Used for security checks.
* @param transfer
* The transfer type.
*/
- UploadService(ODSModelManager modelManager, Entity entity, Transfer transfer) {
- fileService = new CORBAFileService(modelManager, transfer);
+ UploadService(ODSContext context, Entity entity, Transfer transfer) {
+ fileService = new CORBAFileService(context, transfer);
this.entity = entity;
scheduler.scheduleAtFixedRate(() -> {
try {
- modelManager.getAoSession().getName();
+ context.getAoSession().getName();
} catch (AoException e) {
/*
* NOTE: This is done to keep the parent transaction's session
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/WriteRequestHandler.java b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/WriteRequestHandler.java
index ba7810a..e378af6 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/WriteRequestHandler.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/transaction/WriteRequestHandler.java
@@ -17,14 +17,14 @@
import java.util.stream.IntStream;
import org.asam.ods.AoException;
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.adapter.DefaultCore;
+import org.eclipse.mdm.api.base.adapter.EntityType;
import org.eclipse.mdm.api.base.massdata.WriteRequest;
-import org.eclipse.mdm.api.base.model.Core;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.model.ValueType;
import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.DefaultCore;
-import org.eclipse.mdm.api.base.query.EntityType;
import org.eclipse.mdm.api.odsadapter.utils.ODSConverter;
/**
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverter.java b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverter.java
index ed53910..986e6af 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverter.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverter.java
@@ -8,9 +8,12 @@
package org.eclipse.mdm.api.odsadapter.utils;
+import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
+import java.time.temporal.ChronoField;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -29,6 +32,7 @@
import org.asam.ods.T_DCOMPLEX;
import org.asam.ods.T_ExternalReference;
import org.asam.ods.T_LONGLONG;
+import org.eclipse.mdm.api.base.adapter.Attribute;
import org.eclipse.mdm.api.base.model.DoubleComplex;
import org.eclipse.mdm.api.base.model.FileLink;
import org.eclipse.mdm.api.base.model.FloatComplex;
@@ -37,7 +41,6 @@
import org.eclipse.mdm.api.base.model.ScalarType;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.model.ValueType;
-import org.eclipse.mdm.api.base.query.Attribute;
import org.eclipse.mdm.api.base.query.DataAccessException;
import org.eclipse.mdm.api.odsadapter.query.ODSAttribute;
@@ -56,13 +59,17 @@
private static final Map<Integer, DateTimeFormatter> ODS_DATE_FORMATTERS = new HashMap<>();
static {
- ODS_DATE_FORMATTERS.put(4, DateTimeFormatter.ofPattern("yyyy"));
- ODS_DATE_FORMATTERS.put(6, DateTimeFormatter.ofPattern("yyyyMM"));
+ ODS_DATE_FORMATTERS.put(4, new DateTimeFormatterBuilder().appendPattern("yyyy").parseDefaulting(ChronoField.MONTH_OF_YEAR, 1).parseDefaulting(ChronoField.DAY_OF_MONTH, 1).toFormatter());
+ ODS_DATE_FORMATTERS.put(6, new DateTimeFormatterBuilder().appendPattern("yyyyMM").parseDefaulting(ChronoField.DAY_OF_MONTH, 1).toFormatter());
ODS_DATE_FORMATTERS.put(8, DateTimeFormatter.ofPattern("yyyyMMdd"));
ODS_DATE_FORMATTERS.put(10, DateTimeFormatter.ofPattern("yyyyMMddHH"));
ODS_DATE_FORMATTERS.put(12, DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
ODS_DATE_FORMATTERS.put(14, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
- ODS_DATE_FORMATTERS.put(17, DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
+ /*
+ * JDK-8031085: DateTimeFormatter won't parse dates with custom format "yyyyMMddHHmmssSSS"
+ * @see http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8031085
+ */
+ ODS_DATE_FORMATTERS.put(17, new DateTimeFormatterBuilder().appendPattern("yyyyMMddHHmmss").appendValue(ChronoField.MILLI_OF_SECOND, 3).toFormatter());
}
// ======================================================================
@@ -910,7 +917,12 @@
}
try {
- return LocalDateTime.parse(input, formatter);
+ if (input.length() <= 8) {
+ // Java does not accept a bare date as DateTime, so we are using LocalDate instead of LocalDateTime
+ return LocalDate.parse(input, formatter).atStartOfDay();
+ } else {
+ return LocalDateTime.parse(input, formatter);
+ }
} catch (DateTimeParseException e) {
throw new IllegalArgumentException("Invalid ODS date: " + input, e);
}
@@ -1114,7 +1126,8 @@
if (input == null) {
return new T_ExternalReference("", "", "");
}
- return new T_ExternalReference(input.getDescription(), input.getMimeType().toString(), input.getRemotePath());
+ String remotePath=input.isRemote() ? input.getRemotePath() : "";
+ return new T_ExternalReference(input.getDescription(), input.getMimeType().toString(), remotePath);
}
/**
diff --git a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSUtils.java b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSUtils.java
index 1185c66..1f69761 100644
--- a/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSUtils.java
+++ b/src/main/java/org/eclipse/mdm/api/odsadapter/utils/ODSUtils.java
@@ -12,6 +12,7 @@
import org.asam.ods.DataType;
import org.asam.ods.SelOpcode;
import org.asam.ods.SelOperator;
+import org.eclipse.mdm.api.base.adapter.RelationType;
import org.eclipse.mdm.api.base.model.ContextType;
import org.eclipse.mdm.api.base.model.ValueType;
import org.eclipse.mdm.api.base.query.Aggregation;
@@ -19,7 +20,6 @@
import org.eclipse.mdm.api.base.query.JoinType;
import org.eclipse.mdm.api.base.query.ComparisonOperator;
import org.eclipse.mdm.api.base.query.BooleanOperator;
-import org.eclipse.mdm.api.base.query.RelationType;
/**
* Utility class provides bidirectional mappings for ODS types
diff --git a/src/test/java/org/eclipse/mdm/api/odsadapter/JoinTest.java b/src/test/java/org/eclipse/mdm/api/odsadapter/JoinTest.java
index a4694d9..62714a8 100644
--- a/src/test/java/org/eclipse/mdm/api/odsadapter/JoinTest.java
+++ b/src/test/java/org/eclipse/mdm/api/odsadapter/JoinTest.java
@@ -1,357 +1,350 @@
-/*
- * Copyright (c) 2016 Peak Solution GmbH
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.eclipse.mdm.api.odsadapter;
-
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_NAMESERVICE;
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_PASSWORD;
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_SERVICENAME;
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_USER;
-import static org.junit.Assert.assertEquals;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.mdm.api.base.ConnectionException;
-import org.eclipse.mdm.api.base.model.Channel;
-import org.eclipse.mdm.api.base.model.ChannelGroup;
-import org.eclipse.mdm.api.base.model.Measurement;
-import org.eclipse.mdm.api.base.model.Test;
-import org.eclipse.mdm.api.base.model.TestStep;
-import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.Filter;
-import org.eclipse.mdm.api.base.query.ModelManager;
-import org.eclipse.mdm.api.base.query.SearchService;
-import org.eclipse.mdm.api.dflt.EntityManager;
-import org.eclipse.mdm.api.dflt.model.EntityFactory;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * JoinType test
- *
- * @since 1.0.0
- * @author jst, Peak Solution GmbH
- */
-@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 JoinTest {
- private static final Logger LOGGER = LoggerFactory.getLogger(JoinTest.class);
-
- private static final String NAME_SERVICE = "corbaloc::1.2@%s:%s/NameService";
-
- private static final String USER = "sa";
- private static final String PASSWORD = "sa";
-
- private static EntityManager entityManager;
- private static EntityFactory entityFactory;
-
- @BeforeClass
- public static void setUpBeforeClass() throws ConnectionException {
- String nameServiceHost = System.getProperty("host");
- String nameServicePort = System.getProperty("port");
- String serviceName = System.getProperty("service");
-
- if (nameServiceHost == null || nameServiceHost.isEmpty()) {
- throw new IllegalArgumentException("name service host is unknown: define system property 'host'");
- }
-
- nameServicePort = nameServicePort == null || nameServicePort.isEmpty() ? String.valueOf(2809) : nameServicePort;
- if (nameServicePort == null || nameServicePort.isEmpty()) {
- throw new IllegalArgumentException("name service port is unknown: define system property 'port'");
- }
-
- if (serviceName == null || serviceName.isEmpty()) {
- throw new IllegalArgumentException("service name is unknown: define system property 'service'");
- }
-
- Map<String, String> connectionParameters = new HashMap<>();
- connectionParameters.put(PARAM_NAMESERVICE, String.format(NAME_SERVICE, nameServiceHost, nameServicePort));
- connectionParameters.put(PARAM_SERVICENAME, serviceName + ".ASAM-ODS");
- connectionParameters.put(PARAM_USER, USER);
- connectionParameters.put(PARAM_PASSWORD, PASSWORD);
-
- entityManager = new ODSEntityManagerFactory().connect(connectionParameters);
- entityFactory = entityManager.getEntityFactory()
- .orElseThrow(() -> new IllegalStateException("Entity manager factory not available."));
- }
-
- @AfterClass
- public static void tearDownAfterClass() throws ConnectionException {
- if (entityManager != null) {
- entityManager.close();
- }
- }
-
- @org.junit.Test
- public void findTestFromTestStepId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(TestStep.class);
-
- List<Test> list = searchService.fetch(Test.class, Filter.idOnly(et, "37"));
-
- assertEquals(1, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findTestFromMeasurementId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(Measurement.class);
-
- List<Test> list = searchService.fetch(Test.class, Filter.idOnly(et, "65"));
-
- assertEquals(1, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findTestFromChannelGroupId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(ChannelGroup.class);
-
- List<Test> list = searchService.fetch(Test.class, Filter.idOnly(et, "80"));
-
- assertEquals(1, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findTestFromChannelId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(Channel.class);
-
- List<Test> list = searchService.fetch(Test.class, Filter.idOnly(et, "302"));
-
- assertEquals(1, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findTestStepFromTestId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(Test.class);
-
- List<TestStep> list = searchService.fetch(TestStep.class, Filter.idOnly(et, "28"));
-
- assertEquals(1, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findTestStepFromMeasurementId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(Measurement.class);
-
- List<TestStep> list = searchService.fetch(TestStep.class, Filter.idOnly(et, "65"));
-
- assertEquals(1, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findTestStepFromChannelGroupId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(ChannelGroup.class);
-
- List<Test> list = searchService.fetch(Test.class, Filter.idOnly(et, "80"));
-
- assertEquals(1, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findTestStepFromChannelId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(Channel.class);
-
- List<TestStep> list = searchService.fetch(TestStep.class, Filter.idOnly(et, "302"));
-
- assertEquals(1, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findMeasurementFromTestId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(Test.class);
-
- List<Measurement> list = searchService.fetch(Measurement.class, Filter.idOnly(et, "28"));
-
- assertEquals(9, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findMeasurementFromTestStepId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(TestStep.class);
-
- List<Measurement> list = searchService.fetch(Measurement.class, Filter.idOnly(et, "37"));
-
- assertEquals(9, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findMeasurementFromChannelGroupId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(ChannelGroup.class);
-
- List<Measurement> list = searchService.fetch(Measurement.class, Filter.idOnly(et, "80"));
-
- assertEquals(1, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findMeasurementFromChannelId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(Channel.class);
-
- List<Measurement> list = searchService.fetch(Measurement.class, Filter.idOnly(et, "302"));
-
- assertEquals(1, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findChannelGroupFromTestId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(Test.class);
-
- List<ChannelGroup> list = searchService.fetch(ChannelGroup.class, Filter.idOnly(et, "28"));
-
- assertEquals(14, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findChannelGroupFromTestStepId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(TestStep.class);
-
- List<ChannelGroup> list = searchService.fetch(ChannelGroup.class, Filter.idOnly(et, "37"));
-
- assertEquals(14, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findChannelGroupFromMeasurementId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(Measurement.class);
-
- List<ChannelGroup> list = searchService.fetch(ChannelGroup.class, Filter.idOnly(et, "65"));
-
- assertEquals(2, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findChannelGroupFromChannelId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(Channel.class);
-
- List<ChannelGroup> list = searchService.fetch(ChannelGroup.class, Filter.idOnly(et, "302"));
-
- assertEquals(2, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findChannelFromTestId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(Test.class);
-
- List<Channel> list = searchService.fetch(Channel.class, Filter.idOnly(et, "28"));
-
- assertEquals(43, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findChannelFromTestStepId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(TestStep.class);
-
- List<Channel> list = searchService.fetch(Channel.class, Filter.idOnly(et, "37"));
-
- assertEquals(43, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findChannelFromMeasurementId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(Measurement.class);
-
- List<Channel> list = searchService.fetch(Channel.class, Filter.idOnly(et, "65"));
-
- assertEquals(2, list.size());
- System.out.println(list.size());
- }
-
- @org.junit.Test
- public void findChannelFromChannelGroupId() throws DataAccessException {
- ModelManager modelManager = entityManager.getModelManager().get();
- SearchService searchService = entityManager.getSearchService().get();
-
- EntityType et = modelManager.getEntityType(ChannelGroup.class);
-
- List<Channel> list = searchService.fetch(Channel.class, Filter.idOnly(et, "80"));
-
- assertEquals(2, list.size());
- System.out.println(list.size());
- }
-
-}
+/*
+ * Copyright (c) 2016 Peak Solution GmbH
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.eclipse.mdm.api.odsadapter;
+
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_NAMESERVICE;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_PASSWORD;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_SERVICENAME;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_USER;
+import static org.junit.Assert.assertEquals;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.mdm.api.base.ConnectionException;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.ModelManager;
+import org.eclipse.mdm.api.base.model.Channel;
+import org.eclipse.mdm.api.base.model.ChannelGroup;
+import org.eclipse.mdm.api.base.model.Measurement;
+import org.eclipse.mdm.api.base.model.Test;
+import org.eclipse.mdm.api.base.model.TestStep;
+import org.eclipse.mdm.api.base.query.DataAccessException;
+import org.eclipse.mdm.api.base.query.Filter;
+import org.eclipse.mdm.api.base.search.SearchService;
+import org.eclipse.mdm.api.dflt.ApplicationContext;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+
+/**
+ * JoinType test
+ *
+ * @since 1.0.0
+ * @author jst, Peak Solution GmbH
+ */
+@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 JoinTest {
+
+ private static final String NAME_SERVICE = "corbaloc::1.2@%s:%s/NameService";
+
+ private static final String USER = "sa";
+ private static final String PASSWORD = "sa";
+
+ private static ApplicationContext context;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws ConnectionException {
+ String nameServiceHost = System.getProperty("host");
+ String nameServicePort = System.getProperty("port");
+ String serviceName = System.getProperty("service");
+
+ if (nameServiceHost == null || nameServiceHost.isEmpty()) {
+ throw new IllegalArgumentException("name service host is unknown: define system property 'host'");
+ }
+
+ nameServicePort = nameServicePort == null || nameServicePort.isEmpty() ? String.valueOf(2809) : nameServicePort;
+ if (nameServicePort == null || nameServicePort.isEmpty()) {
+ throw new IllegalArgumentException("name service port is unknown: define system property 'port'");
+ }
+
+ if (serviceName == null || serviceName.isEmpty()) {
+ throw new IllegalArgumentException("service name is unknown: define system property 'service'");
+ }
+
+ Map<String, String> connectionParameters = new HashMap<>();
+ connectionParameters.put(PARAM_NAMESERVICE, String.format(NAME_SERVICE, nameServiceHost, nameServicePort));
+ connectionParameters.put(PARAM_SERVICENAME, serviceName + ".ASAM-ODS");
+ connectionParameters.put(PARAM_USER, USER);
+ connectionParameters.put(PARAM_PASSWORD, PASSWORD);
+
+ context = new ODSContextFactory().connect(connectionParameters);
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws ConnectionException {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ @org.junit.Test
+ public void findTestFromTestStepId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(TestStep.class);
+
+ List<Test> list = searchService.fetch(Test.class, Filter.idOnly(et, "37"));
+
+ assertEquals(1, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findTestFromMeasurementId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(Measurement.class);
+
+ List<Test> list = searchService.fetch(Test.class, Filter.idOnly(et, "65"));
+
+ assertEquals(1, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findTestFromChannelGroupId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(ChannelGroup.class);
+
+ List<Test> list = searchService.fetch(Test.class, Filter.idOnly(et, "80"));
+
+ assertEquals(1, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findTestFromChannelId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(Channel.class);
+
+ List<Test> list = searchService.fetch(Test.class, Filter.idOnly(et, "302"));
+
+ assertEquals(1, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findTestStepFromTestId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(Test.class);
+
+ List<TestStep> list = searchService.fetch(TestStep.class, Filter.idOnly(et, "28"));
+
+ assertEquals(1, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findTestStepFromMeasurementId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(Measurement.class);
+
+ List<TestStep> list = searchService.fetch(TestStep.class, Filter.idOnly(et, "65"));
+
+ assertEquals(1, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findTestStepFromChannelGroupId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(ChannelGroup.class);
+
+ List<Test> list = searchService.fetch(Test.class, Filter.idOnly(et, "80"));
+
+ assertEquals(1, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findTestStepFromChannelId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(Channel.class);
+
+ List<TestStep> list = searchService.fetch(TestStep.class, Filter.idOnly(et, "302"));
+
+ assertEquals(1, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findMeasurementFromTestId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(Test.class);
+
+ List<Measurement> list = searchService.fetch(Measurement.class, Filter.idOnly(et, "28"));
+
+ assertEquals(9, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findMeasurementFromTestStepId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(TestStep.class);
+
+ List<Measurement> list = searchService.fetch(Measurement.class, Filter.idOnly(et, "37"));
+
+ assertEquals(9, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findMeasurementFromChannelGroupId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(ChannelGroup.class);
+
+ List<Measurement> list = searchService.fetch(Measurement.class, Filter.idOnly(et, "80"));
+
+ assertEquals(1, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findMeasurementFromChannelId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(Channel.class);
+
+ List<Measurement> list = searchService.fetch(Measurement.class, Filter.idOnly(et, "302"));
+
+ assertEquals(1, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findChannelGroupFromTestId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(Test.class);
+
+ List<ChannelGroup> list = searchService.fetch(ChannelGroup.class, Filter.idOnly(et, "28"));
+
+ assertEquals(14, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findChannelGroupFromTestStepId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(TestStep.class);
+
+ List<ChannelGroup> list = searchService.fetch(ChannelGroup.class, Filter.idOnly(et, "37"));
+
+ assertEquals(14, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findChannelGroupFromMeasurementId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(Measurement.class);
+
+ List<ChannelGroup> list = searchService.fetch(ChannelGroup.class, Filter.idOnly(et, "65"));
+
+ assertEquals(2, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findChannelGroupFromChannelId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(Channel.class);
+
+ List<ChannelGroup> list = searchService.fetch(ChannelGroup.class, Filter.idOnly(et, "302"));
+
+ assertEquals(2, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findChannelFromTestId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(Test.class);
+
+ List<Channel> list = searchService.fetch(Channel.class, Filter.idOnly(et, "28"));
+
+ assertEquals(43, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findChannelFromTestStepId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(TestStep.class);
+
+ List<Channel> list = searchService.fetch(Channel.class, Filter.idOnly(et, "37"));
+
+ assertEquals(43, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findChannelFromMeasurementId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(Measurement.class);
+
+ List<Channel> list = searchService.fetch(Channel.class, Filter.idOnly(et, "65"));
+
+ assertEquals(2, list.size());
+ System.out.println(list.size());
+ }
+
+ @org.junit.Test
+ public void findChannelFromChannelGroupId() throws DataAccessException {
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType et = modelManager.getEntityType(ChannelGroup.class);
+
+ List<Channel> list = searchService.fetch(Channel.class, Filter.idOnly(et, "80"));
+
+ assertEquals(2, list.size());
+ System.out.println(list.size());
+ }
+
+}
diff --git a/src/test/java/org/eclipse/mdm/api/odsadapter/ODSAdapterTest.java b/src/test/java/org/eclipse/mdm/api/odsadapter/ODSAdapterTest.java
index e04002e..9d7790d 100644
--- a/src/test/java/org/eclipse/mdm/api/odsadapter/ODSAdapterTest.java
+++ b/src/test/java/org/eclipse/mdm/api/odsadapter/ODSAdapterTest.java
@@ -1,370 +1,426 @@
-package org.eclipse.mdm.api.odsadapter;
-
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_NAMESERVICE;
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_PASSWORD;
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_SERVICENAME;
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_USER;
-import static org.junit.Assert.fail;
-
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
-import java.util.UUID;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-import org.eclipse.mdm.api.base.ConnectionException;
-import org.eclipse.mdm.api.base.Transaction;
-import org.eclipse.mdm.api.base.massdata.WriteRequest;
-import org.eclipse.mdm.api.base.massdata.WriteRequestBuilder;
-import org.eclipse.mdm.api.base.model.AxisType;
-import org.eclipse.mdm.api.base.model.Channel;
-import org.eclipse.mdm.api.base.model.ChannelGroup;
-import org.eclipse.mdm.api.base.model.ContextRoot;
-import org.eclipse.mdm.api.base.model.ContextType;
-import org.eclipse.mdm.api.base.model.Deletable;
-import org.eclipse.mdm.api.base.model.Entity;
-import org.eclipse.mdm.api.base.model.Measurement;
-import org.eclipse.mdm.api.base.model.PhysicalDimension;
-import org.eclipse.mdm.api.base.model.Quantity;
-import org.eclipse.mdm.api.base.model.ScalarType;
-import org.eclipse.mdm.api.base.model.Test;
-import org.eclipse.mdm.api.base.model.TestStep;
-import org.eclipse.mdm.api.base.model.Unit;
-import org.eclipse.mdm.api.base.model.ValueType;
-import org.eclipse.mdm.api.base.query.DataAccessException;
-import org.eclipse.mdm.api.dflt.EntityManager;
-import org.eclipse.mdm.api.dflt.model.CatalogComponent;
-import org.eclipse.mdm.api.dflt.model.EntityFactory;
-import org.eclipse.mdm.api.dflt.model.Pool;
-import org.eclipse.mdm.api.dflt.model.Project;
-import org.eclipse.mdm.api.dflt.model.TemplateComponent;
-import org.eclipse.mdm.api.dflt.model.TemplateRoot;
-import org.eclipse.mdm.api.dflt.model.TemplateTest;
-import org.eclipse.mdm.api.dflt.model.TemplateTestStep;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@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 ODSAdapterTest {
-
- /*
- * ATTENTION: ==========
- *
- * To run this test make sure the target service is running a MDM default
- * model and any database constraint which enforces a relation of Test to a
- * parent entity is deactivated!
- */
-
- private static final Logger LOGGER = LoggerFactory.getLogger(ODSAdapterTest.class);
-
- private static final String NAME_SERVICE = "corbaloc::1.2@%s:%s/NameService";
-
- private static final String USER = "sa";
- private static final String PASSWORD = "sa";
-
- private static EntityManager entityManager;
- private static EntityFactory entityFactory;
-
- @BeforeClass
- public static void setUpBeforeClass() throws ConnectionException {
- String nameServiceHost = System.getProperty("host");
- String nameServicePort = System.getProperty("port");
- String serviceName = System.getProperty("service");
-
- if (nameServiceHost == null || nameServiceHost.isEmpty()) {
- throw new IllegalArgumentException("name service host is unknown: define system property 'host'");
- }
-
- nameServicePort = nameServicePort == null || nameServicePort.isEmpty() ? String.valueOf(2809) : nameServicePort;
- if (nameServicePort == null || nameServicePort.isEmpty()) {
- throw new IllegalArgumentException("name service port is unknown: define system property 'port'");
- }
-
- if (serviceName == null || serviceName.isEmpty()) {
- throw new IllegalArgumentException("service name is unknown: define system property 'service'");
- }
-
- Map<String, String> connectionParameters = new HashMap<>();
- connectionParameters.put(PARAM_NAMESERVICE, String.format(NAME_SERVICE, nameServiceHost, nameServicePort));
- connectionParameters.put(PARAM_SERVICENAME, serviceName + ".ASAM-ODS");
- connectionParameters.put(PARAM_USER, USER);
- connectionParameters.put(PARAM_PASSWORD, PASSWORD);
-
- entityManager = new ODSEntityManagerFactory().connect(connectionParameters);
- entityFactory = entityManager.getEntityFactory()
- .orElseThrow(() -> new IllegalStateException("Entity manager factory not available."));
- }
-
- @AfterClass
- public static void tearDownAfterClass() throws ConnectionException {
- if (entityManager != null) {
- entityManager.close();
- }
- }
-
- @org.junit.Test
- public void runtTestScript() throws DataAccessException {
- List<CatalogComponent> catalogComponents = createCatalogComponents();
- List<TemplateRoot> templateRoots = createTemplateRoots(catalogComponents);
- List<TemplateTestStep> templateTestSteps = createTemplateTestSteps(templateRoots);
- TemplateTest templateTest = createTemplateTest(templateTestSteps);
- PhysicalDimension physicalDimension = entityFactory.createPhysicalDimension("any_physical_dimension");
- Unit unit = entityFactory.createUnit("any_unit", physicalDimension);
- Quantity quantity = entityFactory.createQuantity("any_quantity", unit);
-
- Transaction transaction = entityManager.startTransaction();
- try {
- create(transaction, "catalog components", catalogComponents);
- create(transaction, "template roots", templateRoots);
- create(transaction, "template test steps", templateTestSteps);
- create(transaction, "template test", Collections.singletonList(templateTest));
- create(transaction, "physical dimension", Collections.singletonList(physicalDimension));
- create(transaction, "unit", Collections.singletonList(unit));
- create(transaction, "quantity", Collections.singletonList(quantity));
-
- transaction.commit();
- } catch (RuntimeException e) {
- transaction.abort();
- fail("Unable to create test data due to: " + e.getMessage());
- }
-
- List<Project> projects = Collections.emptyList();
- try {
- projects = createTestData(templateTest, quantity);
- } catch (DataAccessException | RuntimeException e) {
- e.printStackTrace();
- }
-
- transaction = entityManager.startTransaction();
- try {
- // delete in reverse order!
- if (!projects.isEmpty()) {
- delete(transaction, "projects and their children", projects);
- }
-
- delete(transaction, "quantity", Collections.singletonList(quantity));
- delete(transaction, "unit", Collections.singletonList(unit));
- delete(transaction, "physical dimension", Collections.singletonList(physicalDimension));
- delete(transaction, "template test", Collections.singletonList(templateTest));
- delete(transaction, "template test steps", templateTestSteps);
- delete(transaction, "template roots", templateRoots);
- delete(transaction, "catalog components", catalogComponents);
-
- transaction.commit();
- } catch (RuntimeException e) {
- transaction.abort();
- fail("Unable to delete test data due to: " + e.getMessage());
- }
-
- if (projects.isEmpty()) {
- fail("Was unable to create test data.");
- }
- }
-
- private List<Project> createTestData(TemplateTest templateTest, Quantity quantity) throws DataAccessException {
-
- Project project = entityFactory.createProject("simple_project");
- Pool pool = entityFactory.createPool("simple_pool", project);
-
- List<Test> tests = createTests(2, pool, templateTest);
-
- // create measurement test data
- List<WriteRequest> writeRequests = new ArrayList<>();
- for (Test test : tests) {
- for (TestStep testStep : test.getCommissionedTestSteps()) {
- Optional<TemplateTestStep> templateTestStep = TemplateTestStep.of(testStep);
- ContextRoot[] contextRoots = new ContextRoot[0];
- if (templateTestStep.isPresent()) {
- contextRoots = templateTestStep.get().getTemplateRoots().stream()
- .map(templateRoot -> entityFactory.createContextRoot(templateRoot))
- .toArray(ContextRoot[]::new);
- }
- for (int i = 1; i < 3; i++) {
- Measurement measurement = entityFactory.createMeasurement("measurement_" + i, testStep,
- contextRoots);
-
- // create channels
- List<Channel> channels = new ArrayList<>();
- for (int j = 0; j < 9; j++) {
- channels.add(entityFactory.createChannel("channel_ " + j, measurement, quantity));
- }
-
- // create channel group
- ChannelGroup channelGroup = entityFactory.createChannelGroup("group", 10, measurement);
- writeRequests.addAll(createMeasurementData(measurement, channelGroup, channels));
- }
- }
- }
-
- Transaction transaction = entityManager.startTransaction();
- try {
- create(transaction, "project and pool with tests based on teamplates with measurements and mass data",
- Collections.singleton(project));
-
- transaction.writeMeasuredValues(writeRequests);
- transaction.commit();
- return Collections.singletonList(project);
- } catch (DataAccessException | RuntimeException e) {
- e.printStackTrace();
- transaction.abort();
- }
-
- return Collections.emptyList();
- }
-
- private List<WriteRequest> createMeasurementData(Measurement measurement, ChannelGroup channelGroup,
- List<Channel> channels) {
- // set length of the channel value sequence
- List<WriteRequest> writeRequests = new ArrayList<>();
-
- // populate channel value write requests - one per channel
- Collections.sort(channels, (c1, c2) -> c1.getName().compareTo(c2.getName()));
-
- WriteRequestBuilder wrb = WriteRequest.create(channelGroup, channels.get(0), AxisType.X_AXIS);
- writeRequests.add(wrb.implicitLinear(ScalarType.FLOAT, 0, 1).independent().build());
-
- wrb = WriteRequest.create(channelGroup, channels.get(1), AxisType.Y_AXIS);
- writeRequests.add(wrb.explicit()
- .booleanValues(new boolean[] { true, true, false, true, true, false, true, false, false, false })
- .build());
-
- wrb = WriteRequest.create(channelGroup, channels.get(2), AxisType.Y_AXIS);
- writeRequests.add(wrb.explicit().byteValues(new byte[] { 5, 32, 42, 9, 17, 65, 13, 8, 15, 21 }).build());
-
- wrb = WriteRequest.create(channelGroup, channels.get(3), AxisType.Y_AXIS);
- writeRequests.add(
- wrb.explicit().integerValues(new int[] { 423, 645, 221, 111, 675, 353, 781, 582, 755, 231 }).build());
-
- wrb = WriteRequest.create(channelGroup, channels.get(4), AxisType.Y_AXIS);
- writeRequests.add(wrb.explicit()
- .stringValues(new String[] { "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10" }).build());
-
- LocalDateTime now = LocalDateTime.now();
- wrb = WriteRequest.create(channelGroup, channels.get(5), AxisType.Y_AXIS);
- writeRequests
- .add(wrb.explicit()
- .dateValues(new LocalDateTime[] { now, now.plusDays(1), now.plusDays(2), now.plusDays(3),
- now.plusDays(4), now.plusDays(5), now.plusDays(6), now.plusDays(7), now.plusDays(8),
- now.plusDays(9) })
- .build());
-
- wrb = WriteRequest.create(channelGroup, channels.get(6), AxisType.Y_AXIS);
- writeRequests.add(wrb.explicit().byteStreamValues(new byte[][] { { 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 }, { 9, 10 },
- { 11 }, { 12, 13, 14 }, { 15, 16 }, { 17, 18, 19, 20 }, { 21, 22 }, { 23 } }).build());
-
- wrb = WriteRequest.create(channelGroup, channels.get(7), AxisType.Y_AXIS);
- writeRequests.add(wrb.implicitConstant(ScalarType.SHORT, Short.MAX_VALUE).build());
-
- wrb = WriteRequest.create(channelGroup, channels.get(8), AxisType.Y_AXIS);
- writeRequests.add(wrb.implicitSaw(ScalarType.FLOAT, 0, 1, 4).build());
-
- return writeRequests;
- }
-
- private static void delete(Transaction transaction, String key, Collection<? extends Deletable> entities)
- throws DataAccessException {
- LOGGER.info(">>>>>>>>>>>>>>>>> deleting " + key + "...");
- long start = System.currentTimeMillis();
- transaction.delete(entities);
- LOGGER.info(">>>>>>>>>>>>>>>>> " + key + " deleted in " + (System.currentTimeMillis() - start) + " ms");
- }
-
- private static void create(Transaction transaction, String key, Collection<? extends Entity> entities)
- throws DataAccessException {
- LOGGER.info(">>>>>>>>>>>>>>>>> creating " + key + "...");
- long start = System.currentTimeMillis();
- transaction.create(entities);
- LOGGER.info(">>>>>>>>>>>>>>>>> " + key + " written in " + (System.currentTimeMillis() - start) + " ms");
- }
-
- private List<Test> createTests(int count, Pool pool, TemplateTest templateTest) {
- return IntStream.range(1, ++count)
- .mapToObj(i -> entityFactory.createTest("simple_test_" + i, pool, templateTest))
- .collect(Collectors.toList());
- }
-
- private TemplateTest createTemplateTest(List<TemplateTestStep> templateTestSteps) {
- TemplateTest templateTest = entityFactory.createTemplateTest("tpl_test");
- templateTestSteps.forEach(tts -> {
- entityFactory.createTemplateTestStepUsage(UUID.randomUUID().toString(), templateTest, tts);
- });
- return templateTest;
- }
-
- private List<TemplateTestStep> createTemplateTestSteps(List<TemplateRoot> templateRoots) {
- // make sure each context type is given only once
- templateRoots.stream().collect(Collectors.toMap(TemplateRoot::getContextType, Function.identity()));
-
- List<TemplateTestStep> templateTestSteps = new ArrayList<>();
- TemplateTestStep templateTestStep1 = entityFactory.createTemplateTestStep("tpl_test_step_1");
- templateRoots.forEach(tr -> templateTestStep1.setTemplateRoot(tr));
- templateTestSteps.add(templateTestStep1);
- TemplateTestStep templateTestStep2 = entityFactory.createTemplateTestStep("tpl_test_step_2");
- templateRoots.forEach(tr -> templateTestStep2.setTemplateRoot(tr));
- templateTestSteps.add(templateTestStep2);
-
- return templateTestSteps;
- }
-
- private List<TemplateRoot> createTemplateRoots(List<CatalogComponent> catalogComponents) {
- Map<ContextType, List<CatalogComponent>> groups = catalogComponents.stream()
- .collect(Collectors.groupingBy(CatalogComponent::getContextType));
-
- List<TemplateRoot> templateRoots = new ArrayList<>();
- groups.forEach((contextType, catalogComps) -> {
- TemplateRoot templateRoot = entityFactory.createTemplateRoot(contextType,
- "tpl_" + toLower(contextType.name()) + "_root");
- // create child template components for template root
- catalogComps.forEach(catalogComp -> {
- TemplateComponent templateComponent = entityFactory
- .createTemplateComponent("tpl_" + catalogComp.getName() + "_parent", templateRoot, catalogComp);
- entityFactory.createTemplateComponent("tpl_" + catalogComp.getName() + "_child", templateComponent,
- catalogComp);
- });
-
- templateRoots.add(templateRoot);
- });
-
- return templateRoots;
- }
-
- private List<CatalogComponent> createCatalogComponents() {
- List<CatalogComponent> catalogComponents = new ArrayList<>();
- catalogComponents.add(createCatalogComponent(ContextType.UNITUNDERTEST));
- catalogComponents.add(createCatalogComponent(ContextType.TESTSEQUENCE));
- catalogComponents.add(createCatalogComponent(ContextType.TESTEQUIPMENT));
- return catalogComponents;
- }
-
- private CatalogComponent createCatalogComponent(ContextType contextType) {
- CatalogComponent catalogComponent = entityFactory.createCatalogComponent(contextType,
- toLower(contextType.name()));
-
- entityFactory.createCatalogAttribute("string", ValueType.STRING, catalogComponent);
- entityFactory.createCatalogAttribute("date", ValueType.DATE, catalogComponent);
- entityFactory.createCatalogAttribute("long", ValueType.LONG, catalogComponent);
- entityFactory.createCatalogAttribute("file_link", ValueType.FILE_LINK, catalogComponent);
- entityFactory.createCatalogAttribute("file_link_array", ValueType.FILE_LINK_SEQUENCE, catalogComponent);
- entityFactory.createCatalogAttribute("scalar_type", ScalarType.class, catalogComponent);
-
- return catalogComponent;
- }
-
- private static String toLower(String name) {
- return name.toLowerCase(Locale.ROOT);
- }
-
-}
+package org.eclipse.mdm.api.odsadapter;
+
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_NAMESERVICE;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_PASSWORD;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_SERVICENAME;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_USER;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.eclipse.mdm.api.base.ConnectionException;
+import org.eclipse.mdm.api.base.ServiceNotProvidedException;
+import org.eclipse.mdm.api.base.Transaction;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.ModelManager;
+import org.eclipse.mdm.api.base.massdata.WriteRequest;
+import org.eclipse.mdm.api.base.massdata.WriteRequestBuilder;
+import org.eclipse.mdm.api.base.model.AxisType;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Channel;
+import org.eclipse.mdm.api.base.model.ChannelGroup;
+import org.eclipse.mdm.api.base.model.ContextComponent;
+import org.eclipse.mdm.api.base.model.ContextRoot;
+import org.eclipse.mdm.api.base.model.ContextType;
+import org.eclipse.mdm.api.base.model.Deletable;
+import org.eclipse.mdm.api.base.model.Entity;
+import org.eclipse.mdm.api.base.model.EnumRegistry;
+import org.eclipse.mdm.api.base.model.FileLink;
+import org.eclipse.mdm.api.base.model.Measurement;
+import org.eclipse.mdm.api.base.model.MimeType;
+import org.eclipse.mdm.api.base.model.PhysicalDimension;
+import org.eclipse.mdm.api.base.model.Quantity;
+import org.eclipse.mdm.api.base.model.ScalarType;
+import org.eclipse.mdm.api.base.model.Test;
+import org.eclipse.mdm.api.base.model.TestStep;
+import org.eclipse.mdm.api.base.model.Unit;
+import org.eclipse.mdm.api.base.model.Value;
+import org.eclipse.mdm.api.base.model.ValueType;
+import org.eclipse.mdm.api.base.query.DataAccessException;
+import org.eclipse.mdm.api.base.query.Filter;
+import org.eclipse.mdm.api.base.search.SearchService;
+import org.eclipse.mdm.api.dflt.ApplicationContext;
+import org.eclipse.mdm.api.dflt.EntityManager;
+import org.eclipse.mdm.api.dflt.model.CatalogComponent;
+import org.eclipse.mdm.api.dflt.model.EntityFactory;
+import org.eclipse.mdm.api.dflt.model.Pool;
+import org.eclipse.mdm.api.dflt.model.Project;
+import org.eclipse.mdm.api.dflt.model.TemplateComponent;
+import org.eclipse.mdm.api.dflt.model.TemplateRoot;
+import org.eclipse.mdm.api.dflt.model.TemplateTest;
+import org.eclipse.mdm.api.dflt.model.TemplateTestStep;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@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 ODSAdapterTest {
+
+ /*
+ * ATTENTION: ==========
+ *
+ * To run this test make sure the target service is running a MDM default
+ * model and any database constraint which enforces a relation of Test to a
+ * parent entity is deactivated!
+ */
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ODSAdapterTest.class);
+
+ private static final String NAME_SERVICE = "corbaloc::1.2@%s:%s/NameService";
+
+ private static final String USER = "sa";
+ private static final String PASSWORD = "sa";
+
+ private static ApplicationContext context;
+ private static EntityManager entityManager;
+ private static EntityFactory entityFactory;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws ConnectionException {
+ String nameServiceHost = System.getProperty("host");
+ String nameServicePort = System.getProperty("port");
+ String serviceName = System.getProperty("service");
+
+ if (nameServiceHost == null || nameServiceHost.isEmpty()) {
+ throw new IllegalArgumentException("name service host is unknown: define system property 'host'");
+ }
+
+ nameServicePort = nameServicePort == null || nameServicePort.isEmpty() ? String.valueOf(2809) : nameServicePort;
+ if (nameServicePort == null || nameServicePort.isEmpty()) {
+ throw new IllegalArgumentException("name service port is unknown: define system property 'port'");
+ }
+
+ if (serviceName == null || serviceName.isEmpty()) {
+ throw new IllegalArgumentException("service name is unknown: define system property 'service'");
+ }
+
+ Map<String, String> connectionParameters = new HashMap<>();
+ connectionParameters.put(PARAM_NAMESERVICE, String.format(NAME_SERVICE, nameServiceHost, nameServicePort));
+ connectionParameters.put(PARAM_SERVICENAME, serviceName + ".ASAM-ODS");
+ connectionParameters.put(PARAM_USER, USER);
+ connectionParameters.put(PARAM_PASSWORD, PASSWORD);
+
+ context = new ODSContextFactory().connect(connectionParameters);
+ entityManager = context.getEntityManager()
+ .orElseThrow(() -> new ServiceNotProvidedException(EntityManager.class));
+ entityFactory = context.getEntityFactory()
+ .orElseThrow(() -> new IllegalStateException("Entity manager factory not available."));
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws ConnectionException {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ /* FIXME this test requires that there is a teststep with id 2, that has a unitundertest component called "filetest",
+ * that has an empty filelink attribute "myextref" and a string attrinute "attr1".
+ * remove the comment at org.junit.Test if you fulfill these requirements
+ */
+ //@org.junit.Test
+ public void changeFile() throws Exception {
+ String idteststep = "2";
+ ModelManager modelManager = context.getModelManager().get();
+ SearchService searchService = context.getSearchService().get();
+
+ EntityType etteststep = modelManager.getEntityType(TestStep.class);
+ Transaction transaction;
+
+ transaction = entityManager.startTransaction();
+
+ try {
+ List<TestStep> mealist;
+ mealist = searchService.fetch(TestStep.class, Filter.idOnly(etteststep, idteststep));
+ assertEquals(1, mealist.size());
+ TestStep ts = mealist.get(0);
+ Map<ContextType, ContextRoot> loadContexts = ts.loadContexts(entityManager, ContextType.UNITUNDERTEST);
+ ContextRoot contextRoot = loadContexts.get(ContextType.UNITUNDERTEST);
+ Optional<ContextComponent> contextComponent = contextRoot.getContextComponent("filetest");
+ Value value = contextComponent.get().getValue("myextref");
+ contextComponent.get().getValue("attr1").set("val4711");
+ FileLink fl=FileLink.newRemote("", new MimeType(""), "");
+ FileLink fl2 = (FileLink)value.extract();
+ assertEquals(fl2,fl);
+ List<BaseEntity> toUpdate=new ArrayList<>();
+ toUpdate.add(contextComponent.get());
+ transaction.update(toUpdate);
+ transaction.commit();
+ } catch (RuntimeException e) {
+ transaction.abort();
+ throw e;
+ }
+ }
+
+ @org.junit.Test
+ public void runtTestScript() throws DataAccessException {
+ List<CatalogComponent> catalogComponents = createCatalogComponents();
+ List<TemplateRoot> templateRoots = createTemplateRoots(catalogComponents);
+ List<TemplateTestStep> templateTestSteps = createTemplateTestSteps(templateRoots);
+ TemplateTest templateTest = createTemplateTest(templateTestSteps);
+ PhysicalDimension physicalDimension = entityFactory.createPhysicalDimension("any_physical_dimension");
+ Unit unit = entityFactory.createUnit("any_unit", physicalDimension);
+ Quantity quantity = entityFactory.createQuantity("any_quantity", unit);
+
+ Transaction transaction = entityManager.startTransaction();
+ try {
+ create(transaction, "catalog components", catalogComponents);
+ create(transaction, "template roots", templateRoots);
+ create(transaction, "template test steps", templateTestSteps);
+ create(transaction, "template test", Collections.singletonList(templateTest));
+ create(transaction, "physical dimension", Collections.singletonList(physicalDimension));
+ create(transaction, "unit", Collections.singletonList(unit));
+ create(transaction, "quantity", Collections.singletonList(quantity));
+
+ transaction.commit();
+ } catch (RuntimeException e) {
+ transaction.abort();
+ e.printStackTrace();
+ fail("Unable to create test data due to: " + e.getMessage());
+ }
+
+ List<Project> projects = Collections.emptyList();
+ try {
+ projects = createTestData(templateTest, quantity);
+ } catch (RuntimeException e) {
+ e.printStackTrace();
+ }
+
+ transaction = entityManager.startTransaction();
+ try {
+ // delete in reverse order!
+ if (!projects.isEmpty()) {
+ delete(transaction, "projects and their children", projects);
+ }
+
+ delete(transaction, "quantity", Collections.singletonList(quantity));
+ delete(transaction, "unit", Collections.singletonList(unit));
+ delete(transaction, "physical dimension", Collections.singletonList(physicalDimension));
+ delete(transaction, "template test", Collections.singletonList(templateTest));
+ delete(transaction, "template test steps", templateTestSteps);
+ delete(transaction, "template roots", templateRoots);
+ delete(transaction, "catalog components", catalogComponents);
+
+ transaction.commit();
+ } catch (RuntimeException e) {
+ transaction.abort();
+ fail("Unable to delete test data due to: " + e.getMessage());
+ }
+
+ if (projects.isEmpty()) {
+ fail("Was unable to create test data.");
+ }
+ }
+
+ private List<Project> createTestData(TemplateTest templateTest, Quantity quantity) throws DataAccessException {
+
+ Project project = entityFactory.createProject("simple_project");
+ Pool pool = entityFactory.createPool("simple_pool", project);
+
+ List<Test> tests = createTests(2, pool, templateTest);
+
+ // create measurement test data
+ List<WriteRequest> writeRequests = new ArrayList<>();
+ for (Test test : tests) {
+ for (TestStep testStep : test.getCommissionedTestSteps()) {
+ Optional<TemplateTestStep> templateTestStep = TemplateTestStep.of(testStep);
+ ContextRoot[] contextRoots = new ContextRoot[0];
+ if (templateTestStep.isPresent()) {
+ contextRoots = templateTestStep.get().getTemplateRoots().stream()
+ .map(templateRoot -> entityFactory.createContextRoot(templateRoot))
+ .toArray(ContextRoot[]::new);
+ }
+ for (int i = 1; i < 3; i++) {
+ Measurement measurement = entityFactory.createMeasurement("measurement_" + i, testStep,
+ contextRoots);
+
+ // create channels
+ List<Channel> channels = new ArrayList<>();
+ for (int j = 0; j < 9; j++) {
+ channels.add(entityFactory.createChannel("channel_ " + j, measurement, quantity));
+ }
+
+ // create channel group
+ ChannelGroup channelGroup = entityFactory.createChannelGroup("group", 10, measurement);
+ writeRequests.addAll(createMeasurementData(measurement, channelGroup, channels));
+ }
+ }
+ }
+
+ Transaction transaction = entityManager.startTransaction();
+ try {
+ create(transaction, "project and pool with tests based on teamplates with measurements and mass data",
+ Collections.singleton(project));
+
+ transaction.writeMeasuredValues(writeRequests);
+ transaction.commit();
+ return Collections.singletonList(project);
+ } catch (DataAccessException e) {
+ e.printStackTrace();
+ transaction.abort();
+ }
+
+ return Collections.emptyList();
+ }
+
+ private List<WriteRequest> createMeasurementData(Measurement measurement, ChannelGroup channelGroup,
+ List<Channel> channels) {
+ // set length of the channel value sequence
+ List<WriteRequest> writeRequests = new ArrayList<>();
+
+ // populate channel value write requests - one per channel
+ Collections.sort(channels, (c1, c2) -> c1.getName().compareTo(c2.getName()));
+
+ WriteRequestBuilder wrb = WriteRequest.create(channelGroup, channels.get(0), AxisType.X_AXIS);
+ writeRequests.add(wrb.implicitLinear(ScalarType.FLOAT, 0, 1).independent().build());
+
+ wrb = WriteRequest.create(channelGroup, channels.get(1), AxisType.Y_AXIS);
+ writeRequests.add(wrb.explicit()
+ .booleanValues(new boolean[] { true, true, false, true, true, false, true, false, false, false })
+ .build());
+
+ wrb = WriteRequest.create(channelGroup, channels.get(2), AxisType.Y_AXIS);
+ writeRequests.add(wrb.explicit().byteValues(new byte[] { 5, 32, 42, 9, 17, 65, 13, 8, 15, 21 }).build());
+
+ wrb = WriteRequest.create(channelGroup, channels.get(3), AxisType.Y_AXIS);
+ writeRequests.add(
+ wrb.explicit().integerValues(new int[] { 423, 645, 221, 111, 675, 353, 781, 582, 755, 231 }).build());
+
+ wrb = WriteRequest.create(channelGroup, channels.get(4), AxisType.Y_AXIS);
+ writeRequests.add(wrb.explicit()
+ .stringValues(new String[] { "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10" }).build());
+
+ LocalDateTime now = LocalDateTime.now();
+ wrb = WriteRequest.create(channelGroup, channels.get(5), AxisType.Y_AXIS);
+ writeRequests
+ .add(wrb.explicit()
+ .dateValues(new LocalDateTime[] { now, now.plusDays(1), now.plusDays(2), now.plusDays(3),
+ now.plusDays(4), now.plusDays(5), now.plusDays(6), now.plusDays(7), now.plusDays(8),
+ now.plusDays(9) })
+ .build());
+
+ wrb = WriteRequest.create(channelGroup, channels.get(6), AxisType.Y_AXIS);
+ writeRequests.add(wrb.explicit().byteStreamValues(new byte[][] { { 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 }, { 9, 10 },
+ { 11 }, { 12, 13, 14 }, { 15, 16 }, { 17, 18, 19, 20 }, { 21, 22 }, { 23 } }).build());
+
+ wrb = WriteRequest.create(channelGroup, channels.get(7), AxisType.Y_AXIS);
+ writeRequests.add(wrb.implicitConstant(ScalarType.SHORT, Short.MAX_VALUE).build());
+
+ wrb = WriteRequest.create(channelGroup, channels.get(8), AxisType.Y_AXIS);
+ writeRequests.add(wrb.implicitSaw(ScalarType.FLOAT, 0, 1, 4).build());
+
+ return writeRequests;
+ }
+
+ private static void delete(Transaction transaction, String key, Collection<? extends Deletable> entities)
+ throws DataAccessException {
+ LOGGER.info(">>>>>>>>>>>>>>>>> deleting " + key + "...");
+ long start = System.currentTimeMillis();
+ transaction.delete(entities);
+ LOGGER.info(">>>>>>>>>>>>>>>>> " + key + " deleted in " + (System.currentTimeMillis() - start) + " ms");
+ }
+
+ private static void create(Transaction transaction, String key, Collection<? extends Entity> entities)
+ throws DataAccessException {
+ LOGGER.info(">>>>>>>>>>>>>>>>> creating " + key + "...");
+ long start = System.currentTimeMillis();
+ transaction.create(entities);
+ LOGGER.info(">>>>>>>>>>>>>>>>> " + key + " written in " + (System.currentTimeMillis() - start) + " ms");
+ }
+
+ private List<Test> createTests(int count, Pool pool, TemplateTest templateTest) {
+ return IntStream.range(1, ++count)
+ .mapToObj(i -> entityFactory.createTest("simple_test_" + i, pool, templateTest))
+ .collect(Collectors.toList());
+ }
+
+ private TemplateTest createTemplateTest(List<TemplateTestStep> templateTestSteps) {
+ TemplateTest templateTest = entityFactory.createTemplateTest("tpl_test");
+ templateTestSteps.forEach(tts -> {
+ entityFactory.createTemplateTestStepUsage(UUID.randomUUID().toString(), templateTest, tts);
+ });
+ return templateTest;
+ }
+
+ private List<TemplateTestStep> createTemplateTestSteps(List<TemplateRoot> templateRoots) {
+ // make sure each context type is given only once
+ templateRoots.stream().collect(Collectors.toMap(TemplateRoot::getContextType, Function.identity()));
+
+ List<TemplateTestStep> templateTestSteps = new ArrayList<>();
+ TemplateTestStep templateTestStep1 = entityFactory.createTemplateTestStep("tpl_test_step_1");
+ templateRoots.forEach(tr -> templateTestStep1.setTemplateRoot(tr));
+ templateTestSteps.add(templateTestStep1);
+ TemplateTestStep templateTestStep2 = entityFactory.createTemplateTestStep("tpl_test_step_2");
+ templateRoots.forEach(tr -> templateTestStep2.setTemplateRoot(tr));
+ templateTestSteps.add(templateTestStep2);
+
+ return templateTestSteps;
+ }
+
+ private List<TemplateRoot> createTemplateRoots(List<CatalogComponent> catalogComponents) {
+ Map<ContextType, List<CatalogComponent>> groups = catalogComponents.stream()
+ .collect(Collectors.groupingBy(CatalogComponent::getContextType));
+
+ List<TemplateRoot> templateRoots = new ArrayList<>();
+ groups.forEach((contextType, catalogComps) -> {
+ TemplateRoot templateRoot = entityFactory.createTemplateRoot(contextType,
+ "tpl_" + toLower(contextType.name()) + "_root");
+ // create child template components for template root
+ catalogComps.forEach(catalogComp -> {
+ TemplateComponent templateComponent = entityFactory
+ .createTemplateComponent("tpl_" + catalogComp.getName() + "_parent", templateRoot, catalogComp);
+ entityFactory.createTemplateComponent("tpl_" + catalogComp.getName() + "_child", templateComponent,
+ catalogComp);
+ });
+
+ templateRoots.add(templateRoot);
+ });
+
+ return templateRoots;
+ }
+
+ private List<CatalogComponent> createCatalogComponents() {
+ List<CatalogComponent> catalogComponents = new ArrayList<>();
+ catalogComponents.add(createCatalogComponent(ContextType.UNITUNDERTEST));
+ catalogComponents.add(createCatalogComponent(ContextType.TESTSEQUENCE));
+ catalogComponents.add(createCatalogComponent(ContextType.TESTEQUIPMENT));
+ return catalogComponents;
+ }
+
+ private CatalogComponent createCatalogComponent(ContextType contextType) {
+ CatalogComponent catalogComponent = entityFactory.createCatalogComponent(contextType,
+ toLower(contextType.name()));
+
+ entityFactory.createCatalogAttribute("string", ValueType.STRING, catalogComponent);
+ entityFactory.createCatalogAttribute("date", ValueType.DATE, catalogComponent);
+ entityFactory.createCatalogAttribute("long", ValueType.LONG, catalogComponent);
+ entityFactory.createCatalogAttribute("file_link", ValueType.FILE_LINK, catalogComponent);
+ entityFactory.createCatalogAttribute("file_link_array", ValueType.FILE_LINK_SEQUENCE, catalogComponent);
+ EnumRegistry er = EnumRegistry.getInstance();
+ entityFactory.createCatalogAttribute("scalar_type", er.get(EnumRegistry.SCALAR_TYPE), catalogComponent);
+
+ return catalogComponent;
+ }
+
+ private static String toLower(String name) {
+ return name.toLowerCase(Locale.ROOT);
+ }
+
+}
diff --git a/src/test/java/org/eclipse/mdm/api/odsadapter/RelationTest.java b/src/test/java/org/eclipse/mdm/api/odsadapter/RelationTest.java
new file mode 100755
index 0000000..5098e11
--- /dev/null
+++ b/src/test/java/org/eclipse/mdm/api/odsadapter/RelationTest.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2017 Florian Schmitt and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.eclipse.mdm.api.odsadapter;
+
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_NAMESERVICE;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_PASSWORD;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_SERVICENAME;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_USER;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.mdm.api.base.ConnectionException;
+import org.eclipse.mdm.api.base.ServiceNotProvidedException;
+import org.eclipse.mdm.api.base.Transaction;
+import org.eclipse.mdm.api.base.adapter.EntityStore;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.ModelManager;
+import org.eclipse.mdm.api.base.model.Measurement;
+import org.eclipse.mdm.api.base.model.ParameterSet;
+import org.eclipse.mdm.api.base.query.Filter;
+import org.eclipse.mdm.api.base.query.QueryService;
+import org.eclipse.mdm.api.base.query.Record;
+import org.eclipse.mdm.api.base.query.Result;
+import org.eclipse.mdm.api.base.search.SearchService;
+import org.eclipse.mdm.api.dflt.ApplicationContext;
+import org.eclipse.mdm.api.dflt.EntityManager;
+import org.eclipse.mdm.api.odsadapter.query.ODSEntityFactory;
+import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
+import org.eclipse.mdm.api.odsadapter.search.RelationSearchQuery;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.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 RelationTest {
+
+ /*
+ * ATTENTION: ==========
+ *
+ * To run this test make sure the target service is running a MDM default
+ * model and any database constraint which enforces a relation of Test to a
+ * parent entity is deactivated!
+ */
+
+ private static final String NAME_SERVICE = "corbaloc::1.2@%s:%s/NameService";
+
+ private static final String USER = "sa";
+ private static final String PASSWORD = "sa";
+
+ private static ApplicationContext context;
+ private static EntityManager entityManager;
+ private static ModelManager modelManager;
+ private static QueryService queryService;
+ private static SearchService searchService;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws ConnectionException {
+ String nameServiceHost = System.getProperty("host");
+ String nameServicePort = System.getProperty("port");
+ String serviceName = System.getProperty("service");
+
+ if (nameServiceHost == null || nameServiceHost.isEmpty()) {
+ throw new IllegalArgumentException("name service host is unknown: define system property 'host'");
+ }
+
+ nameServicePort = nameServicePort == null || nameServicePort.isEmpty() ? String.valueOf(2809) : nameServicePort;
+ if (nameServicePort == null || nameServicePort.isEmpty()) {
+ throw new IllegalArgumentException("name service port is unknown: define system property 'port'");
+ }
+
+ if (serviceName == null || serviceName.isEmpty()) {
+ throw new IllegalArgumentException("service name is unknown: define system property 'service'");
+ }
+
+ Map<String, String> connectionParameters = new HashMap<>();
+ connectionParameters.put(PARAM_NAMESERVICE, String.format(NAME_SERVICE, nameServiceHost, nameServicePort));
+ connectionParameters.put(PARAM_SERVICENAME, serviceName + ".ASAM-ODS");
+ connectionParameters.put(PARAM_USER, USER);
+ connectionParameters.put(PARAM_PASSWORD, PASSWORD);
+
+ context = new ODSContextFactory().connect(connectionParameters);
+ entityManager = context.getEntityManager()
+ .orElseThrow(() -> new ServiceNotProvidedException(EntityManager.class));
+ modelManager = context.getModelManager()
+ .orElseThrow(() -> new ServiceNotProvidedException(ModelManager.class));
+ queryService = context.getQueryService()
+ .orElseThrow(() -> new ServiceNotProvidedException(QueryService.class));
+ searchService = context.getSearchService()
+ .orElseThrow(() -> new IllegalStateException("Search service not available."));
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws ConnectionException {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+
+
+ /**
+ * changes a relation between instances. There needs to exist a MeaResult of id 1101 and a ParameterSet of id
+ * 1102 which will be related after running this test.
+ * If these don't exist, please leave the following line commented, or the test will fail.
+ * @throws Exception
+ */
+ @org.junit.Test
+ public void changeRelation() throws Exception {
+ String idmea = "1101";
+ String idparamset = "1002";
+
+ EntityType etmeasurement = modelManager.getEntityType(Measurement.class);
+ EntityType etparamset = modelManager.getEntityType(ParameterSet.class);
+ Transaction transaction;
+
+ transaction = entityManager.startTransaction();
+
+ try {
+ List<Measurement> mealist;
+ // we use the searchService to fetch a measurement. Please note, that we
+ // use the per default defined method to fetch the measurement.
+ // This does not load any related ParameterSets! But
+ // we don't care at this point, because we just want to change
+ // the related ParameterSet to a new one, not look at
+ // the existing relations.
+ mealist = searchService.fetch(Measurement.class, Filter.idOnly(etmeasurement, idmea));
+ assertEquals(1, mealist.size());
+ Measurement mea = mealist.get(0);
+
+ // load the parameter set which we want to relate to our measurment.
+ // again we don't care for any preexisting relations.
+ List<ParameterSet> paramsetlist = new ArrayList<>();
+ ParameterSet paramset = entityManager.load(ParameterSet.class, idparamset);
+ paramsetlist.add(paramset);
+ // Note: we can only set relations in the mutable store (which
+ // doesn't include parent-child-relations)
+ EntityStore store = ODSEntityFactory.getMutableStore(paramset);
+ store.set(mea);
+ assertEquals(store.get(Measurement.class), mea);
+
+ transaction.update(paramsetlist);
+ transaction.commit();
+
+ // reload from database and check if relation is consistent with
+ // expectations
+ // first we need to build our own SearchQuery, because the
+ // predefined ones don't include ParameterSet as stated above.
+ RelationSearchQuery mq = new RelationSearchQuery((ODSModelManager) modelManager,
+ queryService);
+ // the SearchQuery defines how to join measurement and parameterset,
+ // but we also have to declare that we want to fetch the related
+ // measurement
+ List<EntityType> fetchList = new ArrayList<>();
+ fetchList.add(etmeasurement);
+ List<Result> fetch = mq.fetchComplete(fetchList, Filter.idOnly(etparamset, idparamset));
+ assertEquals(fetch.size(), 1);
+
+ // now we can check that the new relation is there as expected
+ Record record = fetch.get(0).getRecord(etmeasurement);
+ assertNotNull(record);
+ assertEquals(record.getID(), idmea);
+
+ } catch (RuntimeException e) {
+ transaction.abort();
+ throw e;
+ }
+
+ }
+ }
diff --git a/src/test/java/org/eclipse/mdm/api/odsadapter/notification/peak/PeakNotificationTest.java b/src/test/java/org/eclipse/mdm/api/odsadapter/notification/peak/PeakNotificationTest.java
index d84ab21..bb33a12 100644
--- a/src/test/java/org/eclipse/mdm/api/odsadapter/notification/peak/PeakNotificationTest.java
+++ b/src/test/java/org/eclipse/mdm/api/odsadapter/notification/peak/PeakNotificationTest.java
@@ -1,9 +1,9 @@
package org.eclipse.mdm.api.odsadapter.notification.peak;
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_NAMESERVICE;
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_PASSWORD;
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_SERVICENAME;
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_USER;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_NAMESERVICE;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_PASSWORD;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_SERVICENAME;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_USER;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.times;
@@ -34,15 +34,14 @@
import org.eclipse.mdm.api.base.notification.NotificationException;
import org.eclipse.mdm.api.base.notification.NotificationFilter;
import org.eclipse.mdm.api.base.notification.NotificationListener;
-import org.eclipse.mdm.api.base.notification.NotificationManager;
+import org.eclipse.mdm.api.base.notification.NotificationService;
import org.eclipse.mdm.api.base.query.DataAccessException;
+import org.eclipse.mdm.api.dflt.ApplicationContext;
import org.eclipse.mdm.api.dflt.EntityManager;
import org.eclipse.mdm.api.dflt.model.EntityFactory;
-import org.eclipse.mdm.api.odsadapter.ODSEntityManager;
-import org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory;
-import org.eclipse.mdm.api.odsadapter.ODSNotificationManagerFactory;
-import org.eclipse.mdm.api.odsadapter.notification.peak.EventProcessor;
-import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
+import org.eclipse.mdm.api.odsadapter.ODSContext;
+import org.eclipse.mdm.api.odsadapter.ODSContextFactory;
+import org.eclipse.mdm.api.odsadapter.notification.ODSNotificationServiceFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
@@ -92,8 +91,9 @@
private static final String NOTIFICATION_USER = "sa";
private static final String NOTIFICATION_PASSWORD = "sa";
+ private static ApplicationContext context;
private static EntityManager entityManager;
- private static NotificationManager notificationManager;
+ private static NotificationService notificationManager;
@BeforeClass
public static void setUpBeforeClass() throws ConnectionException {
@@ -103,24 +103,22 @@
connectionParameters.put(PARAM_USER, USER);
connectionParameters.put(PARAM_PASSWORD, PASSWORD);
- entityManager = new ODSEntityManagerFactory().connect(connectionParameters);
+ context = new ODSContextFactory().connect(connectionParameters);
Map<String, String> notificationParameters = new HashMap<>();
- notificationParameters.put(ODSNotificationManagerFactory.PARAM_SERVER_TYPE,
- ODSNotificationManagerFactory.SERVER_TYPE_PEAK);
- notificationParameters.put(ODSNotificationManagerFactory.PARAM_URL, NOTIFICATION_URL);
- notificationParameters.put(ODSEntityManagerFactory.PARAM_USER, NOTIFICATION_USER);
- notificationParameters.put(ODSEntityManagerFactory.PARAM_PASSWORD, NOTIFICATION_PASSWORD);
- notificationParameters.put(ODSNotificationManagerFactory.PARAM_EVENT_MEDIATYPE, "application/json");
+ notificationParameters.put(ODSNotificationServiceFactory.PARAM_SERVER_TYPE,
+ ODSNotificationServiceFactory.SERVER_TYPE_PEAK);
+ notificationParameters.put(ODSNotificationServiceFactory.PARAM_URL, NOTIFICATION_URL);
+ notificationParameters.put(ODSContextFactory.PARAM_USER, NOTIFICATION_USER);
+ notificationParameters.put(ODSContextFactory.PARAM_PASSWORD, NOTIFICATION_PASSWORD);
- notificationManager = new ODSNotificationManagerFactory().create((ODSEntityManager) entityManager,
- notificationParameters);
+ notificationManager = new ODSNotificationServiceFactory().create(context, notificationParameters);
}
@AfterClass
public static void tearDownAfterClass() throws ConnectionException, NotificationException {
- if (entityManager != null) {
- entityManager.close();
+ if (context != null) {
+ context.close();
}
if (notificationManager != null) {
@@ -219,7 +217,7 @@
assertThat("Parent test not found!", !tests.isEmpty());
- Optional<EntityFactory> entityFactory = entityManager.getEntityFactory();
+ Optional<? extends EntityFactory> entityFactory = context.getEntityFactory();
if (!entityFactory.isPresent()) {
throw new IllegalStateException("Entity factory not present!");
}
@@ -246,7 +244,7 @@
AoSession session = null;
try {
- session = ((ODSModelManager) entityManager.getModelManager().get()).getAoSession().createCoSession();
+ session = ((ODSContext) context).getAoSession().createCoSession();
ApplicationElement aeUUT = session.getApplicationStructure().getElementsByBaseType("AoUnitUnderTest")[0];
@@ -284,7 +282,7 @@
AoSession session = null;
try {
- session = ((ODSModelManager) entityManager.getModelManager().get()).getAoSession().createCoSession();
+ session = ((ODSContext) context).getAoSession().createCoSession();
ApplicationElement aeTyre = session.getApplicationStructure().getElementByName("tyre");
diff --git a/src/test/java/org/eclipse/mdm/api/odsadapter/search/ODSFreeTextSearchTest.java b/src/test/java/org/eclipse/mdm/api/odsadapter/search/ODSFreeTextSearchTest.java
index 05070c5..eb99de7 100644
--- a/src/test/java/org/eclipse/mdm/api/odsadapter/search/ODSFreeTextSearchTest.java
+++ b/src/test/java/org/eclipse/mdm/api/odsadapter/search/ODSFreeTextSearchTest.java
@@ -4,6 +4,7 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyCollection;
+import static org.mockito.Matchers.anyCollectionOf;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -126,7 +127,7 @@
@Test(expected = IllegalStateException.class)
public void illegalLoadRequest_niceExceptionIsThrown() throws DataAccessException, InterruptedException {
loader = mock(EntityLoader.class);
- when(loader.loadAll(any(Key.class), anyCollection())).thenThrow(new DataAccessException(""));
+ when(loader.loadAll(any(), anyCollectionOf(String.class))).thenThrow(new DataAccessException(""));
createExampleIndex("TestStep", "mdm2", "asdf");
ODSFreeTextSearch fts2 = new ODSFreeTextSearch(loader, "mdm2", HOST);
diff --git a/src/test/java/org/eclipse/mdm/api/odsadapter/search/ODSSearchServiceTest.java b/src/test/java/org/eclipse/mdm/api/odsadapter/search/ODSSearchServiceTest.java
index af37982..b1228fa 100644
--- a/src/test/java/org/eclipse/mdm/api/odsadapter/search/ODSSearchServiceTest.java
+++ b/src/test/java/org/eclipse/mdm/api/odsadapter/search/ODSSearchServiceTest.java
@@ -1,160 +1,221 @@
-package org.eclipse.mdm.api.odsadapter.search;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_NAMESERVICE;
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_PASSWORD;
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_SERVICENAME;
-import static org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory.PARAM_USER;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.assertj.core.api.iterable.Extractor;
-import org.assertj.core.groups.Tuple;
-import org.eclipse.mdm.api.base.ConnectionException;
-import org.eclipse.mdm.api.base.model.TestStep;
-import org.eclipse.mdm.api.base.query.EntityType;
-import org.eclipse.mdm.api.base.query.Filter;
-import org.eclipse.mdm.api.base.query.FilterItem;
-import org.eclipse.mdm.api.base.query.ModelManager;
-import org.eclipse.mdm.api.base.query.BracketOperator;
-import org.eclipse.mdm.api.base.query.ComparisonOperator;
-import org.eclipse.mdm.api.base.query.BooleanOperator;
-import org.eclipse.mdm.api.dflt.EntityManager;
-import org.eclipse.mdm.api.odsadapter.ODSEntityManagerFactory;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import com.google.common.collect.ImmutableMap;
-
-@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 ODSSearchServiceTest {
-
- /*
- * ATTENTION: ==========
- *
- * To run this test make sure the target service is running a MDM default
- * model and any database constraint which enforces a relation of Test to a
- * parent entity is deactivated!
- */
-
- private static final String NAME_SERVICE = "corbaloc::1.2@%s:%s/NameService";
-
- private static final String USER = "sa";
- private static final String PASSWORD = "sa";
-
- private static EntityManager entityManager;
- private static ModelManager modelManager;
-
- @BeforeClass
- public static void setUpBeforeClass() throws ConnectionException {
- String nameServiceHost = System.getProperty("host");
- String nameServicePort = System.getProperty("port");
- String serviceName = System.getProperty("service");
-
- if (nameServiceHost == null || nameServiceHost.isEmpty()) {
- throw new IllegalArgumentException("name service host is unknown: define system property 'host'");
- }
-
- nameServicePort = nameServicePort == null || nameServicePort.isEmpty() ? String.valueOf(2809) : nameServicePort;
- if (nameServicePort == null || nameServicePort.isEmpty()) {
- throw new IllegalArgumentException("name service port is unknown: define system property 'port'");
- }
-
- if (serviceName == null || serviceName.isEmpty()) {
- throw new IllegalArgumentException("service name is unknown: define system property 'service'");
- }
-
- Map<String, String> connectionParameters = new HashMap<>();
- connectionParameters.put(PARAM_NAMESERVICE, String.format(NAME_SERVICE, nameServiceHost, nameServicePort));
- connectionParameters.put(PARAM_SERVICENAME, serviceName + ".ASAM-ODS");
- connectionParameters.put(PARAM_USER, USER);
- connectionParameters.put(PARAM_PASSWORD, PASSWORD);
-
- entityManager = new ODSEntityManagerFactory().connect(connectionParameters);
- modelManager = entityManager.getModelManager()
- .orElseThrow(() -> new IllegalStateException("No ModelManager available!"));
- }
-
- @AfterClass
- public static void tearDownAfterClass() throws ConnectionException {
- if (entityManager != null) {
- entityManager.close();
- }
- }
-
- private Extractor<FilterItem, Tuple> filterExtractors = new Extractor<FilterItem, Tuple>() {
-
- @Override
- public Tuple extract(FilterItem f) {
- return tuple(f.isBooleanOperator() ? f.getBooleanOperator() : null,
- f.isCondition() ? f.getCondition().getAttribute().getName() : null,
- f.isCondition() ? f.getCondition().getComparisonOperator() : null,
- f.isCondition() ? f.getCondition().getValue().extract() : null,
- f.isBracketOperator() ?f.getBracketOperator() : null);
- }
- };
-
- @Test
- public void testGetMergedFilter() throws Exception {
-
- ODSSearchService service = Mockito.spy((ODSSearchService) entityManager.getSearchService()
- .orElseThrow(() -> new IllegalStateException("No SearchService available!")));
-
- Mockito.doReturn(ImmutableMap.of(TestStep.class, Arrays.asList("10"))).when(service)
- .fetchIds(Mockito.anyString());
-
- EntityType testStep = modelManager.getEntityType(TestStep.class);
-
- assertThat(service.getMergedFilter(Filter.idOnly(testStep, "11"), "query")).hasSize(7)
- .extracting(filterExtractors).containsExactly(tuple(null, null, null, null, BracketOperator.OPEN),
- tuple(null, "Id", ComparisonOperator.EQUAL, "10"),
- tuple(null, null, null, null, BracketOperator.CLOSE),
- tuple(BooleanOperator.AND, null, null, null, null),
- tuple(null, null, null, null, BracketOperator.OPEN),
- tuple(null, "Id", ComparisonOperator.IN_SET, new String[] { "10" }, null),
- tuple(null, null, null, null, BracketOperator.CLOSE));
- }
-
- @Test
- public void testGetMergedFilterNoAttributeFilter() throws Exception {
- ODSSearchService service = Mockito.spy((ODSSearchService) entityManager.getSearchService().get());
-
- Mockito.doReturn(ImmutableMap.of(TestStep.class, Arrays.asList("10"))).when(service)
- .fetchIds(Mockito.anyString());
-
- assertThat(service.getMergedFilter(Filter.and(), "query")).extracting(filterExtractors)
- .containsExactly(tuple(null, "Id", ComparisonOperator.IN_SET, new String[] { "10" }));
- }
-
- @Test
- public void testGetMergedFilterNoFreetextResult() throws Exception {
- ODSSearchService service = Mockito.spy((ODSSearchService) entityManager.getSearchService().get());
-
- Mockito.doReturn(Collections.emptyMap()).when(service).fetchIds(Mockito.anyString());
-
- EntityType testStep = modelManager.getEntityType(TestStep.class);
-
- assertThat(service.getMergedFilter(Filter.idOnly(testStep, "11"), "")).extracting(filterExtractors)
- .containsExactly(tuple(null, "Id", ComparisonOperator.EQUAL, "11"));
- }
-
- @Test
- public void testGetMergedFilterNoAttributeFilterAndNoFreetextResult() throws Exception {
- ODSSearchService service = Mockito.spy((ODSSearchService) entityManager.getSearchService().get());
-
- Mockito.doReturn(Collections.emptyMap()).when(service).fetchIds(Mockito.anyString());
-
- assertThat(service.getMergedFilter(Filter.and(), null)).isEmpty();
-
- assertThat(service.getMergedFilter(Filter.and(), "")).isEmpty();
- }
-}
+package org.eclipse.mdm.api.odsadapter.search;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_NAMESERVICE;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_PASSWORD;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_SERVICENAME;
+import static org.eclipse.mdm.api.odsadapter.ODSContextFactory.PARAM_USER;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.assertj.core.api.iterable.Extractor;
+import org.assertj.core.groups.Tuple;
+import org.eclipse.mdm.api.base.ConnectionException;
+import org.eclipse.mdm.api.base.ServiceNotProvidedException;
+import org.eclipse.mdm.api.base.Transaction;
+import org.eclipse.mdm.api.base.adapter.Core;
+import org.eclipse.mdm.api.base.adapter.EntityStore;
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.adapter.ModelManager;
+import org.eclipse.mdm.api.base.model.BaseEntity;
+import org.eclipse.mdm.api.base.model.Channel;
+import org.eclipse.mdm.api.base.model.ChannelGroup;
+import org.eclipse.mdm.api.base.model.Measurement;
+import org.eclipse.mdm.api.base.model.ParameterSet;
+import org.eclipse.mdm.api.base.model.Test;
+import org.eclipse.mdm.api.base.model.TestStep;
+import org.eclipse.mdm.api.base.query.BooleanOperator;
+import org.eclipse.mdm.api.base.query.BracketOperator;
+import org.eclipse.mdm.api.base.query.ComparisonOperator;
+import org.eclipse.mdm.api.base.query.Filter;
+import org.eclipse.mdm.api.base.query.FilterItem;
+import org.eclipse.mdm.api.base.query.QueryService;
+import org.eclipse.mdm.api.base.query.Record;
+import org.eclipse.mdm.api.base.query.Result;
+import org.eclipse.mdm.api.base.search.SearchService;
+import org.eclipse.mdm.api.dflt.ApplicationContext;
+import org.eclipse.mdm.api.dflt.EntityManager;
+import org.eclipse.mdm.api.dflt.model.Pool;
+import org.eclipse.mdm.api.dflt.model.Project;
+import org.eclipse.mdm.api.odsadapter.ODSContextFactory;
+import org.eclipse.mdm.api.odsadapter.ODSEntityManager;
+import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
+import org.eclipse.mdm.api.odsadapter.search.JoinTree.JoinConfig;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.mockito.Mockito;
+
+import com.google.common.collect.ImmutableMap;
+
+@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 ODSSearchServiceTest {
+
+ /*
+ * ATTENTION: ==========
+ *
+ * To run this test make sure the target service is running a MDM default
+ * model and any database constraint which enforces a relation of Test to a
+ * parent entity is deactivated!
+ */
+
+ private static final String NAME_SERVICE = "corbaloc::1.2@%s:%s/NameService";
+
+ private static final String USER = "sa";
+ private static final String PASSWORD = "sa";
+
+ private static ApplicationContext context;
+ private static EntityManager entityManager;
+ private static ModelManager modelManager;
+ private static QueryService queryService;
+ private static SearchService searchService;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws ConnectionException {
+ String nameServiceHost = System.getProperty("host");
+ String nameServicePort = System.getProperty("port");
+ String serviceName = System.getProperty("service");
+
+ if (nameServiceHost == null || nameServiceHost.isEmpty()) {
+ throw new IllegalArgumentException("name service host is unknown: define system property 'host'");
+ }
+
+ nameServicePort = nameServicePort == null || nameServicePort.isEmpty() ? String.valueOf(2809) : nameServicePort;
+ if (nameServicePort == null || nameServicePort.isEmpty()) {
+ throw new IllegalArgumentException("name service port is unknown: define system property 'port'");
+ }
+
+ if (serviceName == null || serviceName.isEmpty()) {
+ throw new IllegalArgumentException("service name is unknown: define system property 'service'");
+ }
+
+ Map<String, String> connectionParameters = new HashMap<>();
+ connectionParameters.put(PARAM_NAMESERVICE, String.format(NAME_SERVICE, nameServiceHost, nameServicePort));
+ connectionParameters.put(PARAM_SERVICENAME, serviceName + ".ASAM-ODS");
+ connectionParameters.put(PARAM_USER, USER);
+ connectionParameters.put(PARAM_PASSWORD, PASSWORD);
+
+ context = new ODSContextFactory().connect(connectionParameters);
+ entityManager = context.getEntityManager()
+ .orElseThrow(() -> new ServiceNotProvidedException(EntityManager.class));
+ modelManager = context.getModelManager()
+ .orElseThrow(() -> new ServiceNotProvidedException(ModelManager.class));
+ queryService = context.getQueryService()
+ .orElseThrow(() -> new ServiceNotProvidedException(QueryService.class));
+ searchService = context.getSearchService()
+ .orElseThrow(() -> new IllegalStateException("Search service not available."));
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws ConnectionException {
+ if (context != null) {
+ context.close();
+ }
+ }
+
+ final class MeasurementSearchQuery extends BaseEntitySearchQuery {
+
+ /**
+ * Constructor.
+ *
+ * @param modelManager
+ * Used to load {@link EntityType}s.
+ * @param contextState
+ * The {@link ContextState}.
+ */
+ MeasurementSearchQuery(ODSModelManager modelManager, QueryService queryService, ContextState contextState) {
+ super(modelManager, queryService, ParameterSet.class, Project.class);
+
+ // layers
+ addJoinConfig(JoinConfig.up(Pool.class, Project.class));
+ addJoinConfig(JoinConfig.up(Test.class, Pool.class));
+ addJoinConfig(JoinConfig.up(TestStep.class, Test.class));
+ addJoinConfig(JoinConfig.up(Measurement.class, TestStep.class));
+ addJoinConfig(JoinConfig.up(ParameterSet.class, Measurement.class));
+ addJoinConfig(JoinConfig.down(Measurement.class, Channel.class));
+ addJoinConfig(JoinConfig.down(Measurement.class, ChannelGroup.class));
+
+ // context
+ addJoinConfig(contextState);
+ }
+
+ }
+
+ private Extractor<FilterItem, Tuple> filterExtractors = new Extractor<FilterItem, Tuple>() {
+
+ @Override
+ public Tuple extract(FilterItem f) {
+ return tuple(f.isBooleanOperator() ? f.getBooleanOperator() : null,
+ f.isCondition() ? f.getCondition().getAttribute().getName() : null,
+ f.isCondition() ? f.getCondition().getComparisonOperator() : null,
+ f.isCondition() ? f.getCondition().getValue().extract() : null,
+ f.isBracketOperator() ?f.getBracketOperator() : null);
+ }
+ };
+
+ @org.junit.Test
+ public void testGetMergedFilter() throws Exception {
+
+ ODSSearchService service = Mockito.spy((ODSSearchService) searchService);
+
+ Mockito.doReturn(ImmutableMap.of(TestStep.class, Arrays.asList("10"))).when(service)
+ .fetchIds(Mockito.anyString());
+
+ EntityType testStep = modelManager.getEntityType(TestStep.class);
+
+ assertThat(service.getMergedFilter(Filter.idOnly(testStep, "11"), "query")).hasSize(7)
+ .extracting(filterExtractors).containsExactly(tuple(null, null, null, null, BracketOperator.OPEN),
+ tuple(null, "Id", ComparisonOperator.EQUAL, "10"),
+ tuple(null, null, null, null, BracketOperator.CLOSE),
+ tuple(BooleanOperator.AND, null, null, null, null),
+ tuple(null, null, null, null, BracketOperator.OPEN),
+ tuple(null, "Id", ComparisonOperator.IN_SET, new String[] { "10" }, null),
+ tuple(null, null, null, null, BracketOperator.CLOSE));
+ }
+
+ @org.junit.Test
+ public void testGetMergedFilterNoAttributeFilter() throws Exception {
+ ODSSearchService service = Mockito.spy((ODSSearchService) searchService);
+
+ Mockito.doReturn(ImmutableMap.of(TestStep.class, Arrays.asList("10"))).when(service)
+ .fetchIds(Mockito.anyString());
+
+ assertThat(service.getMergedFilter(Filter.and(), "query")).extracting(filterExtractors)
+ .containsExactly(tuple(null, "Id", ComparisonOperator.IN_SET, new String[] { "10" }));
+ }
+
+ @org.junit.Test
+ public void testGetMergedFilterNoFreetextResult() throws Exception {
+ ODSSearchService service = Mockito.spy((ODSSearchService) searchService);
+
+ Mockito.doReturn(Collections.emptyMap()).when(service).fetchIds(Mockito.anyString());
+
+ EntityType testStep = modelManager.getEntityType(TestStep.class);
+
+ assertThat(service.getMergedFilter(Filter.idOnly(testStep, "11"), "")).extracting(filterExtractors)
+ .containsExactly(tuple(null, "Id", ComparisonOperator.EQUAL, "11"));
+ }
+
+ @org.junit.Test
+ public void testGetMergedFilterNoAttributeFilterAndNoFreetextResult() throws Exception {
+ ODSSearchService service = Mockito.spy((ODSSearchService) searchService);
+
+ Mockito.doReturn(Collections.emptyMap()).when(service).fetchIds(Mockito.anyString());
+
+ assertThat(service.getMergedFilter(Filter.and(), null)).isEmpty();
+
+ assertThat(service.getMergedFilter(Filter.and(), "")).isEmpty();
+ }
+}
diff --git a/src/test/java/org/eclipse/mdm/api/odsadapter/search/RelationSearchQuery.java b/src/test/java/org/eclipse/mdm/api/odsadapter/search/RelationSearchQuery.java
new file mode 100755
index 0000000..4ccb327
--- /dev/null
+++ b/src/test/java/org/eclipse/mdm/api/odsadapter/search/RelationSearchQuery.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017 Florian Schmitt and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.eclipse.mdm.api.odsadapter.search;
+
+import org.eclipse.mdm.api.base.adapter.EntityType;
+import org.eclipse.mdm.api.base.model.Channel;
+import org.eclipse.mdm.api.base.model.ChannelGroup;
+import org.eclipse.mdm.api.base.model.Measurement;
+import org.eclipse.mdm.api.base.model.ParameterSet;
+import org.eclipse.mdm.api.base.model.Test;
+import org.eclipse.mdm.api.base.model.TestStep;
+import org.eclipse.mdm.api.base.query.QueryService;
+import org.eclipse.mdm.api.dflt.model.Pool;
+import org.eclipse.mdm.api.dflt.model.Project;
+import org.eclipse.mdm.api.odsadapter.query.ODSModelManager;
+import org.eclipse.mdm.api.odsadapter.search.JoinTree.JoinConfig;
+
+/**
+ * This class is used as a helper to the tests in org.eclipse.mdm.api.odsadapter.RelationTest
+ * It needs to be here, because BaseEntitySearchQuery is declared as protected
+ * in the org.eclipse.mdm.api.odsadapter.search package.
+ * It makes some sense to leave it protected in that way, because implementing a BaseEntitySearchQuery
+ * requires understanding of the underlying data model which
+ * The RelationTest requires that the related parametersets to a measurement are
+ * loaded. This class provides a JoinConfig which allows this to happen by defining
+ * the way the entities in question have to be joined.
+ * If we wouldn't join the ParameterSet in, the related
+ * entities would not be loaded, and it would be impossible to determine whether there
+ * are any related ParameterSets or not.
+ *
+ */
+public final class RelationSearchQuery extends BaseEntitySearchQuery {
+
+ /**
+ * Constructor.
+ *
+ * @param modelManager
+ * Used to load {@link EntityType}s.
+ * @param contextState
+ * The {@link ContextState}.
+ */
+ public RelationSearchQuery(ODSModelManager modelManager, QueryService queryService) {
+ super(modelManager, queryService, ParameterSet.class, Project.class);
+
+ // layers
+ addJoinConfig(JoinConfig.up(Pool.class, Project.class));
+ addJoinConfig(JoinConfig.up(Test.class, Pool.class));
+ addJoinConfig(JoinConfig.up(TestStep.class, Test.class));
+ addJoinConfig(JoinConfig.up(Measurement.class, TestStep.class));
+ addJoinConfig(JoinConfig.up(ParameterSet.class, Measurement.class));
+ addJoinConfig(JoinConfig.down(Measurement.class, Channel.class));
+ addJoinConfig(JoinConfig.down(Measurement.class, ChannelGroup.class));
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverterTest.java b/src/test/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverterTest.java
new file mode 100644
index 0000000..2478683
--- /dev/null
+++ b/src/test/java/org/eclipse/mdm/api/odsadapter/utils/ODSConverterTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2017 Peak Solution GmbH
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.eclipse.mdm.api.odsadapter.utils;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import java.time.LocalDateTime;
+
+import org.asam.ods.TS_UnionSeq;
+import org.asam.ods.TS_ValueSeq;
+import org.eclipse.mdm.api.odsadapter.query.ODSAttribute;
+import org.junit.Test;
+
+public class ODSConverterTest {
+
+ @Test
+ public void testFromODSValueSeqODSDateYear() throws Exception {
+ ODSAttribute attr = mock(ODSAttribute.class);
+
+ ODSConverter.fromODSValueSeq(attr, "", getTS_ValueSeqFromDates("2017"));
+
+ verify(attr).createValue(eq(""), eq(true), eq(LocalDateTime.of(2017, 1, 1, 0, 0)));
+ }
+
+ @Test
+ public void testFromODSValueSeqODSDateMonth() throws Exception {
+ ODSAttribute attr = mock(ODSAttribute.class);
+
+ ODSConverter.fromODSValueSeq(attr, "", getTS_ValueSeqFromDates("201710"));
+
+ verify(attr).createValue(eq(""), eq(true), eq(LocalDateTime.of(2017, 10, 1, 0, 0)));
+ }
+
+ @Test
+ public void testFromODSValueSeqODSDate() throws Exception {
+ ODSAttribute attr = mock(ODSAttribute.class);
+
+ ODSConverter.fromODSValueSeq(attr, "", getTS_ValueSeqFromDates("20171004"));
+
+ verify(attr).createValue(eq(""), eq(true), eq(LocalDateTime.of(2017, 10, 4, 0, 0)));
+ }
+
+ @Test
+ public void testFromODSValueSeqODSDateHour() throws Exception {
+ ODSAttribute attr = mock(ODSAttribute.class);
+
+ ODSConverter.fromODSValueSeq(attr, "", getTS_ValueSeqFromDates("2017100412"));
+
+ verify(attr).createValue(eq(""), eq(true), eq(LocalDateTime.of(2017, 10, 4, 12, 0)));
+ }
+
+ @Test
+ public void testFromODSValueSeqODSDateMinute() throws Exception {
+ ODSAttribute attr = mock(ODSAttribute.class);
+
+ ODSConverter.fromODSValueSeq(attr, "", getTS_ValueSeqFromDates("201710041213"));
+
+ verify(attr).createValue(eq(""), eq(true), eq(LocalDateTime.of(2017, 10, 4, 12, 13)));
+ }
+
+ @Test
+ public void testFromODSValueSeqODSDateSecond() throws Exception {
+ ODSAttribute attr = mock(ODSAttribute.class);
+
+ ODSConverter.fromODSValueSeq(attr, "", getTS_ValueSeqFromDates("20171004121314"));
+
+ verify(attr).createValue(eq(""), eq(true), eq(LocalDateTime.of(2017, 10, 4, 12, 13, 14, 0)));
+ }
+
+ @Test
+ public void testFromODSValueSeqODSDateMillisecond() throws Exception {
+ ODSAttribute attr = mock(ODSAttribute.class);
+
+ ODSConverter.fromODSValueSeq(attr, "", getTS_ValueSeqFromDates("20171004121314123"));
+
+ verify(attr).createValue(eq(""), eq(true), eq(LocalDateTime.of(2017, 10, 4, 12, 13, 14, 123_000_000)));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testFromODSValueSeqInvalidLength() throws Exception {
+ ODSAttribute attr = mock(ODSAttribute.class);
+
+ ODSConverter.fromODSValueSeq(attr, "", getTS_ValueSeqFromDates("201710041"));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testFromODSValueSeqInvalidMonth() throws Exception {
+ ODSAttribute attr = mock(ODSAttribute.class);
+
+ ODSConverter.fromODSValueSeq(attr, "", getTS_ValueSeqFromDates("20171304"));
+ }
+
+ private TS_ValueSeq getTS_ValueSeqFromDates(String... dates) {
+ TS_UnionSeq u = new TS_UnionSeq();
+ u.dateVal(dates);
+ return new TS_ValueSeq(u, new short[] { 15 });
+ }
+}