diff options
11 files changed, 504 insertions, 75 deletions
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 index 85c971ce7..609afefd4 100644 --- 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 @@ -29,8 +29,8 @@ 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. + * 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 { @@ -108,7 +108,7 @@ public interface PfDao { <T extends PfConcept> int deleteByConceptKey(Class<T> someClass, Collection<PfConceptKey> keys); /** - * Delete a collection of objects in the database referred to by reference key. + * policypolicypolicy 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} @@ -129,6 +129,18 @@ public interface PfDao { * 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}, if name is null, all concepts + * of type T are returned, if name is not null and version is null, all versions of that concept matching the + * name are returned. + * @param key the key of the object to get + * @return the objects that was retrieved from the database + */ + <T extends PfConcept> List<T> getFiltered(Class<T> someClass, PfConceptKey key); + + /** + * 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 @@ -141,8 +153,7 @@ public interface PfDao { * @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 + * @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); @@ -166,6 +177,35 @@ public interface PfDao { <T extends PfConcept> List<T> getAll(Class<T> someClass, PfConceptKey parentKey); /** + * 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} + * @param name the name of the concepts for which to get all versions + * @return the objects or null if no objects were retrieved + */ + <T extends PfConcept> List<T> getAllVersions(Class<T> someClass, final String name); + + /** + * Get latest version of 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> getLatestVersions(Class<T> someClass); + + /** + * Get latest version of an object 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} + * @param conceptName the name of the concept for which to get the latest version + * @return the objects or null if no objects were retrieved + */ + <T extends PfConcept> T getLatestVersion(Class<T> someClass, final String conceptName); + + /** * 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} @@ -197,7 +237,7 @@ public interface PfDao { /** * Update a concept in the database. * - * @param <T> the type of the object to get, a subclass of {@link PfConcept} + * @param <T> the type of the object to update, a subclass of {@link PfConcept} * @param obj the object to update * @return the updated object */ 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 index 947b866a1..f7659b2ce 100644 --- 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 @@ -40,20 +40,58 @@ 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. + * 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 "; + // @formatter:off + private static final String NAME = "name"; + private static final String VERSION = "version"; + private static final String PARENT_NAME = "parentname"; + private static final String PARENT_VERSION = "parentversion"; + private static final String LOCAL_NAME = "localname"; + + private static final String TABLE_TOKEN = "__TABLE__"; + + private static final String DELETE_FROM_TABLE = "DELETE FROM __TABLE__ c"; + + private static final String SELECT_FROM_TABLE = "SELECT c FROM __TABLE__ c"; + + private static final String WHERE = " WHERE "; + private static final String AND = " AND "; + + private static final String NAME_FILTER = "c.key.name = :name"; + private static final String VERSION_FILTER = "c.key.version = :version"; + private static final String PARENT_NAME_FILTER = "c.key.parentKeyName = :parentname"; + private static final String PARENT_VERSION_FILTER = "c.key.parentKeyVersion = :parentversion"; + private static final String LOCAL_NAME_FILTER = "c.key.localName = :localname"; + private static final String MAX_VERISON_FILTER = "c.key.version = (SELECT MAX(c.key.version) FROM __TABLE__ c)"; + + private static final String DELETE_BY_CONCEPT_KEY = + DELETE_FROM_TABLE + WHERE + NAME_FILTER + AND + VERSION_FILTER; + + private static final String DELETE_BY_REFERENCE_KEY = + DELETE_FROM_TABLE + WHERE + PARENT_NAME_FILTER + AND + PARENT_VERSION_FILTER + AND + LOCAL_NAME_FILTER; + + private static final String SELECT_ALL_FOR_PARENT = + SELECT_FROM_TABLE + WHERE + PARENT_NAME_FILTER + AND + PARENT_VERSION_FILTER; + + private static final String SELECT_ALL_VERSIONS = SELECT_FROM_TABLE + WHERE + NAME_FILTER; + + private static final String SELECT_LATEST_VERSION = + SELECT_FROM_TABLE + WHERE + NAME_FILTER + AND + MAX_VERISON_FILTER; + + private static final String SELECT_LATEST_VERSIONS = + "SELECT c FROM __TABLE__ c WHERE c.key.version = (SELECT MAX(c.key.version) FROM __TABLE__ c)"; + + private static final String SELECT_BY_CONCEPT_KEY = + SELECT_FROM_TABLE + WHERE + NAME_FILTER + AND + VERSION_FILTER; + + private static final String SELECT_BY_REFERENCE_KEY = + SELECT_FROM_TABLE + WHERE + PARENT_NAME_FILTER + AND + PARENT_VERSION_FILTER + AND + LOCAL_NAME_FILTER; + // @formatter:on // Entity manager for JPA private EntityManagerFactory emf = null; @@ -138,10 +176,14 @@ public class DefaultPfDao implements PfDao { } final EntityManager mg = getEntityManager(); try { + // @formatter:off 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.createQuery(setQueryTable(DELETE_BY_CONCEPT_KEY, someClass), someClass) + .setParameter(NAME, key.getName()) + .setParameter("version", key.getVersion()) + .executeUpdate(); mg.getTransaction().commit(); + // @formatter:on } finally { mg.close(); } @@ -154,11 +196,15 @@ public class DefaultPfDao implements PfDao { } final EntityManager mg = getEntityManager(); try { + // @formatter:off 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.createQuery(setQueryTable(DELETE_BY_REFERENCE_KEY, someClass), someClass) + .setParameter(PARENT_NAME, key.getParentKeyName()) + .setParameter(PARENT_VERSION, key.getParentKeyVersion()) + .setParameter(LOCAL_NAME, key.getLocalName()) + .executeUpdate(); mg.getTransaction().commit(); + // @formatter:on } finally { mg.close(); } @@ -206,12 +252,16 @@ public class DefaultPfDao implements PfDao { int deletedCount = 0; final EntityManager mg = getEntityManager(); try { + // @formatter:off 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(); + deletedCount += mg.createQuery(setQueryTable(DELETE_BY_CONCEPT_KEY, someClass), someClass) + .setParameter(NAME, key.getName()) + .setParameter("version", key.getVersion()) + .executeUpdate(); } mg.getTransaction().commit(); + // @formatter:on } finally { mg.close(); } @@ -227,16 +277,17 @@ public class DefaultPfDao implements PfDao { int deletedCount = 0; final EntityManager mg = getEntityManager(); try { + // @formatter:off 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(); + deletedCount += mg.createQuery(setQueryTable(DELETE_BY_REFERENCE_KEY, someClass), someClass) + .setParameter(PARENT_NAME, key.getParentKeyName()) + .setParameter(PARENT_VERSION, key.getParentKeyVersion()) + .setParameter(LOCAL_NAME, key.getLocalName()) + .executeUpdate(); } mg.getTransaction().commit(); + // @formatter:on } finally { mg.close(); } @@ -248,7 +299,7 @@ public class DefaultPfDao implements PfDao { final EntityManager mg = getEntityManager(); try { mg.getTransaction().begin(); - mg.createQuery(DELETE_FROM + someClass.getSimpleName() + " c ", someClass).executeUpdate(); + mg.createQuery(setQueryTable(DELETE_FROM_TABLE, someClass), someClass).executeUpdate(); mg.getTransaction().commit(); } finally { mg.close(); @@ -256,6 +307,21 @@ public class DefaultPfDao implements PfDao { } @Override + public <T extends PfConcept> List<T> getFiltered(Class<T> someClass, PfConceptKey key) { + if (key.getName() == null) { + return getAll(someClass); + } + + if (key.getVersion() == null) { + return getAllVersions(someClass, key.getName()); + } + + T foundConcept = get(someClass, key); + + return (foundConcept == null ? Collections.emptyList() : Collections.singletonList(foundConcept)); + } + + @Override public <T extends PfConcept> T get(final Class<T> someClass, final PfConceptKey key) { if (someClass == null) { return null; @@ -313,7 +379,7 @@ public class DefaultPfDao implements PfDao { } final EntityManager mg = getEntityManager(); try { - return mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + " c", someClass).getResultList(); + return mg.createQuery(setQueryTable(SELECT_FROM_TABLE, someClass), someClass).getResultList(); } finally { mg.close(); } @@ -326,62 +392,112 @@ public class DefaultPfDao implements PfDao { } 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) + // @formatter:off + return mg.createQuery(setQueryTable(SELECT_ALL_FOR_PARENT, someClass), someClass) + .setParameter(PARENT_NAME, parentKey.getName()) + .setParameter(PARENT_VERSION, parentKey.getVersion()) .getResultList(); + // @formatter:on } finally { mg.close(); } } @Override - public <T extends PfConcept> T getConcept(final Class<T> someClass, final PfConceptKey key) { - if (someClass == null || key == null) { - return null; + public <T extends PfConcept> List<T> getAllVersions(final Class<T> someClass, final String conceptName) { + if (someClass == null || conceptName == null) { + return Collections.emptyList(); + } + final EntityManager mg = getEntityManager(); + try { + // @formatter:off + return mg.createQuery(setQueryTable(SELECT_ALL_VERSIONS, someClass), someClass) + .setParameter(NAME, conceptName) + .getResultList(); + // @formatter:on + } finally { + mg.close(); + } + } + + @Override + public <T extends PfConcept> List<T> getLatestVersions(final Class<T> someClass) { + if (someClass == null) { + return Collections.emptyList(); } 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(); + // @formatter:off + return mg.createQuery(setQueryTable(SELECT_LATEST_VERSIONS, someClass), someClass) + .getResultList(); + // @formatter:on } finally { mg.close(); } - if (ret == null || ret.isEmpty()) { + } + + @Override + public <T extends PfConcept> T getLatestVersion(final Class<T> someClass, final String conceptName) { + if (someClass == null || conceptName == null) { return null; } - if (ret.size() > 1) { - throw new IllegalArgumentException("More than one result was returned for search for " + someClass - + " with key " + key.getId() + ": " + ret); + final EntityManager mg = getEntityManager(); + List<T> ret; + try { + // @formatter:off + ret = mg.createQuery(setQueryTable(SELECT_LATEST_VERSION, someClass), someClass) + .setParameter(NAME, conceptName) + .getResultList(); + // @formatter:on + } finally { + mg.close(); } - return ret.get(0); + + return getSingleResult(someClass, conceptName, ret); } @Override - public <T extends PfConcept> T getConcept(final Class<T> someClass, final PfReferenceKey key) { + 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_PARENT_KEY_NAME - + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION + key.getParentKeyVersion() - + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'", someClass).getResultList(); + // @formatter:off + ret = mg.createQuery(setQueryTable(SELECT_BY_CONCEPT_KEY, someClass), someClass) + .setParameter(NAME, key.getName()) + .setParameter(VERSION, key.getVersion()) + .getResultList(); + // @formatter:on } finally { mg.close(); } - if (ret == null || ret.isEmpty()) { + + return getSingleResult(someClass, key.getId(), ret); + } + + @Override + public <T extends PfConcept> T getConcept(final Class<T> someClass, final PfReferenceKey key) { + if (someClass == null || key == null) { return null; } - if (ret.size() > 1) { - throw new IllegalArgumentException("More than one result was returned for search for " + someClass - + " with key " + key.getId() + ": " + ret); + final EntityManager mg = getEntityManager(); + List<T> ret; + try { + // @formatter:off + ret = mg.createQuery(setQueryTable(SELECT_BY_REFERENCE_KEY, someClass), someClass) + .setParameter(PARENT_NAME, key.getParentKeyName()) + .setParameter(PARENT_VERSION, key.getParentKeyVersion()) + .setParameter(LOCAL_NAME, key.getLocalName()) + .getResultList(); + // @formatter:on + } finally { + mg.close(); } - return ret.get(0); + + return getSingleResult(someClass, key.getId(), ret); } @Override @@ -414,4 +530,34 @@ public class DefaultPfDao implements PfDao { } return size; } + + /** + * Add the table to a query string. + * + * @param queryString the query string + * @param tableClass the class name of the table + * @return the updated query string + */ + private <T extends PfConcept> String setQueryTable(final String queryString, final Class<T> tableClass) { + return queryString.replaceAll(TABLE_TOKEN, tableClass.getSimpleName()); + } + + /** + * Check that a query returned one and only one entry and return that entry. + * + * @param someClass the class being searched for + * @param conceptName the concept name being searched for + * @param resultList the result list returned by the query + * @return the single unique result + */ + private <T extends PfConcept> T getSingleResult(final Class<T> someClass, final String searchFilter, List<T> ret) { + if (ret == null || ret.isEmpty()) { + return null; + } + if (ret.size() > 1) { + throw new IllegalArgumentException("More than one result was returned query on " + someClass + + " with filter " + searchFilter + ": " + ret); + } + return ret.get(0); + } } 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 index 9b07dfbb1..a0ad5c21d 100644 --- 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 @@ -109,6 +109,9 @@ public class EntityTest { pfDao.init(daoParameters); testAllOps(); + + testVersionOps(); + pfDao.close(); } @@ -294,4 +297,40 @@ public class EntityTest { pfDao.update(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityF"), 120.0)); } + + private void testVersionOps() { + final PfConceptKey aKey0 = new PfConceptKey("AAA0", "0.0.1"); + final PfConceptKey aKey1 = new PfConceptKey("AAA0", "0.0.2"); + final PfConceptKey aKey2 = new PfConceptKey("AAA0", "0.0.3"); + final PfConceptKey bKey0 = new PfConceptKey("BBB0", "0.0.1"); + final PfConceptKey bKey1 = new PfConceptKey("BBB0", "0.0.2"); + final PfConceptKey bKey2 = new PfConceptKey("BBB0", "0.0.3"); + 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"); + final DummyConceptEntity keyInfo3 = new DummyConceptEntity(bKey0, + UUID.fromString("00000000-0000-0000-0000-000000000000"), "key description 0"); + final DummyConceptEntity keyInfo4 = new DummyConceptEntity(bKey1, + UUID.fromString("00000000-0000-0000-0000-000000000001"), "key description 1"); + final DummyConceptEntity keyInfo5 = new DummyConceptEntity(bKey2, + UUID.fromString("00000000-0000-0000-0000-000000000002"), "key description 2"); + + pfDao.create(keyInfo0); + pfDao.create(keyInfo1); + pfDao.create(keyInfo2); + pfDao.create(keyInfo3); + pfDao.create(keyInfo4); + pfDao.create(keyInfo5); + + assertEquals(3, pfDao.getAllVersions(DummyConceptEntity.class, "AAA0").size()); + DummyConceptEntity latestVersionEntity = pfDao.getLatestVersion(DummyConceptEntity.class, "AAA0"); + assertEquals(aKey2, latestVersionEntity.getKey()); + List<DummyConceptEntity> returnedLatestVersions = pfDao.getLatestVersions(DummyConceptEntity.class); + assertEquals(2, returnedLatestVersions.size()); + assertEquals("0.0.3", returnedLatestVersions.get(0).getKey().getVersion()); + assertEquals("0.0.3", returnedLatestVersions.get(1).getKey().getVersion()); + } } diff --git a/models-dao/src/test/resources/META-INF/persistence.xml b/models-dao/src/test/resources/META-INF/persistence.xml index 5779deb18..25858caba 100644 --- a/models-dao/src/test/resources/META-INF/persistence.xml +++ b/models-dao/src/test/resources/META-INF/persistence.xml @@ -37,6 +37,18 @@ <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" /> + + <property name="eclipselink.logging.level" value="ALL" /> + <property name="eclipselink.logging.level.jpa" value="ALL" /> + <property name="eclipselink.logging.level.ddl" value="ALL" /> + <property name="eclipselink.logging.level.connection" value="ALL" /> + <property name="eclipselink.logging.level.sql" value="ALL" /> + <property name="eclipselink.logging.level.transaction" value="ALL" /> + <property name="eclipselink.logging.level.sequencing" value="ALL" /> + <property name="eclipselink.logging.level.server" value="ALL" /> + <property name="eclipselink.logging.level.query" value="ALL" /> + <property name="eclipselink.logging.level.properties" value="ALL" /> + </properties> </persistence-unit> </persistence> diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/provider/PdpProvider.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/provider/PdpProvider.java index a32f5a4a9..20553d788 100644 --- a/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/provider/PdpProvider.java +++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/persistence/provider/PdpProvider.java @@ -21,7 +21,6 @@ package org.onap.policy.models.pdp.persistence.provider; import java.util.ArrayList; -import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -34,12 +33,16 @@ import org.apache.commons.lang3.tuple.Pair; 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.base.PfValidationResult; import org.onap.policy.models.dao.PfDao; +import org.onap.policy.models.pdp.concepts.Pdp; import org.onap.policy.models.pdp.concepts.PdpGroup; import org.onap.policy.models.pdp.concepts.PdpStatistics; import org.onap.policy.models.pdp.concepts.PdpSubGroup; +import org.onap.policy.models.pdp.persistence.concepts.JpaPdp; import org.onap.policy.models.pdp.persistence.concepts.JpaPdpGroup; +import org.onap.policy.models.pdp.persistence.concepts.JpaPdpSubGroup; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,11 +55,14 @@ import org.slf4j.LoggerFactory; public class PdpProvider { private static final Logger LOGGER = LoggerFactory.getLogger(PdpProvider.class); + // Recurring string constants + private static final String NOT_VALID = "\" is not valid \n"; + /** * Get PDP groups. * * @param dao the DAO to use to access the database - * @param name the name of the policy to get, null to get all PDP groups + * @param name the name of the PDP group to get, null to get all PDP groups * @param version the version of the policy to get, null to get all versions of a PDP group * @return the PDP groups found * @throws PfModelException on errors getting PDP groups @@ -64,20 +70,19 @@ public class PdpProvider { public List<PdpGroup> getPdpGroups(@NonNull final PfDao dao, final String name, final String version) throws PfModelException { - PfConceptKey jpaPdpGroupKey = new PfConceptKey(name, version); - JpaPdpGroup jpaPdpGroup = dao.get(JpaPdpGroup.class, jpaPdpGroupKey); + List<JpaPdpGroup> foundPdpGroups = dao.getFiltered(JpaPdpGroup.class, new PfConceptKey(name, version)); - if (jpaPdpGroup != null) { - return Collections.singletonList(jpaPdpGroup.toAuthorative()); + if (foundPdpGroups != null) { + return asPdpGroupList(foundPdpGroups); } else { - String errorMessage = "PDP group not found: " + jpaPdpGroupKey.getId(); + String errorMessage = "no PDP groups found for filter " + name + ":" + version; LOGGER.warn(errorMessage); throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage); } } /** - * Get latest PDP Groups. + * Get latest PDP Groups, returns PDP groups in all states. * * @param dao the DAO to use to access the database * @param name the name of the PDP group to get, null to get all PDP groups @@ -85,11 +90,20 @@ public class PdpProvider { * @throws PfModelException on errors getting policies */ public List<PdpGroup> getLatestPdpGroups(@NonNull final PfDao dao, final String name) throws PfModelException { - return new ArrayList<>(); + List<JpaPdpGroup> returnList = new ArrayList<>(); + + if (name == null) { + returnList.add(dao.getLatestVersion(JpaPdpGroup.class, name)); + } + else { + returnList.addAll(dao.getLatestVersions(JpaPdpGroup.class)); + } + + return asPdpGroupList(returnList); } /** - * Get a filtered list of PDP groups. + * Get a filtered list of PDP groups, returns only active PDP groups. * * @param dao the DAO to use to access the database * @param pdpType The PDP type filter for the returned PDP groups, null to get policy types across PDP subgroups @@ -118,7 +132,7 @@ public class PdpProvider { PfValidationResult validationResult = jpaPdpGroup.validate(new PfValidationResult()); if (!validationResult.isOk()) { - String errorMessage = "pdp group \"" + jpaPdpGroup.getId() + "\" is not valid \n" + validationResult; + String errorMessage = "pdp group \"" + jpaPdpGroup.getId() + NOT_VALID + validationResult; LOGGER.warn(errorMessage); throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage); } @@ -148,9 +162,32 @@ public class PdpProvider { */ public List<PdpGroup> updatePdpGroups(@NonNull final PfDao dao, @NonNull final List<PdpGroup> pdpGroups) throws PfModelException { - return new ArrayList<>(); - } + for (PdpGroup pdpGroup : pdpGroups) { + JpaPdpGroup jpaPdpGroup = new JpaPdpGroup();; + jpaPdpGroup.fromAuthorative(pdpGroup); + + PfValidationResult validationResult = jpaPdpGroup.validate(new PfValidationResult()); + if (!validationResult.isOk()) { + String errorMessage = "pdp group \"" + jpaPdpGroup.getId() + NOT_VALID + validationResult; + LOGGER.warn(errorMessage); + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage); + } + + dao.update(jpaPdpGroup); + } + + // Return the created PDP groups + List<PdpGroup> returnPdpGroups = new ArrayList<>(); + + for (PdpGroup pdpGroup : pdpGroups) { + JpaPdpGroup jpaPdpGroup = + dao.get(JpaPdpGroup.class, new PfConceptKey(pdpGroup.getName(), pdpGroup.getVersion())); + returnPdpGroups.add(jpaPdpGroup.toAuthorative()); + } + + return returnPdpGroups; + } /** * Update a PDP subgroup. @@ -163,7 +200,54 @@ public class PdpProvider { */ public void updatePdpSubGroup(@NonNull final PfDao dao, @NonNull final String pdpGroupName, @NonNull final String pdpGroupVersion, @NonNull final PdpSubGroup pdpSubGroup) throws PfModelException { - // Not implemented yet + + final PfReferenceKey subGroupKey = new PfReferenceKey(pdpGroupName, pdpGroupVersion, pdpSubGroup.getPdpType()); + final JpaPdpSubGroup jpaPdpSubgroup = new JpaPdpSubGroup(subGroupKey); + jpaPdpSubgroup.fromAuthorative(pdpSubGroup); + + PfValidationResult validationResult = jpaPdpSubgroup.validate(new PfValidationResult()); + if (!validationResult.isOk()) { + String errorMessage = "PDP subgroup \"" + jpaPdpSubgroup.getId() + NOT_VALID + validationResult; + LOGGER.warn(errorMessage); + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage); + } + + if (dao.update(jpaPdpSubgroup) == null) { + String errorMessage = "update of PDP subgroup \"" + jpaPdpSubgroup.getId() + "\" failed"; + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage); + } + } + + /** + * Update a PDP. + * + * @param dao the DAO to use to access the database + * @param pdpGroupName the name of the PDP group of the PDP subgroup + * @param pdpGroupVersion the version of the PDP group of the PDP subgroup + * @param pdpSubGroup the PDP subgroup to be updated + * @param pdp the PDP to be updated + * @throws PfModelException on errors updating PDP subgroups + */ + public void updatePdp(@NonNull final PfDao dao, @NonNull final String pdpGroupName, + @NonNull final String pdpGroupVersion, @NonNull final String pdpSubGroup, @NonNull final Pdp pdp) + throws PfModelException { + + final PfReferenceKey pdpKey = + new PfReferenceKey(pdpGroupName, pdpGroupVersion, pdpSubGroup, pdp.getInstanceId()); + final JpaPdp jpaPdp = new JpaPdp(pdpKey); + jpaPdp.fromAuthorative(pdp); + + PfValidationResult validationResult = jpaPdp.validate(new PfValidationResult()); + if (!validationResult.isOk()) { + String errorMessage = "PDP \"" + jpaPdp.getId() + NOT_VALID + validationResult; + LOGGER.warn(errorMessage); + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage); + } + + if (dao.update(jpaPdp) == null) { + String errorMessage = "update of PDP \"" + jpaPdp.getId() + "\" failed"; + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage); + } } /** @@ -177,8 +261,20 @@ public class PdpProvider { */ public PdpGroup deletePdpGroup(@NonNull final PfDao dao, @NonNull final String name, @NonNull final String version) throws PfModelException { - return new PdpGroup(); + PfConceptKey pdpGroupKey = new PfConceptKey(name, version); + + JpaPdpGroup jpaDeletePdpGroup = dao.get(JpaPdpGroup.class, pdpGroupKey); + + if (jpaDeletePdpGroup == null) { + String errorMessage = + "delete of PDP group \"" + pdpGroupKey.getId() + "\" failed, PDP group does not exist"; + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage); + } + + dao.delete(jpaDeletePdpGroup); + + return jpaDeletePdpGroup.toAuthorative(); } /** @@ -223,4 +319,20 @@ public class PdpProvider { final String name) throws PfModelException { return new LinkedHashMap<>(); } + + /** + * Convert JPA PDP group list to an authorative PDP group list. + * + * @param foundPdpGroups the list to convert + * @return the authorative list + */ + private List<PdpGroup> asPdpGroupList(List<JpaPdpGroup> jpaPdpGroupList) { + List<PdpGroup> pdpGroupList = new ArrayList<>(jpaPdpGroupList.size()); + + for (JpaPdpGroup jpaPdpGroup : jpaPdpGroupList) { + pdpGroupList.add(jpaPdpGroup.toAuthorative()); + } + + return pdpGroupList; + } } diff --git a/models-provider/src/main/java/org/onap/policy/models/provider/PolicyModelsProvider.java b/models-provider/src/main/java/org/onap/policy/models/provider/PolicyModelsProvider.java index af1c88f2b..12c72d714 100644 --- a/models-provider/src/main/java/org/onap/policy/models/provider/PolicyModelsProvider.java +++ b/models-provider/src/main/java/org/onap/policy/models/provider/PolicyModelsProvider.java @@ -27,6 +27,7 @@ import lombok.NonNull; import org.apache.commons.lang3.tuple.Pair; import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.pdp.concepts.Pdp; import org.onap.policy.models.pdp.concepts.PdpGroup; import org.onap.policy.models.pdp.concepts.PdpStatistics; import org.onap.policy.models.pdp.concepts.PdpSubGroup; @@ -152,6 +153,18 @@ public interface PolicyModelsProvider extends AutoCloseable { * @return the policies found * @throws PfModelException on errors getting policies */ + public ToscaServiceTemplate getPolicies4PolicyType(@NonNull final String policyTypeName, + final String policyTypeVersion) throws PfModelException; + + /** + * Get policies for a policy type name. + * + * @param policyTypeName the name of the policy type for which to get policies + * @param policyTypeVersion the version of the policy type, null returns all versions of deployed policies for + * policy types + * @return the policies found + * @throws PfModelException on errors getting policies + */ public List<ToscaPolicy> getPolicyList4PolicyType(@NonNull final String policyTypeName, final String policyTypeVersion) throws PfModelException; @@ -328,7 +341,6 @@ public interface PolicyModelsProvider extends AutoCloseable { */ public List<PdpGroup> updatePdpGroups(@NonNull final List<PdpGroup> pdpGroups) throws PfModelException; - /** * Update a PDP subgroup. * @@ -341,6 +353,18 @@ public interface PolicyModelsProvider extends AutoCloseable { @NonNull final PdpSubGroup pdpSubGroup) throws PfModelException; /** + * Update a PDP. + * + * @param pdpGroupName the name of the PDP group of the PDP subgroup + * @param pdpGroupVersion the version of the PDP group of the PDP subgroup + * @param pdpSubGroup the PDP subgroup to be updated + * @param pdp the PDP to be updated + * @throws PfModelException on errors updating PDP subgroups + */ + public void updatePdp(@NonNull final String pdpGroupName, @NonNull final String pdpGroupVersion, + @NonNull final String pdpSubGroup, @NonNull final Pdp pdp) throws PfModelException; + + /** * Delete a PDP group. * * @param name the name of the policy to get, null to get all PDP groups diff --git a/models-provider/src/main/java/org/onap/policy/models/provider/impl/DatabasePolicyModelsProviderImpl.java b/models-provider/src/main/java/org/onap/policy/models/provider/impl/DatabasePolicyModelsProviderImpl.java index 96185b65a..51b7d2f68 100644 --- a/models-provider/src/main/java/org/onap/policy/models/provider/impl/DatabasePolicyModelsProviderImpl.java +++ b/models-provider/src/main/java/org/onap/policy/models/provider/impl/DatabasePolicyModelsProviderImpl.java @@ -37,6 +37,7 @@ 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; +import org.onap.policy.models.pdp.concepts.Pdp; import org.onap.policy.models.pdp.concepts.PdpGroup; import org.onap.policy.models.pdp.concepts.PdpStatistics; import org.onap.policy.models.pdp.concepts.PdpSubGroup; @@ -206,6 +207,13 @@ public class DatabasePolicyModelsProviderImpl implements PolicyModelsProvider { } @Override + public ToscaServiceTemplate getPolicies4PolicyType(@NonNull String policyTypeName, String policyTypeVersion) + throws PfModelException { + assertInitilized(); + return new AuthorativeToscaProvider().getPolicies4PolicyType(pfDao, policyTypeName, policyTypeVersion); + } + + @Override public List<ToscaPolicy> getPolicyList4PolicyType(@NonNull final String policyTypeName, final String policyTypeVersion) throws PfModelException { assertInitilized(); @@ -337,6 +345,12 @@ public class DatabasePolicyModelsProviderImpl implements PolicyModelsProvider { } @Override + public void updatePdp(@NonNull String pdpGroupName, @NonNull String pdpGroupVersion, + @NonNull String pdpSubGroup, @NonNull Pdp pdp) throws PfModelException { + new PdpProvider().updatePdp(pfDao, pdpGroupName, pdpGroupVersion, pdpSubGroup, pdp); + } + + @Override public PdpGroup deletePdpGroup(@NonNull final String name, @NonNull final String version) throws PfModelException { assertInitilized(); return new PdpProvider().deletePdpGroup(pfDao, name, version); diff --git a/models-provider/src/main/java/org/onap/policy/models/provider/impl/DummyPolicyModelsProviderImpl.java b/models-provider/src/main/java/org/onap/policy/models/provider/impl/DummyPolicyModelsProviderImpl.java index bf707ef53..52929ab5a 100644 --- a/models-provider/src/main/java/org/onap/policy/models/provider/impl/DummyPolicyModelsProviderImpl.java +++ b/models-provider/src/main/java/org/onap/policy/models/provider/impl/DummyPolicyModelsProviderImpl.java @@ -34,6 +34,7 @@ import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.common.utils.resources.ResourceUtils; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.pdp.concepts.Pdp; import org.onap.policy.models.pdp.concepts.PdpGroup; import org.onap.policy.models.pdp.concepts.PdpStatistics; import org.onap.policy.models.pdp.concepts.PdpSubGroup; @@ -119,6 +120,12 @@ public class DummyPolicyModelsProviderImpl implements PolicyModelsProvider { } @Override + public ToscaServiceTemplate getPolicies4PolicyType(@NonNull String policyTypeName, String policyTypeVersion) + throws PfModelException { + return null; + } + + @Override public List<ToscaPolicy> getPolicyList4PolicyType(@NonNull final String policyTypeName, final String policyTypeVersion) throws PfModelException { return new ArrayList<>(); @@ -231,6 +238,12 @@ public class DummyPolicyModelsProviderImpl implements PolicyModelsProvider { } @Override + public void updatePdp(@NonNull String pdpGroupName, @NonNull String pdpGroupVersion, + @NonNull String pdpSubGroup, @NonNull Pdp pdp) throws PfModelException { + // Not implemented + } + + @Override public PdpGroup deletePdpGroup(@NonNull final String name, @NonNull final String version) throws PfModelException { return null; } diff --git a/models-provider/src/test/java/org/onap/policy/models/provider/impl/DatabasePolicyModelsProviderTest.java b/models-provider/src/test/java/org/onap/policy/models/provider/impl/DatabasePolicyModelsProviderTest.java index 7ad221721..8a83f4414 100644 --- a/models-provider/src/test/java/org/onap/policy/models/provider/impl/DatabasePolicyModelsProviderTest.java +++ b/models-provider/src/test/java/org/onap/policy/models/provider/impl/DatabasePolicyModelsProviderTest.java @@ -21,6 +21,7 @@ package org.onap.policy.models.provider.impl; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; @@ -311,13 +312,14 @@ public class DatabasePolicyModelsProviderTest { databaseProvider.deleteGuardPolicy("policy_id"); }).hasMessage("no policy found for policy ID: policy_id"); - assertThatThrownBy(() -> { - databaseProvider.getPdpGroups("name", "version"); - }).hasMessage("PDP group not found: name:version"); + assertEquals(0, databaseProvider.getPdpGroups("name", "version").size()); assertNotNull(databaseProvider.createPdpGroups(new ArrayList<>())); assertNotNull(databaseProvider.updatePdpGroups(new ArrayList<>())); - assertNotNull(databaseProvider.deletePdpGroup("name", "version")); + + assertThatThrownBy(() -> { + databaseProvider.deletePdpGroup("name", "version"); + }).hasMessage("delete of PDP group \"name:version\" failed, PDP group does not exist"); } catch (Exception exc) { LOGGER.warn("test should not throw an exception", exc); diff --git a/models-provider/src/test/java/org/onap/policy/models/provider/impl/DummyBadProviderImpl.java b/models-provider/src/test/java/org/onap/policy/models/provider/impl/DummyBadProviderImpl.java index c64603d9a..69b7a0f71 100644 --- a/models-provider/src/test/java/org/onap/policy/models/provider/impl/DummyBadProviderImpl.java +++ b/models-provider/src/test/java/org/onap/policy/models/provider/impl/DummyBadProviderImpl.java @@ -30,6 +30,7 @@ import lombok.NonNull; import org.apache.commons.lang3.tuple.Pair; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.pdp.concepts.Pdp; import org.onap.policy.models.pdp.concepts.PdpGroup; import org.onap.policy.models.pdp.concepts.PdpStatistics; import org.onap.policy.models.pdp.concepts.PdpSubGroup; @@ -159,6 +160,11 @@ public class DummyBadProviderImpl implements PolicyModelsProvider { } @Override + public void updatePdp(@NonNull String pdpGroupName, @NonNull String pdpGroupVersion, + @NonNull String pdpSubGroup, @NonNull Pdp pdp) throws PfModelException { + } + + @Override public PdpGroup deletePdpGroup(@NonNull String name, @NonNull String verison) throws PfModelException { return null; } @@ -184,6 +190,12 @@ public class DummyBadProviderImpl implements PolicyModelsProvider { } @Override + public ToscaServiceTemplate getPolicies4PolicyType(@NonNull String policyTypeName, String policyTypeVersion) + throws PfModelException { + return null; + } + + @Override public List<ToscaPolicy> getPolicyList4PolicyType(@NonNull String policyTypeName, final String policyTypeVersion) throws PfModelException { return null; diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/authorative/provider/AuthorativeToscaProvider.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/authorative/provider/AuthorativeToscaProvider.java index d0127d65f..2b6c25e7a 100644 --- a/models-tosca/src/main/java/org/onap/policy/models/tosca/authorative/provider/AuthorativeToscaProvider.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/authorative/provider/AuthorativeToscaProvider.java @@ -179,6 +179,21 @@ public class AuthorativeToscaProvider { * @return the policies found * @throws PfModelException on errors getting policies */ + public ToscaServiceTemplate getPolicies4PolicyType(@NonNull final PfDao dao, @NonNull final String policyTypeName, + final String policyTypeVersion) throws PfModelException { + return null; + } + + /** + * Get policies for a policy type name. + * + * @param dao the DAO to use to access the database + * @param policyTypeName the name of the policy type for which to get policies + * @param policyTypeVersion the version of the policy type, null returns all versions of deployed policies for + * policy types + * @return the policies found + * @throws PfModelException on errors getting policies + */ public List<ToscaPolicy> getPolicyList4PolicyType(@NonNull final PfDao dao, @NonNull final String policyTypeName, final String policyTypeVersion) throws PfModelException { return new ArrayList<>(); |