2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019-2024 Nordix Foundation.
4 * Modifications Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved.
5 * Modifications Copyright (C) 2020, 2022 Bell Canada. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * SPDX-License-Identifier: Apache-2.0
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.models.provider.impl;
25 import static org.assertj.core.api.Assertions.assertThatCode;
26 import static org.assertj.core.api.Assertions.assertThatThrownBy;
27 import static org.junit.jupiter.api.Assertions.assertEquals;
28 import static org.junit.jupiter.api.Assertions.assertNotNull;
29 import static org.junit.jupiter.api.Assertions.assertTrue;
31 import java.util.ArrayList;
32 import java.util.List;
34 import org.junit.jupiter.api.AfterAll;
35 import org.junit.jupiter.api.BeforeAll;
36 import org.junit.jupiter.api.Test;
37 import org.onap.policy.models.base.PfModelException;
38 import org.onap.policy.models.pdp.concepts.Pdp;
39 import org.onap.policy.models.pdp.concepts.PdpGroup;
40 import org.onap.policy.models.pdp.concepts.PdpGroupFilter;
41 import org.onap.policy.models.pdp.concepts.PdpSubGroup;
42 import org.onap.policy.models.pdp.enums.PdpHealthStatus;
43 import org.onap.policy.models.pdp.enums.PdpState;
44 import org.onap.policy.models.provider.PolicyModelsProvider;
45 import org.onap.policy.models.provider.PolicyModelsProviderFactory;
46 import org.onap.policy.models.provider.PolicyModelsProviderParameters;
47 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
48 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifierOptVersion;
49 import org.onap.policy.models.tosca.authorative.concepts.ToscaEntityFilter;
50 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
51 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType;
52 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
53 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
54 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
55 import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate;
56 import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter;
59 * Test the database models provider implementation.
61 * @author Liam Fallon (liam.fallon@est.tech)
63 class DatabasePolicyModelsProviderTest {
64 private static final String NAME = "name";
66 private static final String TEMPLATE_IS_NULL = "^serviceTemplate is marked .*on.*ull but is null$";
68 private static final String SUBGROUP_IS_NULL = "^pdpSubGroup is marked .*on.*ull but is null$";
70 private static final String GROUP_IS_NULL = "^pdpGroupName is marked .*on.*ull but is null$";
72 private static final String NAME_IS_NULL = "^name is marked .*on.*ull but is null$";
74 private static final String FILTER_IS_NULL = "^filter is marked .*on.*ull but is null$";
76 private static final String GROUP = "group";
78 private static final String VERSION_100 = "1.0.0";
80 private static PolicyModelsProviderParameters parameters;
82 private static PolicyModelsProvider databaseProvider;
85 * Initialize parameters.
88 public static void setupParameters() {
89 parameters = new PolicyModelsProviderParameters();
90 parameters.setDatabaseDriver("org.h2.Driver");
91 parameters.setDatabaseUrl("jdbc:h2:mem:DatabasePolicyModelsProviderTest");
92 parameters.setDatabaseUser("policy");
93 parameters.setDatabasePassword("P01icY");
94 parameters.setPersistenceUnit("ToscaConceptTest");
101 public static void tearDown() throws PfModelException {
102 if (databaseProvider != null) {
103 databaseProvider.close();
108 void testInitAndClose() throws Exception {
109 assertThatThrownBy(() -> {
110 new DatabasePolicyModelsProviderImpl(null);
111 }).hasMessageMatching("^parameters is marked .*on.*ull but is null$");
113 databaseProvider = new PolicyModelsProviderFactory().createPolicyModelsProvider(parameters);
115 final String savedDatabaseUrl = parameters.getDatabaseUrl();
116 parameters.setDatabaseUrl("jdbc://www.acmecorp.nonexist");
118 databaseProvider.close();
119 assertThatThrownBy(() -> {
120 databaseProvider.init();
121 }).hasMessageContaining("could not create Data Access Object (DAO)");
123 databaseProvider.close();
125 parameters.setDatabaseUrl(savedDatabaseUrl);
127 final String savedPersistenceUnit = parameters.getPersistenceUnit();
128 parameters.setPersistenceUnit("WileECoyote");
130 assertThatThrownBy(databaseProvider::init).hasMessageContaining("could not create Data Access Object (DAO)");
131 parameters.setPersistenceUnit(savedPersistenceUnit);
133 databaseProvider.init();
134 databaseProvider.close();
136 assertThatThrownBy(() -> {
137 databaseProvider.init();
138 databaseProvider.init();
139 }).hasMessage("provider is already initialized");
141 databaseProvider.close();
143 databaseProvider.close();
147 void testProviderMethodsNull() throws Exception {
149 databaseProvider = new PolicyModelsProviderFactory().createPolicyModelsProvider(parameters);
151 assertThatThrownBy(() -> {
152 databaseProvider.getFilteredPolicyTypes(null);
153 }).hasMessageMatching(FILTER_IS_NULL);
155 assertThatThrownBy(() -> {
156 databaseProvider.getFilteredPolicyTypeList(null);
157 }).hasMessageMatching(FILTER_IS_NULL);
159 assertThatThrownBy(() -> {
160 databaseProvider.createPolicyTypes(null);
161 }).hasMessageMatching(TEMPLATE_IS_NULL);
163 assertThatThrownBy(() -> {
164 databaseProvider.updatePolicyTypes(null);
165 }).hasMessageMatching(TEMPLATE_IS_NULL);
167 assertThatThrownBy(() -> {
168 databaseProvider.deletePolicyType(null, null);
169 }).hasMessageMatching(NAME_IS_NULL);
171 assertThatThrownBy(() -> {
172 databaseProvider.deletePolicyType("aaa", null);
173 }).hasMessageMatching("^version is marked .*on.*ull but is null$");
175 assertThatThrownBy(() -> {
176 databaseProvider.deletePolicyType(null, "aaa");
177 }).hasMessageMatching(NAME_IS_NULL);
179 assertThatThrownBy(() -> {
180 databaseProvider.getFilteredPolicies(null);
181 }).hasMessageMatching(FILTER_IS_NULL);
183 assertThatThrownBy(() -> {
184 databaseProvider.getFilteredPolicyList(null);
185 }).hasMessageMatching(FILTER_IS_NULL);
187 assertThatThrownBy(() -> {
188 databaseProvider.createPolicies(null);
189 }).hasMessageMatching(TEMPLATE_IS_NULL);
191 assertThatThrownBy(() -> {
192 databaseProvider.updatePolicies(null);
193 }).hasMessageMatching(TEMPLATE_IS_NULL);
195 assertThatThrownBy(() -> {
196 databaseProvider.deletePolicy(null, null);
197 }).hasMessageMatching(NAME_IS_NULL);
199 assertThatThrownBy(() -> {
200 databaseProvider.deletePolicy(null, "aaa");
201 }).hasMessageMatching(NAME_IS_NULL);
203 assertThatThrownBy(() -> {
204 databaseProvider.deletePolicy("aaa", null);
205 }).hasMessageMatching("^version is marked .*on.*ull but is null$");
209 void testProviderMethodsNullGroup() throws Exception {
211 databaseProvider = new PolicyModelsProviderFactory().createPolicyModelsProvider(parameters);
213 assertThatThrownBy(() -> {
214 databaseProvider.getFilteredPdpGroups(null);
215 }).hasMessageMatching(FILTER_IS_NULL);
217 assertThatThrownBy(() -> {
218 databaseProvider.createPdpGroups(null);
219 }).hasMessageMatching("^pdpGroups is marked .*on.*ull but is null$");
221 assertThatThrownBy(() -> {
222 databaseProvider.updatePdpGroups(null);
223 }).hasMessageMatching("^pdpGroups is marked .*on.*ull but is null$");
225 assertThatThrownBy(() -> {
226 databaseProvider.updatePdpSubGroup(null, null);
227 }).hasMessageMatching(GROUP_IS_NULL);
229 assertThatThrownBy(() -> {
230 databaseProvider.updatePdpSubGroup(null, new PdpSubGroup());
231 }).hasMessageMatching(GROUP_IS_NULL);
233 assertThatThrownBy(() -> {
234 databaseProvider.updatePdpSubGroup(NAME, null);
235 }).hasMessageMatching(SUBGROUP_IS_NULL);
237 assertThatThrownBy(() -> {
238 databaseProvider.updatePdpSubGroup(NAME, new PdpSubGroup());
239 }).hasMessage("parameter \"localName\" is null");
241 assertThatThrownBy(() -> {
242 databaseProvider.updatePdp(null, null, null);
243 }).hasMessageMatching(GROUP_IS_NULL);
245 assertThatThrownBy(() -> {
246 databaseProvider.updatePdp(null, null, new Pdp());
247 }).hasMessageMatching(GROUP_IS_NULL);
249 assertThatThrownBy(() -> {
250 databaseProvider.updatePdp(null, "sub", null);
251 }).hasMessageMatching(GROUP_IS_NULL);
253 assertThatThrownBy(() -> {
254 databaseProvider.updatePdp(null, "sub", new Pdp());
255 }).hasMessageMatching(GROUP_IS_NULL);
257 assertThatThrownBy(() -> {
258 databaseProvider.updatePdp(NAME, null, null);
259 }).hasMessageMatching(SUBGROUP_IS_NULL);
261 assertThatThrownBy(() -> {
262 databaseProvider.updatePdp(NAME, null, new Pdp());
263 }).hasMessageMatching(SUBGROUP_IS_NULL);
265 assertThatThrownBy(() -> {
266 databaseProvider.updatePdp(NAME, "sub", null);
267 }).hasMessageMatching("^pdp is marked .*on.*ull but is null$");
269 assertThatThrownBy(() -> {
270 databaseProvider.updatePdp(NAME, "sub", new Pdp());
271 }).hasMessage("parameter \"localName\" is null");
273 assertThatThrownBy(() -> {
274 databaseProvider.deletePdpGroup(null);
275 }).hasMessageMatching(NAME_IS_NULL);
277 databaseProvider.close();
281 void testProviderMethodsNotInit() throws Exception {
282 databaseProvider = new PolicyModelsProviderFactory().createPolicyModelsProvider(parameters);
284 databaseProvider.close();
286 assertThatThrownBy(() -> {
287 databaseProvider.getPolicyTypes(NAME, "version");
288 }).hasMessage("policy models provider is not initilaized");
292 void testProviderMethods() throws PfModelException {
293 databaseProvider = new PolicyModelsProviderFactory().createPolicyModelsProvider(parameters);
295 assertThatThrownBy(() -> databaseProvider.getPolicyTypes(NAME, VERSION_100))
296 .hasMessage("service template not found in database");
298 assertTrue(databaseProvider.getPolicyTypeList(NAME, VERSION_100).isEmpty());
301 () -> databaseProvider.getFilteredPolicyTypes(ToscaEntityFilter.<ToscaPolicyType>builder().build()))
302 .hasMessage("service template not found in database");
304 assertTrue(databaseProvider.getFilteredPolicyTypeList(ToscaEntityFilter.<ToscaPolicyType>builder().build())
307 assertThatThrownBy(() -> {
308 databaseProvider.createPolicyTypes(new ToscaServiceTemplate());
309 }).hasMessage("no policy types specified on service template");
311 assertThatThrownBy(() -> {
312 databaseProvider.updatePolicyTypes(new ToscaServiceTemplate());
313 }).hasMessage("no policy types specified on service template");
315 assertThatThrownBy(() -> databaseProvider.deletePolicyType(NAME, VERSION_100))
316 .hasMessage("service template not found in database");
318 assertThatThrownBy(() -> databaseProvider.getPolicies(NAME, VERSION_100))
319 .hasMessage("service template not found in database");
321 assertTrue(databaseProvider.getPolicyList(NAME, VERSION_100).isEmpty());
324 () -> databaseProvider.getFilteredPolicies(ToscaTypedEntityFilter.<ToscaPolicy>builder().build()))
325 .hasMessage("service template not found in database");
327 assertTrue(databaseProvider.getFilteredPolicyList(ToscaTypedEntityFilter.<ToscaPolicy>builder().build())
330 assertThatThrownBy(() -> {
331 databaseProvider.createPolicies(new ToscaServiceTemplate());
332 }).hasMessage("topology template not specified on service template");
334 assertThatThrownBy(() -> {
335 databaseProvider.updatePolicies(new ToscaServiceTemplate());
336 }).hasMessage("topology template not specified on service template");
338 assertThatThrownBy(() -> databaseProvider.deletePolicy("Policy", "0.0.0").getToscaTopologyTemplate())
339 .hasMessage("service template not found in database");
341 assertEquals(0, databaseProvider.getPdpGroups(NAME).size());
342 assertEquals(0, databaseProvider.getFilteredPdpGroups(PdpGroupFilter.builder().build()).size());
344 assertNotNull(databaseProvider.createPdpGroups(new ArrayList<>()));
345 assertNotNull(databaseProvider.updatePdpGroups(new ArrayList<>()));
349 void testProviderMethodsInGroups() throws PfModelException {
350 PdpGroup pdpGroup = new PdpGroup();
351 pdpGroup.setName(GROUP);
352 pdpGroup.setVersion("1.2.3");
353 pdpGroup.setPdpGroupState(PdpState.ACTIVE);
354 pdpGroup.setPdpSubgroups(new ArrayList<>());
355 List<PdpGroup> groupList = new ArrayList<>();
356 groupList.add(pdpGroup);
358 PdpSubGroup pdpSubGroup = new PdpSubGroup();
359 pdpSubGroup.setPdpType("type");
360 pdpSubGroup.setDesiredInstanceCount(123);
361 pdpSubGroup.setSupportedPolicyTypes(new ArrayList<>());
362 pdpSubGroup.getSupportedPolicyTypes().add(new ToscaConceptIdentifier("type", "7.8.9"));
363 pdpGroup.getPdpSubgroups().add(pdpSubGroup);
366 pdp.setInstanceId("type-0");
367 pdp.setMessage("Hello");
368 pdp.setPdpState(PdpState.ACTIVE);
369 pdp.setHealthy(PdpHealthStatus.UNKNOWN);
370 pdpSubGroup.setPdpInstances(new ArrayList<>());
371 pdpSubGroup.getPdpInstances().add(pdp);
373 databaseProvider = new PolicyModelsProviderFactory().createPolicyModelsProvider(parameters);
376 databaseProvider.createPdpGroups(groupList).get(0).getPdpSubgroups().get(0).getDesiredInstanceCount());
377 assertEquals(1, databaseProvider.getPdpGroups(GROUP).size());
379 pdpSubGroup.setDesiredInstanceCount(234);
380 databaseProvider.updatePdpSubGroup(GROUP, pdpSubGroup);
382 databaseProvider.getPdpGroups(GROUP).get(0).getPdpSubgroups().get(0).getDesiredInstanceCount());
384 assertEquals("Hello", databaseProvider.getPdpGroups(GROUP).get(0).getPdpSubgroups().get(0).getPdpInstances()
385 .get(0).getMessage());
386 pdp.setMessage("Howdy");
387 databaseProvider.updatePdp(GROUP, "type", pdp);
388 assertEquals("Howdy", databaseProvider.getPdpGroups(GROUP).get(0).getPdpSubgroups().get(0).getPdpInstances()
389 .get(0).getMessage());
391 assertThatThrownBy(() -> {
392 databaseProvider.deletePdpGroup(NAME);
393 }).hasMessage("delete of PDP group \"name:0.0.0\" failed, PDP group does not exist");
395 assertEquals(pdpGroup.getName(), databaseProvider.deletePdpGroup(GROUP).getName());
399 void testDeletePolicyDeployedInSubgroup() throws PfModelException {
400 List<ToscaConceptIdentifier> policies = new ArrayList<>();
402 policies.add(new ToscaConceptIdentifier("p0", "0.0.1"));
403 policies.add(new ToscaConceptIdentifier("p1", "0.0.1"));
405 List<ToscaConceptIdentifier> supportedPolicyTypes = new ArrayList<>();
406 supportedPolicyTypes.add(new ToscaConceptIdentifier("pt2", "0.0.1"));
408 PdpSubGroup subGroup = new PdpSubGroup();
409 subGroup.setPdpType("pdpType");
410 subGroup.setSupportedPolicyTypes(supportedPolicyTypes);
411 subGroup.setPolicies(policies);
413 List<PdpSubGroup> pdpSubgroups = new ArrayList<>();
414 pdpSubgroups.add(subGroup);
416 PdpGroup pdpGroup = new PdpGroup();
417 pdpGroup.setName("pdpGroup");
418 pdpGroup.setPdpGroupState(PdpState.PASSIVE);
419 pdpGroup.setPdpSubgroups(pdpSubgroups);
421 List<PdpGroup> pdpGroups = new ArrayList<>();
422 pdpGroups.add(pdpGroup);
424 databaseProvider = new PolicyModelsProviderFactory().createPolicyModelsProvider(parameters);
426 databaseProvider.createPdpGroups(pdpGroups);
428 assertThatThrownBy(() -> databaseProvider.deletePolicy("p0", "0.0.1"))
429 .hasMessageContaining("policy is in use, it is deployed in PDP group pdpGroup subgroup pdpType");
431 assertThatThrownBy(() -> databaseProvider.deletePolicy("p3", "0.0.1"))
432 .hasMessageContaining("service template not found in database");
434 databaseProvider.close();
438 void testDeletePolicyTypeSupportedInSubgroup() throws PfModelException {
439 List<ToscaConceptIdentifier> supportedPolicyTypes = new ArrayList<>();
440 supportedPolicyTypes.add(new ToscaConceptIdentifier("pt1", "0.0.1"));
441 supportedPolicyTypes.add(new ToscaConceptIdentifier("pt2", "0.0.1"));
443 PdpSubGroup subGroup = new PdpSubGroup();
444 subGroup.setPdpType("pdpType");
445 subGroup.setSupportedPolicyTypes(supportedPolicyTypes);
447 List<PdpSubGroup> pdpSubgroups = new ArrayList<>();
448 pdpSubgroups.add(subGroup);
450 PdpGroup pdpGroup = new PdpGroup();
451 pdpGroup.setName("pdpGroup");
452 pdpGroup.setPdpGroupState(PdpState.PASSIVE);
453 pdpGroup.setPdpSubgroups(pdpSubgroups);
455 List<PdpGroup> pdpGroups = new ArrayList<>();
456 pdpGroups.add(pdpGroup);
458 databaseProvider = new PolicyModelsProviderFactory().createPolicyModelsProvider(parameters);
460 databaseProvider.createPdpGroups(pdpGroups);
462 assertThatThrownBy(() -> databaseProvider.deletePolicyType("pt2", "0.0.1"))
463 .hasMessageContaining("policy type is in use, it is referenced in PDP group pdpGroup subgroup pdpType");
465 assertThatThrownBy(() -> databaseProvider.deletePolicyType("pt0", "0.0.1"))
466 .hasMessageContaining("service template not found in database");
468 databaseProvider.close();
472 void testToscaNodeTemplateHandling() throws PfModelException {
473 databaseProvider = new PolicyModelsProviderFactory().createPolicyModelsProvider(parameters);
475 ToscaServiceTemplate serviceTemplate = makeNodeTemplate();
477 assertEquals("1.0.1",
478 databaseProvider.createToscaNodeTemplates(serviceTemplate).getToscaTopologyTemplate().getNodeTemplates()
479 .get("metadataSet1").getVersion());
480 assertEquals(1, databaseProvider.getNodeTemplateMetadataSets(null, null).size());
482 ToscaNodeTemplate nodeTemplate1 = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates()
483 .get("metadataSet1");
484 nodeTemplate1.setMetadata(Map.of("dummyKey", "updatedValue"));
485 serviceTemplate.getToscaTopologyTemplate().setNodeTemplates(Map.of("metadataSet1:1.0.1", nodeTemplate1));
486 assertEquals("updatedValue", databaseProvider.updateToscaNodeTemplates(serviceTemplate)
487 .getToscaTopologyTemplate().getNodeTemplates().get("metadataSet1").getMetadata().get("dummyKey"));
489 assertThatThrownBy(() -> {
490 databaseProvider.deleteToscaNodeTemplate("invalidName", "1.0.1");
491 }).hasMessage("node template invalidName:1.0.1 not found");
493 assertThatCode(() -> databaseProvider.getServiceTemplateList(NAME, VERSION_100))
494 .doesNotThrowAnyException();
496 assertThatCode(() -> databaseProvider.getFilteredServiceTemplateList(ToscaEntityFilter
497 .<ToscaServiceTemplate>builder().build()))
498 .doesNotThrowAnyException();
504 void testToscaTemplateMethods() throws PfModelException {
505 databaseProvider = new PolicyModelsProviderFactory().createPolicyModelsProvider(parameters);
507 assertThatThrownBy(() -> databaseProvider.createServiceTemplate(new ToscaServiceTemplate()))
508 .hasMessageContaining("\"service template\" INVALID");
510 assertThatThrownBy(() -> databaseProvider.updateServiceTemplate(new ToscaServiceTemplate()))
511 .hasMessageContaining("\"service template\" INVALID");
513 assertThatThrownBy(() -> databaseProvider.deleteServiceTemplate(NAME, VERSION_100))
514 .hasMessageContaining("service template not found in database");
516 assertThatThrownBy(() -> databaseProvider.getToscaNodeTemplate(NAME, VERSION_100))
517 .hasMessageContaining("service template not found in database");
519 assertNotNull(databaseProvider.getAllPolicyStatus());
521 assertNotNull(databaseProvider.getAllPolicyStatus(new ToscaConceptIdentifierOptVersion()));
523 assertNotNull(databaseProvider.getGroupPolicyStatus("testGroup"));
525 ToscaServiceTemplate serviceTemplate = makeNodeTemplate();
526 databaseProvider.createToscaNodeTemplates(serviceTemplate);
528 assertThatCode(() -> databaseProvider.createServiceTemplate(new ToscaServiceTemplate()))
529 .doesNotThrowAnyException();
530 assertThatCode(() -> databaseProvider.getToscaNodeTemplate(serviceTemplate.getName(),
531 serviceTemplate.getVersion())).doesNotThrowAnyException();
533 assertThatCode(() -> databaseProvider.updateServiceTemplate(new ToscaServiceTemplate()))
534 .doesNotThrowAnyException();
535 assertThatCode(() -> databaseProvider.deleteServiceTemplate(serviceTemplate.getName(),
536 serviceTemplate.getVersion())).doesNotThrowAnyException();
540 databaseProvider.close();
543 private ToscaServiceTemplate makeNodeTemplate() {
544 ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
545 serviceTemplate.setToscaDefinitionsVersion("sample:1.1.0");
546 serviceTemplate.setToscaTopologyTemplate(new ToscaTopologyTemplate());
547 serviceTemplate.setNodeTypes(Map.of("org.onap.policy.metadataSet:1.0.0", new ToscaNodeType()));
548 ToscaNodeTemplate nodeTemplate1 = new ToscaNodeTemplate();
549 nodeTemplate1.setName("metadataSet1");
550 nodeTemplate1.setVersion("1.0.1");
551 nodeTemplate1.setType("org.onap.policy.metadataSet");
552 nodeTemplate1.setTypeVersion("1.0.0");
553 nodeTemplate1.setMetadata(Map.of("dummyKey", "dummyValue"));
555 serviceTemplate.getToscaTopologyTemplate().setNodeTemplates(Map.of("metadataSet1", nodeTemplate1));
557 return serviceTemplate;