Fix return building on policy get
[policy/models.git] / models-tosca / src / main / java / org / onap / policy / models / tosca / simple / provider / SimpleToscaProvider.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019-2020 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.tosca.simple.provider;
22
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.List;
26
27 import javax.ws.rs.core.Response;
28
29 import lombok.NonNull;
30
31 import org.apache.commons.collections4.CollectionUtils;
32 import org.onap.policy.models.base.PfConcept;
33 import org.onap.policy.models.base.PfConceptFilter;
34 import org.onap.policy.models.base.PfConceptKey;
35 import org.onap.policy.models.base.PfKey;
36 import org.onap.policy.models.base.PfModelException;
37 import org.onap.policy.models.base.PfModelRuntimeException;
38 import org.onap.policy.models.base.PfValidationResult;
39 import org.onap.policy.models.dao.PfDao;
40 import org.onap.policy.models.tosca.simple.concepts.JpaToscaDataType;
41 import org.onap.policy.models.tosca.simple.concepts.JpaToscaDataTypes;
42 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicies;
43 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicy;
44 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyType;
45 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyTypes;
46 import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;
47 import org.onap.policy.models.tosca.utils.ToscaServiceTemplateUtils;
48 import org.onap.policy.models.tosca.utils.ToscaUtils;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 /**
53  * This class provides the provision of information on TOSCA concepts in the database to callers.
54  *
55  * @author Liam Fallon (liam.fallon@est.tech)
56  */
57 public class SimpleToscaProvider {
58     private static final Logger LOGGER = LoggerFactory.getLogger(SimpleToscaProvider.class);
59
60     // Recurring string constants
61     private static final String SERVICE_TEMPLATE_NOT_FOUND_IN_DATABASE = "service template not found in database";
62     private static final String DO_NOT_EXIST = " do not exist";
63
64     /**
65      * Get Service Template.
66      *
67      * @param dao the DAO to use to access the database
68      * @return the service template
69      * @throws PfModelException on errors getting the service template
70      */
71     public JpaToscaServiceTemplate getServiceTemplate(@NonNull final PfDao dao) throws PfModelException {
72         LOGGER.debug("->getServiceTemplate");
73
74         JpaToscaServiceTemplate serviceTemplate = new SimpleToscaServiceTemplateProvider().read(dao);
75         if (serviceTemplate == null) {
76             throw new PfModelRuntimeException(Response.Status.NOT_FOUND, SERVICE_TEMPLATE_NOT_FOUND_IN_DATABASE);
77         }
78
79         LOGGER.debug("<-getServiceTemplate: serviceTemplate={}", serviceTemplate);
80         return serviceTemplate;
81     }
82
83     /**
84      * Append a service template fragment to the service template in the database.
85      *
86      * @param dao the DAO to use to access the database
87      * @param incomingServiceTemplateFragment the service template containing the definition of the entities to be
88      *        created
89      * @return the TOSCA service template in the database after the operation
90      * @throws PfModelException on errors appending a service template to the template in the database
91      */
92     public JpaToscaServiceTemplate appendToServiceTemplate(@NonNull final PfDao dao,
93             @NonNull final JpaToscaServiceTemplate incomingServiceTemplateFragment) throws PfModelException {
94         LOGGER.debug("->appendServiceTemplateFragment: incomingServiceTemplateFragment={}",
95                 incomingServiceTemplateFragment);
96
97         JpaToscaServiceTemplate dbServiceTemplate = new SimpleToscaServiceTemplateProvider().read(dao);
98
99         JpaToscaServiceTemplate serviceTemplateToWrite;
100         if (dbServiceTemplate == null) {
101             serviceTemplateToWrite = incomingServiceTemplateFragment;
102         } else {
103             serviceTemplateToWrite =
104                     ToscaServiceTemplateUtils.addFragment(dbServiceTemplate, incomingServiceTemplateFragment);
105         }
106
107         PfValidationResult result = serviceTemplateToWrite.validate(new PfValidationResult());
108         if (!result.isValid()) {
109             throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, result.toString());
110         }
111
112         new SimpleToscaServiceTemplateProvider().write(dao, serviceTemplateToWrite);
113
114         LOGGER.debug("<-appendServiceTemplateFragment: returnServiceTempalate={}", serviceTemplateToWrite);
115         return serviceTemplateToWrite;
116     }
117
118     /**
119      * Get data types.
120      *
121      * @param dao the DAO to use to access the database
122      * @param name the name of the data type to get, set to null to get all policy types
123      * @param version the version of the data type to get, set to null to get all versions
124      * @return the data types found
125      * @throws PfModelException on errors getting data types
126      */
127     public JpaToscaServiceTemplate getDataTypes(@NonNull final PfDao dao, final String name, final String version)
128             throws PfModelException {
129         LOGGER.debug("->getDataTypes: name={}, version={}", name, version);
130
131         JpaToscaServiceTemplate serviceTemplate = getServiceTemplate(dao);
132
133         if (!ToscaUtils.doDataTypesExist(serviceTemplate)) {
134             throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
135                     "data types for " + name + ":" + version + DO_NOT_EXIST);
136         }
137
138         serviceTemplate.setPolicyTypes(null);
139         serviceTemplate.setTopologyTemplate(null);
140
141         ToscaUtils.getEntityTree(serviceTemplate.getDataTypes(), name, version);
142
143         if (!ToscaUtils.doDataTypesExist(serviceTemplate)) {
144             throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
145                     "data types for " + name + ":" + version + DO_NOT_EXIST);
146         }
147
148         for (JpaToscaDataType dataType : serviceTemplate.getDataTypes().getConceptMap().values()) {
149             Collection<PfConceptKey> referencedDataTypeKeys = dataType.getReferencedDataTypes();
150
151             for (PfConceptKey referencedDataTypeKey : referencedDataTypeKeys) {
152                 JpaToscaServiceTemplate dataTypeEntityTreeServiceTemplate =
153                         getDataTypes(dao, referencedDataTypeKey.getName(), referencedDataTypeKey.getVersion());
154
155                 serviceTemplate =
156                         ToscaServiceTemplateUtils.addFragment(serviceTemplate, dataTypeEntityTreeServiceTemplate);
157             }
158         }
159
160         LOGGER.debug("<-getDataTypes: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
161         return serviceTemplate;
162     }
163
164     /**
165      * Create data types.
166      *
167      * @param dao the DAO to use to access the database
168      * @param incomingServiceTemplate the service template containing the definition of the data types to be created
169      * @return the TOSCA service template containing the created data types
170      * @throws PfModelException on errors creating data types
171      */
172     public JpaToscaServiceTemplate createDataTypes(@NonNull final PfDao dao,
173             @NonNull final JpaToscaServiceTemplate incomingServiceTemplate) throws PfModelException {
174         LOGGER.debug("->createDataTypes: incomingServiceTemplate={}", incomingServiceTemplate);
175
176         ToscaUtils.assertDataTypesExist(incomingServiceTemplate);
177
178         JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, incomingServiceTemplate);
179
180         LOGGER.debug("<-createDataTypes: returnServiceTempalate={}", writtenServiceTemplate);
181         return writtenServiceTemplate;
182     }
183
184     /**
185      * Update Data types.
186      *
187      * @param dao the DAO to use to access the database
188      * @param serviceTemplate the service template containing the definition of the data types to be modified
189      * @return the TOSCA service template containing the modified data types
190      * @throws PfModelException on errors updating Data types
191      */
192     public JpaToscaServiceTemplate updateDataTypes(@NonNull final PfDao dao,
193             @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
194         LOGGER.debug("->updateDataTypes: serviceTempalate={}", serviceTemplate);
195
196         ToscaUtils.assertDataTypesExist(serviceTemplate);
197
198         for (JpaToscaDataType dataType : serviceTemplate.getDataTypes().getAll(null)) {
199             dao.update(dataType);
200         }
201
202         // Return the created data types
203         JpaToscaDataTypes returnDataTypes = new JpaToscaDataTypes();
204
205         for (PfConceptKey dataTypeKey : serviceTemplate.getDataTypes().getConceptMap().keySet()) {
206             returnDataTypes.getConceptMap().put(dataTypeKey, dao.get(JpaToscaDataType.class, dataTypeKey));
207         }
208
209         JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
210         returnServiceTemplate.setDataTypes(returnDataTypes);
211
212         LOGGER.debug("<-updateDataTypes: returnServiceTempalate={}", returnServiceTemplate);
213         return returnServiceTemplate;
214     }
215
216     /**
217      * Delete Data types.
218      *
219      * @param dao the DAO to use to access the database
220      * @param dataTypeKey the data type key for the Data types to be deleted, if the version of the key is null, all
221      *        versions of the data type are deleted.
222      * @return the TOSCA service template containing the data types that were deleted
223      * @throws PfModelException on errors deleting data types
224      */
225     public JpaToscaServiceTemplate deleteDataType(@NonNull final PfDao dao, @NonNull final PfConceptKey dataTypeKey)
226             throws PfModelException {
227         LOGGER.debug("->deleteDataType: key={}", dataTypeKey);
228
229         JpaToscaServiceTemplate serviceTemplate = getDataTypes(dao, dataTypeKey.getName(), dataTypeKey.getVersion());
230
231         dao.delete(JpaToscaDataType.class, dataTypeKey);
232
233         LOGGER.debug("<-deleteDataType: key={}, serviceTempalate={}", dataTypeKey, serviceTemplate);
234         return serviceTemplate;
235     }
236
237     /**
238      * Get policy types.
239      *
240      * @param dao the DAO to use to access the database
241      * @param name the name of the policy type to get, set to null to get all policy types
242      * @param version the version of the policy type to get, set to null to get all versions
243      * @return the policy types found
244      * @throws PfModelException on errors getting policy types
245      */
246     public JpaToscaServiceTemplate getPolicyTypes(@NonNull final PfDao dao, final String name, final String version)
247             throws PfModelException {
248         LOGGER.debug("->getPolicyTypes: name={}, version={}", name, version);
249
250         JpaToscaServiceTemplate serviceTemplate = getServiceTemplate(dao);
251
252         serviceTemplate.setDataTypes(null);
253         serviceTemplate.setTopologyTemplate(null);
254
255         if (!ToscaUtils.doPolicyTypesExist(serviceTemplate)) {
256             throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
257                     "policy types for " + name + ":" + version + DO_NOT_EXIST);
258         }
259
260         ToscaUtils.getEntityTree(serviceTemplate.getPolicyTypes(), name, version);
261
262         if (!ToscaUtils.doPolicyTypesExist(serviceTemplate)) {
263             throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
264                     "policy types for " + name + ":" + version + DO_NOT_EXIST);
265         }
266
267         JpaToscaServiceTemplate dataTypeServiceTemplate = new JpaToscaServiceTemplate(serviceTemplate);
268         dataTypeServiceTemplate.setPolicyTypes(null);
269
270         for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getConceptMap().values()) {
271             Collection<PfConceptKey> referencedDataTypeKeys = policyType.getReferencedDataTypes();
272
273             for (PfConceptKey referencedDataTypeKey : referencedDataTypeKeys) {
274                 JpaToscaServiceTemplate dataTypeEntityTreeServiceTemplate =
275                         getDataTypes(dao, referencedDataTypeKey.getName(), referencedDataTypeKey.getVersion());
276
277                 dataTypeServiceTemplate = ToscaServiceTemplateUtils.addFragment(dataTypeServiceTemplate,
278                         dataTypeEntityTreeServiceTemplate);
279             }
280         }
281
282         serviceTemplate = ToscaServiceTemplateUtils.addFragment(serviceTemplate, dataTypeServiceTemplate);
283
284         LOGGER.debug("<-getPolicyTypes: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
285         return serviceTemplate;
286     }
287
288     /**
289      * Create policy types.
290      *
291      * @param dao the DAO to use to access the database
292      * @param incomingServiceTemplate the service template containing the definition of the policy types to be created
293      * @return the TOSCA service template containing the created policy types
294      * @throws PfModelException on errors creating policy types
295      */
296     public JpaToscaServiceTemplate createPolicyTypes(@NonNull final PfDao dao,
297             @NonNull final JpaToscaServiceTemplate incomingServiceTemplate) throws PfModelException {
298         LOGGER.debug("->createPolicyTypes: serviceTempalate={}", incomingServiceTemplate);
299
300         ToscaUtils.assertPolicyTypesExist(incomingServiceTemplate);
301
302         JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, incomingServiceTemplate);
303
304         LOGGER.debug("<-createPolicyTypes: returnServiceTempalate={}", writtenServiceTemplate);
305         return writtenServiceTemplate;
306     }
307
308     /**
309      * Update policy types.
310      *
311      * @param dao the DAO to use to access the database
312      * @param serviceTemplate the service template containing the definition of the policy types to be modified
313      * @return the TOSCA service template containing the modified policy types
314      * @throws PfModelException on errors updating policy types
315      */
316     public JpaToscaServiceTemplate updatePolicyTypes(@NonNull final PfDao dao,
317             @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
318         LOGGER.debug("->updatePolicyTypes: serviceTempalate={}", serviceTemplate);
319
320         ToscaUtils.assertPolicyTypesExist(serviceTemplate);
321
322         // Update the data types on the policy type
323         if (ToscaUtils.doDataTypesExist(serviceTemplate)) {
324             updateDataTypes(dao, serviceTemplate);
325         }
326
327         for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
328             dao.update(policyType);
329         }
330
331         // Return the created policy types
332         JpaToscaPolicyTypes returnPolicyTypes = new JpaToscaPolicyTypes();
333
334         for (PfConceptKey policyTypeKey : serviceTemplate.getPolicyTypes().getConceptMap().keySet()) {
335             returnPolicyTypes.getConceptMap().put(policyTypeKey, dao.get(JpaToscaPolicyType.class, policyTypeKey));
336         }
337
338         JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
339         returnServiceTemplate.setPolicyTypes(returnPolicyTypes);
340
341         LOGGER.debug("<-updatePolicyTypes: returnServiceTempalate={}", returnServiceTemplate);
342         return returnServiceTemplate;
343     }
344
345     /**
346      * Delete policy types.
347      *
348      * @param dao the DAO to use to access the database
349      * @param policyTypeKey the policy type key for the policy types to be deleted, if the version of the key is null,
350      *        all versions of the policy type are deleted.
351      * @return the TOSCA service template containing the policy types that were deleted
352      * @throws PfModelException on errors deleting policy types
353      */
354     public JpaToscaServiceTemplate deletePolicyType(@NonNull final PfDao dao, @NonNull final PfConceptKey policyTypeKey)
355             throws PfModelException {
356         LOGGER.debug("->deletePolicyType: key={}", policyTypeKey);
357
358         JpaToscaServiceTemplate serviceTemplate =
359                 getPolicyTypes(dao, policyTypeKey.getName(), policyTypeKey.getVersion());
360
361         dao.delete(JpaToscaPolicyType.class, policyTypeKey);
362
363         LOGGER.debug("<-deletePolicyType: key={}, serviceTempalate={}", policyTypeKey, serviceTemplate);
364         return serviceTemplate;
365     }
366
367     /**
368      * Get policies.
369      *
370      * @param dao the DAO to use to access the database
371      * @param name the name of the policy to get, set to null to get all policy types
372      * @param version the version of the policy to get, set to null to get all versions
373      * @return the policies found
374      * @throws PfModelException on errors getting policies
375      */
376     public JpaToscaServiceTemplate getPolicies(@NonNull final PfDao dao, final String name, final String version)
377             throws PfModelException {
378         LOGGER.debug("->getPolicies: name={}, version={}", name, version);
379
380         JpaToscaServiceTemplate dbServiceTemplate = getServiceTemplate(dao);
381
382         JpaToscaServiceTemplate serviceTemplate = new JpaToscaServiceTemplate(dbServiceTemplate);
383         serviceTemplate.setDataTypes(new JpaToscaDataTypes());
384         serviceTemplate.setPolicyTypes(new JpaToscaPolicyTypes());
385
386         if (!ToscaUtils.doPoliciesExist(serviceTemplate)) {
387             throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
388                     "policies for " + name + ":" + version + DO_NOT_EXIST);
389         }
390
391         ToscaUtils.getEntityTree(serviceTemplate.getTopologyTemplate().getPolicies(), name, version);
392
393         if (!ToscaUtils.doPoliciesExist(serviceTemplate)) {
394             throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
395                     "policies for " + name + ":" + version + DO_NOT_EXIST);
396         }
397
398         JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate(serviceTemplate);
399         returnServiceTemplate.getTopologyTemplate().setPolicies(new JpaToscaPolicies());
400
401         for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().values()) {
402             JpaToscaServiceTemplate referencedEntitiesServiceTemplate =
403                     getPolicyTypes(dao, policy.getType().getName(), policy.getType().getVersion());
404
405             returnServiceTemplate.getTopologyTemplate().getPolicies().getConceptMap().put(policy.getKey(), policy);
406             returnServiceTemplate =
407                     ToscaServiceTemplateUtils.addFragment(returnServiceTemplate, referencedEntitiesServiceTemplate);
408         }
409
410         LOGGER.debug("<-getPolicies: name={}, version={}, serviceTemplate={}", name, version, returnServiceTemplate);
411         return returnServiceTemplate;
412     }
413
414     /**
415      * Create policies.
416      *
417      * @param dao the DAO to use to access the database
418      * @param incomingServiceTemplate the service template containing the definitions of the new policies to be created.
419      * @return the TOSCA service template containing the policy types that were created
420      * @throws PfModelException on errors creating policies
421      */
422     public JpaToscaServiceTemplate createPolicies(@NonNull final PfDao dao,
423             @NonNull final JpaToscaServiceTemplate incomingServiceTemplate) throws PfModelException {
424         LOGGER.debug("->createPolicies: incomingServiceTemplate={}", incomingServiceTemplate);
425
426         ToscaUtils.assertPoliciesExist(incomingServiceTemplate);
427
428         JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, incomingServiceTemplate);
429
430         LOGGER.debug("<-createPolicies: serviceTemplate={}", writtenServiceTemplate);
431         return writtenServiceTemplate;
432     }
433
434     /**
435      * Update policies.
436      *
437      * @param dao the DAO to use to access the database
438      * @param serviceTemplate the service template containing the definitions of the policies to be updated.
439      * @return the TOSCA service template containing the policies that were updated
440      * @throws PfModelException on errors updating policies
441      */
442     public JpaToscaServiceTemplate updatePolicies(@NonNull final PfDao dao,
443             @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
444         LOGGER.debug("->updatePolicies: serviceTempalate={}", serviceTemplate);
445
446         ToscaUtils.assertPoliciesExist(serviceTemplate);
447
448         for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getAll(null)) {
449             verifyPolicyTypeForPolicy(dao, policy);
450             dao.update(policy);
451         }
452
453         // Return the created policy types
454         JpaToscaPolicies returnPolicies = new JpaToscaPolicies();
455         returnPolicies.setKey(serviceTemplate.getTopologyTemplate().getPolicies().getKey());
456
457         for (PfConceptKey policyKey : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().keySet()) {
458             returnPolicies.getConceptMap().put(policyKey, dao.get(JpaToscaPolicy.class, policyKey));
459         }
460
461         serviceTemplate.getTopologyTemplate().setPolicies(returnPolicies);
462
463         LOGGER.debug("<-updatePolicies: serviceTemplate={}", serviceTemplate);
464         return serviceTemplate;
465     }
466
467     /**
468      * Delete policies.
469      *
470      * @param dao the DAO to use to access the database
471      * @param policyKey the policy key
472      * @return the TOSCA service template containing the policies that were deleted
473      * @throws PfModelException on errors deleting policies
474      */
475     public JpaToscaServiceTemplate deletePolicy(@NonNull final PfDao dao, @NonNull final PfConceptKey policyKey)
476             throws PfModelException {
477         LOGGER.debug("->deletePolicy: key={}", policyKey);
478
479         JpaToscaServiceTemplate serviceTemplate = getPolicies(dao, policyKey.getName(), policyKey.getVersion());
480
481         dao.delete(JpaToscaPolicy.class, policyKey);
482
483         LOGGER.debug("<-deletePolicy: key={}, serviceTempalate={}", policyKey, serviceTemplate);
484         return serviceTemplate;
485     }
486
487     /**
488      * Verify the policy type for a policy exists.
489      *
490      * @param dao the DAO to use to access policy types in the database
491      * @param policy the policy to check the policy type for
492      */
493     private void verifyPolicyTypeForPolicy(final PfDao dao, final JpaToscaPolicy policy) {
494         PfConceptKey policyTypeKey = policy.getType();
495
496         JpaToscaPolicyType policyType = null;
497
498         if (PfKey.NULL_KEY_VERSION.equals(policyTypeKey.getVersion())) {
499             policyType = getLatestPolicyTypeVersion(dao, policyTypeKey.getName());
500
501             if (policyType != null) {
502                 policy.getType().setVersion(policyType.getKey().getVersion());
503             }
504         } else {
505             policyType = dao.get(JpaToscaPolicyType.class, policyTypeKey);
506         }
507
508         if (policyType == null) {
509             String errorMessage =
510                     "policy type " + policyTypeKey.getId() + " for policy " + policy.getId() + " does not exist";
511             throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, errorMessage);
512         }
513     }
514
515     /**
516      * Get the latest version of the policy type for the given policy type name.
517      *
518      * @param dao the DAO to use to access policy types in the database
519      * @param policyTypeName the name of the policy type
520      * @return the latest policy type
521      */
522     private JpaToscaPolicyType getLatestPolicyTypeVersion(final PfDao dao, final String policyTypeName) {
523         // Policy type version is not specified, get the latest version from the database
524         List<JpaToscaPolicyType> jpaPolicyTypeList = dao.getFiltered(JpaToscaPolicyType.class, policyTypeName, null);
525
526         if (CollectionUtils.isEmpty(jpaPolicyTypeList)) {
527             return null;
528         }
529
530         // Create a filter to get the latest version of the policy type
531         PfConceptFilter pfConceptFilter = PfConceptFilter.builder().version(PfConceptFilter.LATEST_VERSION).build();
532
533         // FIlter the returned policy type list
534         List<PfConcept> policyTypeKeyList = new ArrayList<>(jpaPolicyTypeList);
535         List<PfConcept> filterdPolicyTypeList = pfConceptFilter.filter(policyTypeKeyList);
536
537         // We should have one and only one returned entry
538         if (filterdPolicyTypeList.size() != 1) {
539             String errorMessage = "search for latest policy type " + policyTypeName + " returned more than one entry";
540             throw new PfModelRuntimeException(Response.Status.CONFLICT, errorMessage);
541         }
542
543         return (JpaToscaPolicyType) filterdPolicyTypeList.get(0);
544     }
545 }