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