diff options
Diffstat (limited to 'models-dao')
16 files changed, 1784 insertions, 0 deletions
diff --git a/models-dao/pom.xml b/models-dao/pom.xml index 90b98015d..d71fce868 100644 --- a/models-dao/pom.xml +++ b/models-dao/pom.xml @@ -30,4 +30,19 @@ <artifactId>policy-models-dao</artifactId> <name>${project.artifactId}</name> <description>[${project.parent.artifactId}] module provides common DAO (Data Access Object) model handling for the ONAP Policy Framework</description> + + <dependencies> + <dependency> + <groupId>org.onap.policy.models</groupId> + <artifactId>policy-models-base</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <scope>test</scope> + </dependency> + + </dependencies> </project> diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/DaoParameters.java b/models-dao/src/main/java/org/onap/policy/models/dao/DaoParameters.java new file mode 100644 index 000000000..18ae74ae1 --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/DaoParameters.java @@ -0,0 +1,126 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.dao; + +import java.util.Properties; + +/** + * This class is a POJO that holds properties for PF DAOs. + */ +public class DaoParameters { + /** The default PF DAO plugin class. */ + public static final String DEFAULT_PLUGIN_CLASS = "org.onap.policy.models.dao.impl.DefaultPfDao"; + + private String pluginClass = DEFAULT_PLUGIN_CLASS; + private String persistenceUnit; + + private Properties jdbcProperties = new Properties(); + + /** + * Gets the DAO plugin class, this is the DAO class to use and it must implement the + * {@link PfDao} interface. + * + * @return the DAO plugin class + */ + public String getPluginClass() { + return pluginClass; + } + + /** + * Sets the DAO plugin class, a class that implements the {@link PfDao} interface. + * + * @param daoPluginClass the DAO plugin class + */ + public void setPluginClass(final String daoPluginClass) { + pluginClass = daoPluginClass; + } + + /** + * Gets the persistence unit for the DAO. The persistence unit defines the JDBC properties the + * DAO will use. The persistence unit must defined in the {@code META-INF/persistence.xml} + * resource file + * + * @return the persistence unit to use for JDBC access + */ + public String getPersistenceUnit() { + return persistenceUnit; + } + + /** + * Sets the persistence unit for the DAO. The persistence unit defines the JDBC properties the + * DAO will use. The persistence unit must defined in the {@code META-INF/persistence.xml} + * resource file + * + * @param daoPersistenceUnit the persistence unit to use for JDBC access + */ + public void setPersistenceUnit(final String daoPersistenceUnit) { + persistenceUnit = daoPersistenceUnit; + } + + /** + * Gets the JDBC properties. + * + * @return the JDBC properties + */ + public Properties getJdbcProperties() { + return jdbcProperties; + } + + /** + * Sets the JDBC properties. + * + * @param jdbcProperties the JDBC properties + */ + public void setJdbcProperties(final Properties jdbcProperties) { + this.jdbcProperties = jdbcProperties; + } + + /** + * Gets a single JDBC property. + * + * @param key the key of the property + * @return the JDBC property + */ + public String getJdbcProperty(final String key) { + return jdbcProperties.getProperty(key); + } + + /** + * Sets a single JDBC property. + * + * @param key the key of the property + * @param value the value of the JDBC property + */ + public void setJdbcProperty(final String key, final String value) { + jdbcProperties.setProperty(key, value); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "DAOParameters [pluginClass=" + pluginClass + ", persistenceUnit=" + persistenceUnit + + ", jdbcProperties=" + jdbcProperties + "]"; + } +} diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/PfDao.java b/models-dao/src/main/java/org/onap/policy/models/dao/PfDao.java new file mode 100644 index 000000000..85c971ce7 --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/PfDao.java @@ -0,0 +1,205 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.dao; + +import java.util.Collection; +import java.util.List; + +import org.onap.policy.models.base.PfConcept; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.base.PfReferenceKey; + +/** + * The Interface PfDao describes the DAO interface for reading and writing Policy Framework + * {@link PfConcept} concepts to and from databases using JDBC. + */ +public interface PfDao { + + /** + * Initialize the Policy Framework DAO with the given parameters. + * + * @param daoParameters parameters to use to access the database + * @throws PfModelException on initialization errors + */ + void init(DaoParameters daoParameters) throws PfModelException; + + /** + * Close the Policy Framework DAO. + */ + void close(); + + /** + * Creates an Policy Framework concept on the database. + * + * @param <T> the type of the object to create, a subclass of {@link PfConcept} + * @param obj the object to create + */ + <T extends PfConcept> void create(T obj); + + /** + * Delete an Policy Framework concept on the database. + * + * @param <T> the type of the object to delete, a subclass of {@link PfConcept} + * @param obj the object to delete + */ + <T extends PfConcept> void delete(T obj); + + /** + * Delete an Policy Framework concept on the database. + * + * @param <T> the type of the object to delete, a subclass of {@link PfConcept} + * @param someClass the class of the object to delete, a subclass of {@link PfConcept} + * @param key the key of the object to delete + */ + <T extends PfConcept> void delete(Class<T> someClass, PfConceptKey key); + + /** + * Delete an Policy Framework concept on the database. + * + * @param <T> the type of the object to delete, a subclass of {@link PfConcept} + * @param someClass the class of the object to delete, a subclass of {@link PfConcept} + * @param key the key of the object to delete + */ + <T extends PfConcept> void delete(Class<T> someClass, PfReferenceKey key); + + /** + * Create a collection of objects in the database. + * + * @param <T> the type of the object to create, a subclass of {@link PfConcept} + * @param objs the objects to create + */ + <T extends PfConcept> void createCollection(Collection<T> objs); + + /** + * Delete a collection of objects in the database. + * + * @param <T> the type of the objects to delete, a subclass of {@link PfConcept} + * @param objs the objects to delete + */ + <T extends PfConcept> void deleteCollection(Collection<T> objs); + + /** + * Delete a collection of objects in the database referred to by concept key. + * + * @param <T> the type of the objects to delete, a subclass of {@link PfConcept} + * @param someClass the class of the objects to delete, a subclass of {@link PfConcept} + * @param keys the keys of the objects to delete + * @return the number of objects deleted + */ + <T extends PfConcept> int deleteByConceptKey(Class<T> someClass, Collection<PfConceptKey> keys); + + /** + * Delete a collection of objects in the database referred to by reference key. + * + * @param <T> the type of the objects to delete, a subclass of {@link PfConcept} + * @param someClass the class of the objects to delete, a subclass of {@link PfConcept} + * @param keys the keys of the objects to delete + * @return the number of objects deleted + */ + <T extends PfConcept> int deleteByReferenceKey(Class<T> someClass, Collection<PfReferenceKey> keys); + + /** + * Delete all objects of a given class in the database. + * + * @param <T> the type of the objects to delete, a subclass of {@link PfConcept} + * @param someClass the class of the objects to delete, a subclass of {@link PfConcept} + */ + <T extends PfConcept> void deleteAll(Class<T> someClass); + + /** + * Get an object from the database, referred to by concept key. + * + * @param <T> the type of the object to get, a subclass of {@link PfConcept} + * @param someClass the class of the object to get, a subclass of {@link PfConcept} + * @param key the key of the object to get + * @return the object that was retrieved from the database + */ + <T extends PfConcept> T get(Class<T> someClass, PfConceptKey key); + + /** + * Get an object from the database, referred to by reference key. + * + * @param <T> the type of the object to get, a subclass of {@link PfConcept} + * @param someClass the class of the object to get, a subclass of {@link PfConcept} + * @param key the key of the object to get + * @return the object that was retrieved from the database or null if the object was not + * retrieved + */ + <T extends PfConcept> T get(Class<T> someClass, PfReferenceKey key); + + /** + * Get all the objects in the database of a given type. + * + * @param <T> the type of the objects to get, a subclass of {@link PfConcept} + * @param someClass the class of the objects to get, a subclass of {@link PfConcept} + * @return the objects or null if no objects were retrieved + */ + <T extends PfConcept> List<T> getAll(Class<T> someClass); + + /** + * Get all the objects in the database of the given type with the given parent concept key. + * + * @param <T> the type of the objects to get, a subclass of {@link PfConcept} + * @param someClass the class of the objects to get, a subclass of {@link PfConcept} + * @param parentKey the parent key of the concepts to get + * @return the all + */ + <T extends PfConcept> List<T> getAll(Class<T> someClass, PfConceptKey parentKey); + + /** + * Get a concept from the database with the given concept key. + * + * @param <T> the type of the object to get, a subclass of {@link PfConcept} + * @param someClass the class of the object to get, a subclass of {@link PfConcept} + * @param conceptId the concept key of the concept to get + * @return the concept that matches the key or null if the concept is not retrieved + */ + <T extends PfConcept> T getConcept(Class<T> someClass, PfConceptKey conceptId); + + /** + * Get a concept from the database with the given reference key. + * + * @param <T> the type of the object to get, a subclass of {@link PfConcept} + * @param someClass the class of the object to get, a subclass of {@link PfConcept} + * @param conceptId the concept key of the concept to get + * @return the concept that matches the key or null if the concept is not retrieved + */ + <T extends PfConcept> T getConcept(Class<T> someClass, PfReferenceKey conceptId); + + /** + * Get the number of instances of a concept that exist in the database. + * + * @param <T> the type of the object to get, a subclass of {@link PfConcept} + * @param someClass the class of the object to get, a subclass of {@link PfConcept} + * @return the number of instances of the concept in the database + */ + <T extends PfConcept> long size(Class<T> someClass); + + /** + * Update a concept in the database. + * + * @param <T> the type of the object to get, a subclass of {@link PfConcept} + * @param obj the object to update + * @return the updated object + */ + <T extends PfConcept> T update(T obj); +} diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/PfDaoFactory.java b/models-dao/src/main/java/org/onap/policy/models/dao/PfDaoFactory.java new file mode 100644 index 000000000..3b7e31eb8 --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/PfDaoFactory.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.dao; + +import org.onap.policy.common.utils.validation.Assertions; +import org.onap.policy.models.base.PfModelException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This factory class returns a Policy Framework DAO for the configured persistence mechanism. The + * factory uses the plugin class specified in {@link DaoParameters} to instantiate a DAO instance. + */ +public class PfDaoFactory { + // Get a reference to the logger + private static final Logger LOGGER = LoggerFactory.getLogger(PfDaoFactory.class); + + /** + * Return a Policy Framework DAO for the required Policy Framework DAO plugin class. + * + * @param daoParameters parameters to use to read the database configuration information + * @return the Policy Framework DAO + * @throws PfModelException on invalid JPA plugins + */ + public PfDao createPfDao(final DaoParameters daoParameters) throws PfModelException { + Assertions.argumentOfClassNotNull(daoParameters, PfModelException.class, + "Parameter \"daoParameters\" may not be null"); + + // Get the class for the DAO using reflection + Object pfDaoObject = null; + try { + pfDaoObject = Class.forName(daoParameters.getPluginClass()).newInstance(); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { + String errorMessage = + "Policy Framework DAO class not found for DAO plugin \"" + daoParameters.getPluginClass() + "\""; + LOGGER.error(errorMessage, e); + throw new PfModelException(errorMessage, e); + } + + // Check the class is a Policy Framework DAO + if (!(pfDaoObject instanceof PfDao)) { + String errorMessage = "Specified DAO plugin class \"" + daoParameters.getPluginClass() + + "\" does not implement the PfDao interface"; + LOGGER.error(errorMessage); + throw new PfModelException(errorMessage); + } + + return (PfDao) pfDaoObject; + } +} diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/converters/CDataConditioner.java b/models-dao/src/main/java/org/onap/policy/models/dao/converters/CDataConditioner.java new file mode 100644 index 000000000..327f65ece --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/converters/CDataConditioner.java @@ -0,0 +1,69 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.dao.converters; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; +import javax.xml.bind.annotation.adapters.XmlAdapter; + +/** + * The Class CDATAConditioner converts a CDATA String to and from database format by removing spaces + * at the ends of lines and platform-specific new line endings. + */ +@Converter +public class CDataConditioner extends XmlAdapter<String, String> implements AttributeConverter<String, String> { + + private static final String NL = "\n"; + + @Override + public String convertToDatabaseColumn(final String raw) { + return clean(raw); + } + + @Override + public String convertToEntityAttribute(final String db) { + return clean(db); + } + + @Override + public String unmarshal(final String value) throws Exception { + return this.convertToEntityAttribute(value); + } + + @Override + public String marshal(final String value) throws Exception { + return this.convertToDatabaseColumn(value); + } + + /** + * Clean. + * + * @param in the in + * @return the string + */ + public static final String clean(final String in) { + if (in == null) { + return null; + } else { + return in.replaceAll("\\s+$", "").replaceAll("\\r?\\n", NL); + } + } +} diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/converters/Uuid2String.java b/models-dao/src/main/java/org/onap/policy/models/dao/converters/Uuid2String.java new file mode 100644 index 000000000..a2b1c085a --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/converters/Uuid2String.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.dao.converters; + +import java.util.UUID; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; +import javax.xml.bind.annotation.adapters.XmlAdapter; + +/** + * The Class UUIDConverter converts a UUID to and from database format. + */ +@Converter +public class Uuid2String extends XmlAdapter<String, UUID> implements AttributeConverter<UUID, String> { + + @Override + public String convertToDatabaseColumn(final UUID uuid) { + String returnString; + if (uuid == null) { + returnString = ""; + } else { + returnString = uuid.toString(); + } + return returnString; + } + + @Override + public UUID convertToEntityAttribute(final String uuidString) { + return UUID.fromString(uuidString); + } + + @Override + public UUID unmarshal(final String value) throws Exception { + return this.convertToEntityAttribute(value); + } + + @Override + public String marshal(final UUID value) throws Exception { + return this.convertToDatabaseColumn(value); + } +} diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/converters/package-info.java b/models-dao/src/main/java/org/onap/policy/models/dao/converters/package-info.java new file mode 100644 index 000000000..416eff20c --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/converters/package-info.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Contains converters used by PF EclipseLink marshaling and unmarshaling of + * {@link org.onap.policy.models.base.PfConcept} instances to and from files and databases. + */ + +package org.onap.policy.models.dao.converters; diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/impl/DefaultPfDao.java b/models-dao/src/main/java/org/onap/policy/models/dao/impl/DefaultPfDao.java new file mode 100644 index 000000000..429632db0 --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/impl/DefaultPfDao.java @@ -0,0 +1,415 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.dao.impl; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.onap.policy.models.base.PfConcept; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.base.PfReferenceKey; +import org.onap.policy.models.dao.DaoParameters; +import org.onap.policy.models.dao.PfDao; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class DefaultPfDao is an JPA implementation of the {@link PfDao} class for Policy Framework + * concepts ({@link PfConcept}). It uses the default JPA implementation in the javax + * {@link Persistence} class. + */ +public class DefaultPfDao implements PfDao { + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultPfDao.class); + + private static final String SELECT_C_FROM = "SELECT c FROM "; + private static final String AND_C_KEY_LOCAL_NAME = "' AND c.key.localName='"; + private static final String AND_C_KEY_PARENT_KEY_VERSION = "' AND c.key.parentKeyVersion='"; + private static final String C_WHERE_C_KEY_PARENT_KEY_NAME = " c WHERE c.key.parentKeyName='"; + private static final String AND_C_KEY_VERSION = "' AND c.key.version='"; + private static final String C_WHERE_C_KEY_NAME = " c WHERE c.key.name='"; + private static final String DELETE_FROM = "DELETE FROM "; + + // Entity manager for JPA + private EntityManagerFactory emf = null; + + @Override + public void init(final DaoParameters daoParameters) throws PfModelException { + if (daoParameters == null || daoParameters.getPersistenceUnit() == null) { + LOGGER.error("Policy Framework persistence unit parameter not set"); + throw new PfModelException("Policy Framework persistence unit parameter not set"); + } + + LOGGER.debug("Creating Policy Framework persistence unit \"{}\" . . .", daoParameters.getPersistenceUnit()); + try { + emf = Persistence.createEntityManagerFactory(daoParameters.getPersistenceUnit(), + daoParameters.getJdbcProperties()); + } catch (final Exception ex) { + String errorMessage = "Creation of Policy Framework persistence unit \"" + + daoParameters.getPersistenceUnit() + "\" failed"; + LOGGER.warn(errorMessage, ex); + throw new PfModelException(errorMessage, ex); + } + LOGGER.debug("Created Policy Framework persistence unit \"{}\"", daoParameters.getPersistenceUnit()); + } + + /** + * Gets the entity manager for this DAO. + * + * @return the entity manager + */ + protected final synchronized EntityManager getEntityManager() { + if (emf == null) { + LOGGER.warn("Policy Framework DAO has not been initialized"); + throw new PfModelRuntimeException("Policy Framework DAO has not been initialized"); + } + + return emf.createEntityManager(); + } + + @Override + public final void close() { + if (emf != null) { + emf.close(); + } + } + + @Override + public <T extends PfConcept> void create(final T obj) { + if (obj == null) { + return; + } + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + mg.merge(obj); + mg.getTransaction().commit(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> void delete(final T obj) { + if (obj == null) { + return; + } + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + mg.remove(mg.contains(obj) ? obj : mg.merge(obj)); + mg.getTransaction().commit(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> void delete(final Class<T> someClass, final PfConceptKey key) { + if (key == null) { + return; + } + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME + key.getName() + + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).executeUpdate(); + mg.getTransaction().commit(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> void delete(final Class<T> someClass, final PfReferenceKey key) { + if (key == null) { + return; + } + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME + + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION + key.getParentKeyVersion() + + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'", someClass).executeUpdate(); + mg.getTransaction().commit(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> void createCollection(final Collection<T> objs) { + if (objs == null || objs.isEmpty()) { + return; + } + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + for (final T t : objs) { + mg.merge(t); + } + mg.getTransaction().commit(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> void deleteCollection(final Collection<T> objs) { + if (objs == null || objs.isEmpty()) { + return; + } + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + for (final T t : objs) { + mg.remove(mg.contains(t) ? t : mg.merge(t)); + } + mg.getTransaction().commit(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> int deleteByConceptKey(final Class<T> someClass, + final Collection<PfConceptKey> keys) { + if (keys == null || keys.isEmpty()) { + return 0; + } + int deletedCount = 0; + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + for (final PfConceptKey key : keys) { + deletedCount += mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME + + key.getName() + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).executeUpdate(); + } + mg.getTransaction().commit(); + } finally { + mg.close(); + } + return deletedCount; + } + + @Override + public <T extends PfConcept> int deleteByReferenceKey(final Class<T> someClass, + final Collection<PfReferenceKey> keys) { + if (keys == null || keys.isEmpty()) { + return 0; + } + int deletedCount = 0; + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + for (final PfReferenceKey key : keys) { + deletedCount += + mg.createQuery( + DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME + + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION + + key.getParentKeyVersion() + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'", + someClass).executeUpdate(); + } + mg.getTransaction().commit(); + } finally { + mg.close(); + } + return deletedCount; + } + + @Override + public <T extends PfConcept> void deleteAll(final Class<T> someClass) { + final EntityManager mg = getEntityManager(); + try { + mg.getTransaction().begin(); + mg.createQuery(DELETE_FROM + someClass.getSimpleName() + " c ", someClass).executeUpdate(); + mg.getTransaction().commit(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> T get(final Class<T> someClass, final PfConceptKey key) { + if (someClass == null) { + return null; + } + final EntityManager mg = getEntityManager(); + try { + final T t = mg.find(someClass, key); + if (t != null) { + // This clone is created to force the JPA DAO to recurse down through the object + try { + final T clonedT = someClass.newInstance(); + t.copyTo(clonedT); + return clonedT; + } catch (final Exception e) { + LOGGER.warn("Could not clone object of class \"" + someClass.getCanonicalName() + "\"", e); + return null; + } + } else { + return null; + } + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> T get(final Class<T> someClass, final PfReferenceKey key) { + if (someClass == null) { + return null; + } + final EntityManager mg = getEntityManager(); + try { + final T t = mg.find(someClass, key); + if (t != null) { + try { + final T clonedT = someClass.newInstance(); + t.copyTo(clonedT); + return clonedT; + } catch (final Exception e) { + LOGGER.warn("Could not clone object of class \"" + someClass.getCanonicalName() + "\"", e); + return null; + } + } else { + return null; + } + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> List<T> getAll(final Class<T> someClass) { + if (someClass == null) { + return Collections.emptyList(); + } + final EntityManager mg = getEntityManager(); + try { + return mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + " c", someClass).getResultList(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> List<T> getAll(final Class<T> someClass, final PfConceptKey parentKey) { + if (someClass == null) { + return Collections.emptyList(); + } + final EntityManager mg = getEntityManager(); + try { + return mg + .createQuery( + SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME + + parentKey.getName() + AND_C_KEY_PARENT_KEY_VERSION + parentKey.getVersion() + "'", + someClass) + .getResultList(); + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> T getConcept(final Class<T> someClass, final PfConceptKey key) { + if (someClass == null || key == null) { + return null; + } + final EntityManager mg = getEntityManager(); + List<T> ret; + try { + ret = mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME + key.getName() + + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).getResultList(); + } finally { + mg.close(); + } + if (ret == null || ret.isEmpty()) { + return null; + } + if (ret.size() > 1) { + throw new IllegalArgumentException("More than one result was returned for search for " + someClass + + " with key " + key.getId() + ": " + ret); + } + return ret.get(0); + } + + @Override + public <T extends PfConcept> T getConcept(final Class<T> someClass, final PfReferenceKey key) { + if (someClass == null || key == null) { + return null; + } + final EntityManager mg = getEntityManager(); + List<T> ret; + try { + ret = mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME + + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION + key.getParentKeyVersion() + + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'", someClass).getResultList(); + } finally { + mg.close(); + } + if (ret == null || ret.isEmpty()) { + return null; + } + if (ret.size() > 1) { + throw new IllegalArgumentException("More than one result was returned for search for " + someClass + + " with key " + key.getId() + ": " + ret); + } + return ret.get(0); + } + + @Override + public <T extends PfConcept> T update(final T obj) { + final EntityManager mg = getEntityManager(); + T ret; + try { + mg.getTransaction().begin(); + ret = mg.merge(obj); + mg.flush(); + mg.getTransaction().commit(); + } finally { + mg.close(); + } + return ret; + } + + @Override + public <T extends PfConcept> long size(final Class<T> someClass) { + if (someClass == null) { + return 0; + } + final EntityManager mg = getEntityManager(); + long size = 0; + try { + size = mg.createQuery("SELECT COUNT(c) FROM " + someClass.getSimpleName() + " c", Long.class) + .getSingleResult(); + } finally { + mg.close(); + } + return size; + } +} diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/impl/package-info.java b/models-dao/src/main/java/org/onap/policy/models/dao/impl/package-info.java new file mode 100644 index 000000000..0d27628a0 --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/impl/package-info.java @@ -0,0 +1,25 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Contains a default DAO implementation for the PF {@link org.onap.policy.models.base.PfConcept} + * classes that uses javax persistence. + */ +package org.onap.policy.models.dao.impl; diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/package-info.java b/models-dao/src/main/java/org/onap/policy/models/dao/package-info.java new file mode 100644 index 000000000..e8cfbe4e7 --- /dev/null +++ b/models-dao/src/main/java/org/onap/policy/models/dao/package-info.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Defines and implements the Data Access Object (DAO) that allows Apex + * {@link org.onap.policy.apex.model.basicmodel.concepts.AxConcept} concepts to be read from and written to databases + * over JDBC. + */ + +package org.onap.policy.models.dao; diff --git a/models-dao/src/test/java/org/onap/policy/models/dao/DaoMiscTest.java b/models-dao/src/test/java/org/onap/policy/models/dao/DaoMiscTest.java new file mode 100644 index 000000000..4dd70cee9 --- /dev/null +++ b/models-dao/src/test/java/org/onap/policy/models/dao/DaoMiscTest.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.dao; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import java.util.Properties; + +import org.junit.Test; +import org.onap.policy.models.dao.DaoParameters; +import org.onap.policy.models.dao.PfDaoFactory; +import org.onap.policy.models.dao.converters.CDataConditioner; +import org.onap.policy.models.dao.converters.Uuid2String; + +public class DaoMiscTest { + + @Test + public void testUuid2StringMopUp() { + final Uuid2String uuid2String = new Uuid2String(); + assertEquals("", uuid2String.convertToDatabaseColumn(null)); + } + + @Test + public void testCDataConditionerMopUp() { + assertNull(CDataConditioner.clean(null)); + } + + @Test + public void testDaoFactory() { + final DaoParameters daoParameters = new DaoParameters(); + + daoParameters.setPluginClass("somewhere.over.the.rainbow"); + try { + new PfDaoFactory().createPfDao(daoParameters); + fail("test shold throw an exception here"); + } catch (final Exception e) { + assertEquals("Policy Framework DAO class not found for DAO plugin \"somewhere.over.the.rainbow\"", + e.getMessage()); + } + + daoParameters.setPluginClass("java.lang.String"); + try { + new PfDaoFactory().createPfDao(daoParameters); + fail("test shold throw an exception here"); + } catch (final Exception e) { + assertEquals("Specified DAO plugin class \"java.lang.String\" " + "does not implement the PfDao interface", + e.getMessage()); + } + } + + @Test + public void testDaoParameters() { + final DaoParameters pars = new DaoParameters(); + pars.setJdbcProperties(new Properties()); + assertEquals(0, pars.getJdbcProperties().size()); + + pars.setJdbcProperty("name", "Dorothy"); + assertEquals("Dorothy", pars.getJdbcProperty("name")); + + pars.setPersistenceUnit("Kansas"); + assertEquals("Kansas", pars.getPersistenceUnit()); + + pars.setPluginClass("somewhere.over.the.rainbow"); + assertEquals("somewhere.over.the.rainbow", pars.getPluginClass()); + + assertEquals("DAOParameters [pluginClass=somewhere.over.the.rainbow, " + + "persistenceUnit=Kansas, jdbcProperties={name=Dorothy}]", pars.toString()); + } +} diff --git a/models-dao/src/test/java/org/onap/policy/models/dao/DummyConceptEntity.java b/models-dao/src/test/java/org/onap/policy/models/dao/DummyConceptEntity.java new file mode 100644 index 000000000..fa2e71a08 --- /dev/null +++ b/models-dao/src/test/java/org/onap/policy/models/dao/DummyConceptEntity.java @@ -0,0 +1,139 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.dao; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Table; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NonNull; + +import org.onap.policy.common.utils.validation.Assertions; +import org.onap.policy.models.base.PfConcept; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfKey; +import org.onap.policy.models.base.PfValidationResult; + +@Entity +@Table(name = "DummyConceptEntity") +@Data +@EqualsAndHashCode(callSuper = false) +public class DummyConceptEntity extends PfConcept { + private static final long serialVersionUID = -2962570563281067894L; + + @EmbeddedId() + @NonNull + private PfConceptKey key; + + @Column + @NonNull + private UUID uuid; + + @Column + @NonNull + private String description; + + public DummyConceptEntity() { + this.key = new PfConceptKey(); + } + + public DummyConceptEntity(final Double doubleValue) { + this.key = new PfConceptKey(); + } + + public DummyConceptEntity(final PfConceptKey key, final Double doubleValue) { + this.key = key; + } + + /** + * Constructor. + * + * @param key the key + * @param uuid the uuid + * @param description the description + */ + public DummyConceptEntity(PfConceptKey key, UUID uuid, String description) { + this.key = key; + this.uuid = uuid; + this.description = description; + } + + @Override + public List<PfKey> getKeys() { + final List<PfKey> keyList = new ArrayList<>(); + keyList.add(getKey()); + return keyList; + } + + @Override + public PfValidationResult validate(final PfValidationResult result) { + return key.validate(result); + } + + @Override + public void clean() { + key.clean(); + } + + @Override + public PfConcept copyTo(final PfConcept target) { + Assertions.argumentNotNull(target, "target may not be null"); + + final PfConcept copyObject = target; + Assertions.instanceOf(copyObject, DummyConceptEntity.class); + + final DummyConceptEntity copy = ((DummyConceptEntity) copyObject); + copy.setKey(key); + copy.setUuid(uuid); + copy.setDescription(description); + + return copyObject; + } + + @Override + public int compareTo(final PfConcept otherObj) { + Assertions.argumentNotNull(otherObj, "comparison object may not be null"); + + if (this == otherObj) { + return 0; + } + if (getClass() != otherObj.getClass()) { + return this.hashCode() - otherObj.hashCode(); + } + + final DummyConceptEntity other = (DummyConceptEntity) otherObj; + + if (!key.equals(other.key)) { + return key.compareTo(other.key); + } + if (!uuid.equals(other.uuid)) { + return uuid.compareTo(other.uuid); + } + return description.compareTo(other.description); + } +} diff --git a/models-dao/src/test/java/org/onap/policy/models/dao/DummyReferenceEntity.java b/models-dao/src/test/java/org/onap/policy/models/dao/DummyReferenceEntity.java new file mode 100644 index 000000000..044a63dc5 --- /dev/null +++ b/models-dao/src/test/java/org/onap/policy/models/dao/DummyReferenceEntity.java @@ -0,0 +1,121 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.dao; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Table; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NonNull; + +import org.onap.policy.common.utils.validation.Assertions; +import org.onap.policy.models.base.PfConcept; +import org.onap.policy.models.base.PfKey; +import org.onap.policy.models.base.PfReferenceKey; +import org.onap.policy.models.base.PfValidationResult; + +@Entity +@Table(name = "DummyReferenceEntity") +@Data +@EqualsAndHashCode(callSuper = false) +public class DummyReferenceEntity extends PfConcept { + private static final long serialVersionUID = -2962570563281067894L; + + @EmbeddedId() + @NonNull + private PfReferenceKey key; + + @Column + private double doubleValue; + + /** + * Default constructor. + */ + public DummyReferenceEntity() { + this.key = new PfReferenceKey(); + this.doubleValue = 123.45; + } + + /** + * Constructor. + * + * @param key the key + * @param doubleValue the double value + */ + public DummyReferenceEntity(final PfReferenceKey key, final double doubleValue) { + this.key = key; + this.doubleValue = doubleValue; + } + + @Override + public List<PfKey> getKeys() { + final List<PfKey> keyList = new ArrayList<>(); + keyList.add(getKey()); + return keyList; + } + + @Override + public PfValidationResult validate(final PfValidationResult result) { + return key.validate(result); + } + + @Override + public void clean() { + key.clean(); + } + + @Override + public PfConcept copyTo(final PfConcept target) { + Assertions.argumentNotNull(target, "target may not be null"); + + final PfConcept copyObject = target; + Assertions.instanceOf(copyObject, DummyReferenceEntity.class); + + final DummyReferenceEntity copy = ((DummyReferenceEntity) copyObject); + copy.setKey(key); + copy.setDoubleValue(doubleValue); + + return copyObject; + } + + + @Override + public int compareTo(final PfConcept otherObj) { + Assertions.argumentNotNull(otherObj, "comparison object may not be null"); + + if (this == otherObj) { + return 0; + } + if (getClass() != otherObj.getClass()) { + return this.hashCode() - otherObj.hashCode(); + } + + final DummyReferenceEntity other = (DummyReferenceEntity) otherObj; + + return new Double(doubleValue).compareTo(new Double(other.doubleValue)); + } +} diff --git a/models-dao/src/test/java/org/onap/policy/models/dao/EntityTest.java b/models-dao/src/test/java/org/onap/policy/models/dao/EntityTest.java new file mode 100644 index 000000000..8278cfe20 --- /dev/null +++ b/models-dao/src/test/java/org/onap/policy/models/dao/EntityTest.java @@ -0,0 +1,299 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.dao; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.sql.Connection; +import java.sql.DriverManager; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; +import java.util.UUID; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.base.PfReferenceKey; +import org.onap.policy.models.dao.DaoParameters; +import org.onap.policy.models.dao.PfDao; +import org.onap.policy.models.dao.PfDaoFactory; +import org.onap.policy.models.dao.impl.DefaultPfDao; + +/** + * JUnit test class. + */ +public class EntityTest { + private Connection connection; + private PfDao pfDao; + + @Before + public void setup() throws Exception { + connection = DriverManager.getConnection("jdbc:h2:mem:test"); + } + + @After + public void teardown() throws Exception { + connection.close(); + new File("derby.log").delete(); + } + + @Test + public void testEntityTestSanity() throws PfModelException { + final DaoParameters daoParameters = new DaoParameters(); + + pfDao = new PfDaoFactory().createPfDao(daoParameters); + + try { + pfDao.init(null); + fail("Test should throw an exception here"); + } catch (final Exception e) { + assertEquals("Policy Framework persistence unit parameter not set", e.getMessage()); + } + + try { + pfDao.init(daoParameters); + fail("Test should throw an exception here"); + } catch (final Exception e) { + assertEquals("Policy Framework persistence unit parameter not set", e.getMessage()); + } + + daoParameters.setPluginClass("somewhere.over.the.rainbow"); + daoParameters.setPersistenceUnit("Dorothy"); + try { + pfDao.init(daoParameters); + fail("Test should throw an exception here"); + } catch (final Exception e) { + assertEquals("Creation of Policy Framework persistence unit \"Dorothy\" failed", e.getMessage()); + } + try { + pfDao.create(new PfConceptKey()); + fail("Test should throw an exception here"); + } catch (final Exception e) { + assertEquals("Policy Framework DAO has not been initialized", e.getMessage()); + } + pfDao.close(); + } + + @Test + public void testEntityTestAllOpsJpa() throws PfModelException { + final DaoParameters daoParameters = new DaoParameters(); + daoParameters.setPluginClass(DefaultPfDao.class.getCanonicalName()); + daoParameters.setPersistenceUnit("DaoTest"); + + pfDao = new PfDaoFactory().createPfDao(daoParameters); + pfDao.init(daoParameters); + + testAllOps(); + pfDao.close(); + } + + @Test + public void testEntityTestBadVals() throws PfModelException { + final DaoParameters daoParameters = new DaoParameters(); + daoParameters.setPluginClass(DefaultPfDao.class.getCanonicalName()); + daoParameters.setPersistenceUnit("DaoTest"); + + pfDao = new PfDaoFactory().createPfDao(daoParameters); + pfDao.init(daoParameters); + + final PfConceptKey nullKey = null; + final PfReferenceKey nullRefKey = null; + final List<PfConceptKey> nullKeyList = null; + final List<PfConceptKey> emptyKeyList = new ArrayList<>(); + final List<PfReferenceKey> nullRKeyList = null; + final List<PfReferenceKey> emptyRKeyList = new ArrayList<>(); + + pfDao.create(nullKey); + pfDao.createCollection(nullKeyList); + pfDao.createCollection(emptyKeyList); + + pfDao.delete(nullKey); + pfDao.deleteCollection(nullKeyList); + pfDao.deleteCollection(emptyKeyList); + pfDao.delete(PfConceptKey.class, nullKey); + pfDao.delete(PfReferenceKey.class, nullRefKey); + pfDao.deleteByConceptKey(PfConceptKey.class, nullKeyList); + pfDao.deleteByConceptKey(PfConceptKey.class, emptyKeyList); + pfDao.deleteByReferenceKey(PfReferenceKey.class, nullRKeyList); + pfDao.deleteByReferenceKey(PfReferenceKey.class, emptyRKeyList); + + pfDao.get(null, nullKey); + pfDao.get(null, nullRefKey); + pfDao.getAll(null); + pfDao.getAll(null, nullKey); + pfDao.getConcept(null, nullKey); + pfDao.getConcept(PfConceptKey.class, nullKey); + pfDao.getConcept(null, nullRefKey); + pfDao.getConcept(PfReferenceKey.class, nullRefKey); + pfDao.size(null); + + pfDao.close(); + } + + private void testAllOps() { + final PfConceptKey aKey0 = new PfConceptKey("A-KEY0", "0.0.1"); + final PfConceptKey aKey1 = new PfConceptKey("A-KEY1", "0.0.1"); + final PfConceptKey aKey2 = new PfConceptKey("A-KEY2", "0.0.1"); + final DummyConceptEntity keyInfo0 = new DummyConceptEntity(aKey0, + UUID.fromString("00000000-0000-0000-0000-000000000000"), "key description 0"); + final DummyConceptEntity keyInfo1 = new DummyConceptEntity(aKey1, + UUID.fromString("00000000-0000-0000-0000-000000000001"), "key description 1"); + final DummyConceptEntity keyInfo2 = new DummyConceptEntity(aKey2, + UUID.fromString("00000000-0000-0000-0000-000000000002"), "key description 2"); + + pfDao.create(keyInfo0); + + final DummyConceptEntity keyInfoBack0 = pfDao.get(DummyConceptEntity.class, aKey0); + assertTrue(keyInfo0.equals(keyInfoBack0)); + + final DummyConceptEntity keyInfoBackNull = pfDao.get(DummyConceptEntity.class, PfConceptKey.getNullKey()); + assertNull(keyInfoBackNull); + + final DummyConceptEntity keyInfoBack1 = pfDao.getConcept(DummyConceptEntity.class, aKey0); + assertTrue(keyInfoBack0.equals(keyInfoBack1)); + + final DummyConceptEntity keyInfoBack2 = + pfDao.getConcept(DummyConceptEntity.class, new PfConceptKey("A-KEY3", "0.0.1")); + assertNull(keyInfoBack2); + + final Set<DummyConceptEntity> keyInfoSetIn = new TreeSet<DummyConceptEntity>(); + keyInfoSetIn.add(keyInfo1); + keyInfoSetIn.add(keyInfo2); + + pfDao.createCollection(keyInfoSetIn); + + Set<DummyConceptEntity> keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class)); + + keyInfoSetIn.add(keyInfo0); + assertTrue(keyInfoSetIn.equals(keyInfoSetOut)); + + pfDao.delete(keyInfo1); + keyInfoSetIn.remove(keyInfo1); + keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class)); + assertTrue(keyInfoSetIn.equals(keyInfoSetOut)); + + pfDao.deleteCollection(keyInfoSetIn); + keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class)); + assertEquals(0, keyInfoSetOut.size()); + + keyInfoSetIn.add(keyInfo0); + keyInfoSetIn.add(keyInfo1); + keyInfoSetIn.add(keyInfo0); + pfDao.createCollection(keyInfoSetIn); + keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class)); + assertTrue(keyInfoSetIn.equals(keyInfoSetOut)); + + pfDao.delete(DummyConceptEntity.class, aKey0); + keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class)); + assertEquals(2, keyInfoSetOut.size()); + assertEquals(2, pfDao.size(DummyConceptEntity.class)); + + final Set<PfConceptKey> keySetIn = new TreeSet<PfConceptKey>(); + keySetIn.add(aKey1); + keySetIn.add(aKey2); + + final int deletedCount = pfDao.deleteByConceptKey(DummyConceptEntity.class, keySetIn); + assertEquals(2, deletedCount); + + keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class)); + assertEquals(0, keyInfoSetOut.size()); + + keyInfoSetIn.add(keyInfo0); + keyInfoSetIn.add(keyInfo1); + keyInfoSetIn.add(keyInfo0); + pfDao.createCollection(keyInfoSetIn); + keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class)); + assertTrue(keyInfoSetIn.equals(keyInfoSetOut)); + + pfDao.deleteAll(DummyConceptEntity.class); + assertEquals(0, pfDao.size(DummyConceptEntity.class)); + + final PfConceptKey owner0Key = new PfConceptKey("Owner0", "0.0.1"); + final PfConceptKey owner1Key = new PfConceptKey("Owner1", "0.0.1"); + final PfConceptKey owner2Key = new PfConceptKey("Owner2", "0.0.1"); + final PfConceptKey owner3Key = new PfConceptKey("Owner3", "0.0.1"); + final PfConceptKey owner4Key = new PfConceptKey("Owner4", "0.0.1"); + final PfConceptKey owner5Key = new PfConceptKey("Owner5", "0.0.1"); + + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity0"), 100.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity1"), 101.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity2"), 102.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity3"), 103.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity4"), 104.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner1Key, "Entity5"), 105.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner1Key, "Entity6"), 106.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner1Key, "Entity7"), 107.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner2Key, "Entity8"), 108.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner2Key, "Entity9"), 109.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner3Key, "EntityA"), 110.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner4Key, "EntityB"), 111.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityC"), 112.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityD"), 113.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityE"), 114.0)); + pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityF"), 115.0)); + + TreeSet<DummyReferenceEntity> testEntitySetOut = + new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class)); + assertEquals(16, testEntitySetOut.size()); + + testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner0Key)); + assertEquals(5, testEntitySetOut.size()); + + testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner1Key)); + assertEquals(3, testEntitySetOut.size()); + + testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner2Key)); + assertEquals(2, testEntitySetOut.size()); + + testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner3Key)); + assertEquals(1, testEntitySetOut.size()); + + testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner4Key)); + assertEquals(1, testEntitySetOut.size()); + + testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner5Key)); + assertEquals(4, testEntitySetOut.size()); + + assertNotNull(pfDao.get(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity0"))); + assertNotNull(pfDao.getConcept(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity0"))); + assertNull(pfDao.get(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity1000"))); + assertNull(pfDao.getConcept(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity1000"))); + pfDao.delete(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity0")); + + final Set<PfReferenceKey> rKeySetIn = new TreeSet<PfReferenceKey>(); + rKeySetIn.add(new PfReferenceKey(owner4Key, "EntityB")); + rKeySetIn.add(new PfReferenceKey(owner5Key, "EntityD")); + + final int deletedRCount = pfDao.deleteByReferenceKey(DummyReferenceEntity.class, rKeySetIn); + assertEquals(2, deletedRCount); + + pfDao.update(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityF"), 120.0)); + } +} diff --git a/models-dao/src/test/resources/META-INF/persistence.xml b/models-dao/src/test/resources/META-INF/persistence.xml new file mode 100644 index 000000000..1f430bc8b --- /dev/null +++ b/models-dao/src/test/resources/META-INF/persistence.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + Copyright (C) 2019 Nordix Foundation. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 + ============LICENSE_END========================================================= +--> + +<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> + <persistence-unit name="DaoTest" transaction-type="RESOURCE_LOCAL"> + <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> + + <class>org.onap.policy.models.dao.converters.CDataConditioner</class> + <class>org.onap.policy.models.dao.converters.Uuid2String</class> + <class>org.onap.policy.models.base.concepts.PfConcepttKey</class> + <class>org.onap.policy.models.dao.DummyConceptEntity</class> + <class>org.onap.policy.models.dao.DummyReferenceEntity</class> + + <properties> + <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" /> + <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:testdb" /> + <property name="javax.persistence.jdbc.user" value="sa" /> + <property name="javax.persistence.jdbc.password" value="" /> + <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> + <property name="eclipselink.ddl-generation.output-mode" value="database" /> + <property name="eclipselink.logging.level" value="INFO" /> + </properties> + </persistence-unit> +</persistence> diff --git a/models-dao/src/test/resources/logback-test.xml b/models-dao/src/test/resources/logback-test.xml new file mode 100644 index 000000000..f0c510c78 --- /dev/null +++ b/models-dao/src/test/resources/logback-test.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + Copyright (C) 2019 Nordix Foundation. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 + ============LICENSE_END========================================================= +--> + +<configuration> + + <contextName>PolicyModels</contextName> + <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /> + <property name="LOG_DIR" value="${java.io.tmpdir}/onap_policy_logging/" /> + + <!-- USE FOR STD OUT ONLY --> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern> + </encoder> + </appender> + + <root level="INFO"> + <appender-ref ref="STDOUT" /> + </root> + + <logger name="org.infinispan" level="INFO" additivity="false"> + <appender-ref ref="STDOUT" /> + </logger> + + <logger name="org.apache.zookeeper.ClientCnxn" level="OFF" additivity="false"> + <appender-ref ref="STDOUT" /> + </logger> + + <appender name="FILE" class="ch.qos.logback.core.FileAppender"> + <file>${LOG_DIR}/models.log</file> + <encoder> + <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level + %logger{26} - %msg %n %ex{full}</pattern> + </encoder> + </appender> + + <logger name="org.onap.policy.models.dao" level="INFO" additivity="false"> + <appender-ref ref="STDOUT" /> + </logger> +</configuration> |