Merge "Add classes for PDP "simple" REST APIs"
[policy/models.git] / models-dao / src / main / java / org / onap / policy / models / dao / impl / DefaultPfDao.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019 Nordix Foundation.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.models.dao.impl;
22
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.List;
26
27 import javax.persistence.EntityManager;
28 import javax.persistence.EntityManagerFactory;
29 import javax.persistence.Persistence;
30 import javax.ws.rs.core.Response;
31
32 import org.onap.policy.models.base.PfConcept;
33 import org.onap.policy.models.base.PfConceptKey;
34 import org.onap.policy.models.base.PfModelException;
35 import org.onap.policy.models.base.PfModelRuntimeException;
36 import org.onap.policy.models.base.PfReferenceKey;
37 import org.onap.policy.models.dao.DaoParameters;
38 import org.onap.policy.models.dao.PfDao;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 /**
43  * The Class DefaultPfDao is an JPA implementation of the {@link PfDao} class for Policy Framework
44  * concepts ({@link PfConcept}). It uses the default JPA implementation in the javax
45  * {@link Persistence} class.
46  */
47 public class DefaultPfDao implements PfDao {
48     private static final Logger LOGGER = LoggerFactory.getLogger(DefaultPfDao.class);
49
50     private static final String SELECT_C_FROM = "SELECT c FROM ";
51     private static final String AND_C_KEY_LOCAL_NAME = "' AND c.key.localName='";
52     private static final String AND_C_KEY_PARENT_KEY_VERSION = "' AND c.key.parentKeyVersion='";
53     private static final String C_WHERE_C_KEY_PARENT_KEY_NAME = " c WHERE c.key.parentKeyName='";
54     private static final String AND_C_KEY_VERSION = "' AND c.key.version='";
55     private static final String C_WHERE_C_KEY_NAME = " c WHERE c.key.name='";
56     private static final String DELETE_FROM = "DELETE FROM ";
57
58     // Entity manager for JPA
59     private EntityManagerFactory emf = null;
60
61     @Override
62     public void init(final DaoParameters daoParameters) throws PfModelException {
63         if (daoParameters == null || daoParameters.getPersistenceUnit() == null) {
64             LOGGER.error("Policy Framework persistence unit parameter not set");
65             throw new PfModelException(Response.Status.INTERNAL_SERVER_ERROR,
66                     "Policy Framework persistence unit parameter not set");
67         }
68
69         LOGGER.debug("Creating Policy Framework persistence unit \"{}\" . . .", daoParameters.getPersistenceUnit());
70         try {
71             emf = Persistence.createEntityManagerFactory(daoParameters.getPersistenceUnit(),
72                     daoParameters.getJdbcProperties());
73         } catch (final Exception ex) {
74             String errorMessage = "Creation of Policy Framework persistence unit \""
75                     + daoParameters.getPersistenceUnit() + "\" failed";
76             LOGGER.warn(errorMessage, ex);
77             throw new PfModelException(Response.Status.INTERNAL_SERVER_ERROR, errorMessage, ex);
78         }
79         LOGGER.debug("Created Policy Framework persistence unit \"{}\"", daoParameters.getPersistenceUnit());
80     }
81
82     /**
83      * Gets the entity manager for this DAO.
84      *
85      * @return the entity manager
86      */
87     protected final synchronized EntityManager getEntityManager() {
88         if (emf == null) {
89             LOGGER.warn("Policy Framework DAO has not been initialized");
90             throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR,
91                     "Policy Framework DAO has not been initialized");
92         }
93
94         return emf.createEntityManager();
95     }
96
97     @Override
98     public final void close() {
99         if (emf != null) {
100             emf.close();
101         }
102     }
103
104     @Override
105     public <T extends PfConcept> void create(final T obj) {
106         if (obj == null) {
107             return;
108         }
109         final EntityManager mg = getEntityManager();
110         try {
111             mg.getTransaction().begin();
112             mg.merge(obj);
113             mg.getTransaction().commit();
114         } finally {
115             mg.close();
116         }
117     }
118
119     @Override
120     public <T extends PfConcept> void delete(final T obj) {
121         if (obj == null) {
122             return;
123         }
124         final EntityManager mg = getEntityManager();
125         try {
126             mg.getTransaction().begin();
127             mg.remove(mg.contains(obj) ? obj : mg.merge(obj));
128             mg.getTransaction().commit();
129         } finally {
130             mg.close();
131         }
132     }
133
134     @Override
135     public <T extends PfConcept> void delete(final Class<T> someClass, final PfConceptKey key) {
136         if (key == null) {
137             return;
138         }
139         final EntityManager mg = getEntityManager();
140         try {
141             mg.getTransaction().begin();
142             mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME + key.getName()
143                     + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).executeUpdate();
144             mg.getTransaction().commit();
145         } finally {
146             mg.close();
147         }
148     }
149
150     @Override
151     public <T extends PfConcept> void delete(final Class<T> someClass, final PfReferenceKey key) {
152         if (key == null) {
153             return;
154         }
155         final EntityManager mg = getEntityManager();
156         try {
157             mg.getTransaction().begin();
158             mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME
159                     + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION + key.getParentKeyVersion()
160                     + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'", someClass).executeUpdate();
161             mg.getTransaction().commit();
162         } finally {
163             mg.close();
164         }
165     }
166
167     @Override
168     public <T extends PfConcept> void createCollection(final Collection<T> objs) {
169         if (objs == null || objs.isEmpty()) {
170             return;
171         }
172         final EntityManager mg = getEntityManager();
173         try {
174             mg.getTransaction().begin();
175             for (final T t : objs) {
176                 mg.merge(t);
177             }
178             mg.getTransaction().commit();
179         } finally {
180             mg.close();
181         }
182     }
183
184     @Override
185     public <T extends PfConcept> void deleteCollection(final Collection<T> objs) {
186         if (objs == null || objs.isEmpty()) {
187             return;
188         }
189         final EntityManager mg = getEntityManager();
190         try {
191             mg.getTransaction().begin();
192             for (final T t : objs) {
193                 mg.remove(mg.contains(t) ? t : mg.merge(t));
194             }
195             mg.getTransaction().commit();
196         } finally {
197             mg.close();
198         }
199     }
200
201     @Override
202     public <T extends PfConcept> int deleteByConceptKey(final Class<T> someClass, final Collection<PfConceptKey> keys) {
203         if (keys == null || keys.isEmpty()) {
204             return 0;
205         }
206         int deletedCount = 0;
207         final EntityManager mg = getEntityManager();
208         try {
209             mg.getTransaction().begin();
210             for (final PfConceptKey key : keys) {
211                 deletedCount += mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME
212                         + key.getName() + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).executeUpdate();
213             }
214             mg.getTransaction().commit();
215         } finally {
216             mg.close();
217         }
218         return deletedCount;
219     }
220
221     @Override
222     public <T extends PfConcept> int deleteByReferenceKey(final Class<T> someClass,
223             final Collection<PfReferenceKey> keys) {
224         if (keys == null || keys.isEmpty()) {
225             return 0;
226         }
227         int deletedCount = 0;
228         final EntityManager mg = getEntityManager();
229         try {
230             mg.getTransaction().begin();
231             for (final PfReferenceKey key : keys) {
232                 deletedCount +=
233                         mg.createQuery(
234                                 DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME
235                                         + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION
236                                         + key.getParentKeyVersion() + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'",
237                                 someClass).executeUpdate();
238             }
239             mg.getTransaction().commit();
240         } finally {
241             mg.close();
242         }
243         return deletedCount;
244     }
245
246     @Override
247     public <T extends PfConcept> void deleteAll(final Class<T> someClass) {
248         final EntityManager mg = getEntityManager();
249         try {
250             mg.getTransaction().begin();
251             mg.createQuery(DELETE_FROM + someClass.getSimpleName() + " c ", someClass).executeUpdate();
252             mg.getTransaction().commit();
253         } finally {
254             mg.close();
255         }
256     }
257
258     @Override
259     public <T extends PfConcept> T get(final Class<T> someClass, final PfConceptKey key) {
260         if (someClass == null) {
261             return null;
262         }
263         final EntityManager mg = getEntityManager();
264         try {
265             final T t = mg.find(someClass, key);
266             if (t != null) {
267                 // This clone is created to force the JPA DAO to recurse down through the object
268                 try {
269                     final T clonedT = someClass.newInstance();
270                     t.copyTo(clonedT);
271                     return clonedT;
272                 } catch (final Exception e) {
273                     LOGGER.warn("Could not clone object of class \"" + someClass.getCanonicalName() + "\"", e);
274                     return null;
275                 }
276             } else {
277                 return null;
278             }
279         } finally {
280             mg.close();
281         }
282     }
283
284     @Override
285     public <T extends PfConcept> T get(final Class<T> someClass, final PfReferenceKey key) {
286         if (someClass == null) {
287             return null;
288         }
289         final EntityManager mg = getEntityManager();
290         try {
291             final T t = mg.find(someClass, key);
292             if (t != null) {
293                 try {
294                     final T clonedT = someClass.newInstance();
295                     t.copyTo(clonedT);
296                     return clonedT;
297                 } catch (final Exception e) {
298                     LOGGER.warn("Could not clone object of class \"" + someClass.getCanonicalName() + "\"", e);
299                     return null;
300                 }
301             } else {
302                 return null;
303             }
304         } finally {
305             mg.close();
306         }
307     }
308
309     @Override
310     public <T extends PfConcept> List<T> getAll(final Class<T> someClass) {
311         if (someClass == null) {
312             return Collections.emptyList();
313         }
314         final EntityManager mg = getEntityManager();
315         try {
316             return mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + " c", someClass).getResultList();
317         } finally {
318             mg.close();
319         }
320     }
321
322     @Override
323     public <T extends PfConcept> List<T> getAll(final Class<T> someClass, final PfConceptKey parentKey) {
324         if (someClass == null) {
325             return Collections.emptyList();
326         }
327         final EntityManager mg = getEntityManager();
328         try {
329             return mg
330                     .createQuery(
331                             SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME
332                                     + parentKey.getName() + AND_C_KEY_PARENT_KEY_VERSION + parentKey.getVersion() + "'",
333                             someClass)
334                     .getResultList();
335         } finally {
336             mg.close();
337         }
338     }
339
340     @Override
341     public <T extends PfConcept> T getConcept(final Class<T> someClass, final PfConceptKey key) {
342         if (someClass == null || key == null) {
343             return null;
344         }
345         final EntityManager mg = getEntityManager();
346         List<T> ret;
347         try {
348             ret = mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME + key.getName()
349                     + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).getResultList();
350         } finally {
351             mg.close();
352         }
353         if (ret == null || ret.isEmpty()) {
354             return null;
355         }
356         if (ret.size() > 1) {
357             throw new IllegalArgumentException("More than one result was returned for search for " + someClass
358                     + " with key " + key.getId() + ": " + ret);
359         }
360         return ret.get(0);
361     }
362
363     @Override
364     public <T extends PfConcept> T getConcept(final Class<T> someClass, final PfReferenceKey key) {
365         if (someClass == null || key == null) {
366             return null;
367         }
368         final EntityManager mg = getEntityManager();
369         List<T> ret;
370         try {
371             ret = mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME
372                     + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION + key.getParentKeyVersion()
373                     + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'", someClass).getResultList();
374         } finally {
375             mg.close();
376         }
377         if (ret == null || ret.isEmpty()) {
378             return null;
379         }
380         if (ret.size() > 1) {
381             throw new IllegalArgumentException("More than one result was returned for search for " + someClass
382                     + " with key " + key.getId() + ": " + ret);
383         }
384         return ret.get(0);
385     }
386
387     @Override
388     public <T extends PfConcept> T update(final T obj) {
389         final EntityManager mg = getEntityManager();
390         T ret;
391         try {
392             mg.getTransaction().begin();
393             ret = mg.merge(obj);
394             mg.flush();
395             mg.getTransaction().commit();
396         } finally {
397             mg.close();
398         }
399         return ret;
400     }
401
402     @Override
403     public <T extends PfConcept> long size(final Class<T> someClass) {
404         if (someClass == null) {
405             return 0;
406         }
407         final EntityManager mg = getEntityManager();
408         long size = 0;
409         try {
410             size = mg.createQuery("SELECT COUNT(c) FROM " + someClass.getSimpleName() + " c", Long.class)
411                     .getSingleResult();
412         } finally {
413             mg.close();
414         }
415         return size;
416     }
417 }