diff --git a/src/main/java/org/etsi/osl/tmf/ram702/api/ResourceActivationApiRouteBuilder.java b/src/main/java/org/etsi/osl/tmf/ram702/api/ResourceActivationApiRouteBuilder.java index dd7dab5476c06be644092072afc2f8acc31c849a..75c44d9ba434c8b9a9d47b60ab87378385df9692 100644 --- a/src/main/java/org/etsi/osl/tmf/ram702/api/ResourceActivationApiRouteBuilder.java +++ b/src/main/java/org/etsi/osl/tmf/ram702/api/ResourceActivationApiRouteBuilder.java @@ -46,17 +46,17 @@ public class ResourceActivationApiRouteBuilder extends RouteBuilder { private static final transient Log logger = LogFactory.getLog(ResourceActivationApiRouteBuilder.class.getName()); - @Value("${CATALOG_ADD_RESOURCE}") - private String CATALOG_ADD_RESOURCE = ""; + @Value("${CATALOG_ADD_RESOURCEACTIVATION}") + private String CATALOG_ADD_RESOURCEACTIVATION = ""; - @Value("${CATALOG_UPD_RESOURCE}") - private String CATALOG_UPD_RESOURCE = ""; + @Value("${CATALOG_UPD_RESOURCEACTIVATION}") + private String CATALOG_UPD_RESOURCEACTIVATION = ""; - @Value("${CATALOG_UPDADD_RESOURCE}") - private String CATALOG_UPDADD_RESOURCE = ""; + @Value("${CATALOG_UPDADD_RESOURCEACTIVATION}") + private String CATALOG_UPDADD_RESOURCEACTIVATION = ""; - @Value("${CATALOG_GET_RESOURCE_BY_ID}") - private String CATALOG_GET_RESOURCE_BY_ID = ""; + @Value("${CATALOG_GET_RESOURCEACTIVATION_BY_ID}") + private String CATALOG_GET_RESOURCEACTIVATION_BY_ID = ""; @Autowired private ProducerTemplate template; @@ -67,8 +67,8 @@ public class ResourceActivationApiRouteBuilder extends RouteBuilder { @Override public void configure() throws Exception { - from( CATALOG_ADD_RESOURCE ) - .log(LoggingLevel.INFO, log, CATALOG_ADD_RESOURCE + " message received!") + from( CATALOG_ADD_RESOURCEACTIVATION ) + .log(LoggingLevel.INFO, log, CATALOG_ADD_RESOURCEACTIVATION + " message received!") .to("log:DEBUG?showBody=true&showHeaders=true") .unmarshal().json( JsonLibrary.Jackson, ResourceCreate.class, true) .bean( resourceRepoService, "addResource(${body})") @@ -76,16 +76,16 @@ public class ResourceActivationApiRouteBuilder extends RouteBuilder { .json( JsonLibrary.Jackson) .convertBodyTo( String.class ); - from( CATALOG_UPD_RESOURCE ) - .log(LoggingLevel.INFO, log, CATALOG_UPD_RESOURCE + " message received!") + from( CATALOG_UPD_RESOURCEACTIVATION ) + .log(LoggingLevel.INFO, log, CATALOG_UPD_RESOURCEACTIVATION + " message received!") .to("log:DEBUG?showBody=true&showHeaders=true") .unmarshal().json( JsonLibrary.Jackson, ResourceUpdate.class, true) .bean( resourceRepoService, "updateResource(${header.resourceId}, ${body}, ${header.triggerServiceActionQueue} )") .marshal().json( JsonLibrary.Jackson) .convertBodyTo( String.class ); - from( CATALOG_UPDADD_RESOURCE ) - .log(LoggingLevel.INFO, log, CATALOG_UPDADD_RESOURCE + " message received!") + from( CATALOG_UPDADD_RESOURCEACTIVATION ) + .log(LoggingLevel.INFO, log, CATALOG_UPDADD_RESOURCEACTIVATION + " message received!") .to("log:DEBUG?showBody=true&showHeaders=true") .unmarshal().json( JsonLibrary.Jackson, ResourceCreate.class, true) .bean( resourceRepoService, "addOrUpdateResourceByNameCategoryVersion(${header.aname},${header.acategory}, ${header.aversion}, ${body})") diff --git a/src/main/java/org/etsi/osl/tmf/ram702/api/ResourceActivationApiRouteBuilderEvents.java b/src/main/java/org/etsi/osl/tmf/ram702/api/ResourceActivationApiRouteBuilderEvents.java deleted file mode 100644 index c30136f29940635b1881df2e26e09b3df9403032..0000000000000000000000000000000000000000 --- a/src/main/java/org/etsi/osl/tmf/ram702/api/ResourceActivationApiRouteBuilderEvents.java +++ /dev/null @@ -1,112 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * org.etsi.osl.tmf.api - * %% - * Copyright (C) 2024 openslice.io - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * =========================LICENSE_END================================== - */ - -package org.etsi.osl.tmf.ram702.api; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.ObjectMapper; - -import org.apache.camel.ProducerTemplate; -import org.apache.camel.builder.RouteBuilder; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.etsi.osl.tmf.common.model.Notification; -import org.etsi.osl.tmf.ri639.model.ResourceAttributeValueChangeNotification; -import org.etsi.osl.tmf.ri639.model.ResourceCreateNotification; -import org.etsi.osl.tmf.ri639.model.ResourceStateChangeNotification; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; -import org.springframework.stereotype.Component; - -@Configuration -// @RefreshScope -@Component -public class ResourceActivationApiRouteBuilderEvents extends RouteBuilder { - - private static final transient Log logger = - LogFactory.getLog(ResourceActivationApiRouteBuilderEvents.class.getName()); - - - - @Value("${EVENT_RESOURCE_CREATE}") - private String EVENT_RESOURCE_CREATE = ""; - - @Value("${EVENT_RESOURCE_STATE_CHANGED}") - private String EVENT_RESOURCE_STATE_CHANGED = ""; - - @Value("${EVENT_RESOURCE_DELETE}") - private String EVENT_RESOURCE_DELETE = ""; - - @Value("${EVENT_RESOURCE_ATTRIBUTE_VALUE_CHANGED}") - private String EVENT_RESOURCE_ATTRIBUTE_VALUE_CHANGED = ""; - - - @Autowired - private ProducerTemplate template; - - - @Override - public void configure() throws Exception { - - } - - - /** - * @param n - */ - public void publishEvent(final Notification n, final String objId) { - n.setEventType(n.getClass().getName()); - logger.info("will send Event topic for type " + n.getEventType()); - try { - String msgtopic = ""; - - if (n instanceof ResourceCreateNotification) { - msgtopic = EVENT_RESOURCE_CREATE; - } else if (n instanceof ResourceAttributeValueChangeNotification) { - msgtopic = EVENT_RESOURCE_ATTRIBUTE_VALUE_CHANGED; - }else if (n instanceof ResourceStateChangeNotification ) { - msgtopic = EVENT_RESOURCE_STATE_CHANGED; - } - - Map map = new HashMap<>(); - map.put("eventid", n.getEventId()); - map.put("objId", objId); - - template.sendBodyAndHeaders(msgtopic, toJsonString(n), map); - - } catch (Exception e) { - logger.error("Cannot send Event . " + e.getStackTrace()); - } - } - - static String toJsonString(Object object) throws IOException { - ObjectMapper mapper = new ObjectMapper(); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - return mapper.writeValueAsString(object); - } - -} diff --git a/src/main/java/org/etsi/osl/tmf/scm633/reposervices/ServiceSpecificationRepoService.java b/src/main/java/org/etsi/osl/tmf/scm633/reposervices/ServiceSpecificationRepoService.java index f2a517266d56a3334fbf812e3806a5a4ede9b5ed..eb6ca09c1cf0d752a8a84412b2b5b054b6e2b2a5 100644 --- a/src/main/java/org/etsi/osl/tmf/scm633/reposervices/ServiceSpecificationRepoService.java +++ b/src/main/java/org/etsi/osl/tmf/scm633/reposervices/ServiceSpecificationRepoService.java @@ -1450,7 +1450,12 @@ public class ServiceSpecificationRepoService { serviceSpecCharacteristicItem.setValidFor( sourceChar.getValidFor() ); for (ResourceSpecificationCharacteristicValue cv : sourceChar.getResourceSpecCharacteristicValue()) { ServiceSpecCharacteristicValue serviceSpecCharacteristicValueItem = new ServiceSpecCharacteristicValue(); - serviceSpecCharacteristicValueItem.setValue( new Any( cv.getValue().getValue(), cv.getValue().getAlias())); + if ( cv.getValue()!=null && cv.getValue().getValue()!=null) { + serviceSpecCharacteristicValueItem.setValue( new Any( cv.getValue().getValue(), cv.getValue().getAlias())); + } else { + serviceSpecCharacteristicValueItem.setValue( new Any( "", "")); + } + serviceSpecCharacteristicValueItem.isDefault( cv.isIsDefault() ); serviceSpecCharacteristicValueItem.setUnitOfMeasure( cv.getUnitOfMeasure() ); serviceSpecCharacteristicItem.addServiceSpecCharacteristicValueItem(serviceSpecCharacteristicValueItem ); diff --git a/src/main/java/org/etsi/osl/tmf/sim638/service/ServiceRepoService.java b/src/main/java/org/etsi/osl/tmf/sim638/service/ServiceRepoService.java index 436cb6ce6a9690f44c63f2a89761123955b71e05..b69e14aa5ec939ad97b4aa049cdb99c29e25f4aa 100644 --- a/src/main/java/org/etsi/osl/tmf/sim638/service/ServiceRepoService.java +++ b/src/main/java/org/etsi/osl/tmf/sim638/service/ServiceRepoService.java @@ -578,11 +578,19 @@ public class ServiceRepoService { } if (serviceCharacteristicChanged) { - Note noteItem = new Note(); - noteItem.setText("Service Characteristic changed: " + charChangedForNotes ); - noteItem.setAuthor("API"); - noteItem.setDate(OffsetDateTime.now(ZoneOffset.UTC) ); - service.addNoteItem(noteItem); + + Characteristic noteCheck = service.getServiceCharacteristicByName("_DETAILED_NOTES_"); + if ( noteCheck!= null + && noteCheck.getValue() != null + && noteCheck.getValue().getValue() != null + && !noteCheck.getValue().getValue().equals("")) { + Note noteItem = new Note(); + noteItem.setText("Service Characteristic changed: " + charChangedForNotes ); + noteItem.setAuthor("SIM638-API"); + noteItem.setDate(OffsetDateTime.now(ZoneOffset.UTC) ); + service.addNoteItem(noteItem); + + } } @@ -639,6 +647,11 @@ public class ServiceRepoService { this.addServiceActionQueueItem(saqi); } + + + + + /* * Update any parent service */ @@ -946,6 +959,8 @@ public class ServiceRepoService { public ServiceActionQueueItem addServiceActionQueueItem(@Valid ServiceActionQueueItem item) { logger.debug("Will add ServiceActionQueueItem ServiceRefId: " + item.getServiceRefId() ); + + //find any similar action inqueue and delete them, so to keep this one as the most recent List result = this.serviceActionQueueRepo.findByServiceRefIdAndAction(item.getServiceRefId(), item.getAction()); logger.debug("Will add ServiceActionQueueItem ServiceRefId result: " +result.size() ); @@ -1114,37 +1129,59 @@ public class ServiceRepoService { public void updateServicesHavingThisSupportingResource(@Valid Resource res) { try { - logger.info("Will update services related to this resource with id = " + res.getId() ); + logger.debug("Will update services related to this resource with id = " + res.getId() ); var aservices = findServicesHavingThisSupportingResourceID( res.getId() ); + + logger.debug("services.found = " + aservices.size() ); for (Service as : aservices) { - Service aService = findByUuid(as.getId()); - - //if ( aService.getState().equals( ServiceStateType.ACTIVE ) ) { - + Service aService = findByUuid(as.getId()); + + List rlist = new ArrayList(); + for (ResourceRef rref : aService.getSupportingResource()) { + Optional result = resourceRepo.findByUuid(rref.getId()); + if (result.isPresent()) { + rlist.add( result.get() ); + } + } + + rlist.add(res); //add also this one + + ServiceStateType nextState = aService.findNextStateBasedOnSupportingResources(rlist); ServiceUpdate supd = new ServiceUpdate(); + supd.setState(nextState); + String stateText=""; + if ( !aService.getState().equals(nextState)) { + stateText = "State changed from " + aService.getState() + " to " + nextState + "."; + } - //copy characteristics from resource to service + + //copy characteristics, from resource to service for (org.etsi.osl.tmf.ri639.model.Characteristic rChar : res.getResourceCharacteristic()) { - Characteristic cNew = new Characteristic(); - cNew.setName( rChar.getName()); - cNew.value( new Any( rChar.getValue() )); - supd.addServiceCharacteristicItem( cNew ); + Characteristic cNew = new Characteristic(); + cNew.setName( rChar.getName()); + cNew.value( new Any( rChar.getValue() )); + supd.addServiceCharacteristicItem( cNew ); } + Characteristic noteCheck = as.getServiceCharacteristicByName("_DETAILED_NOTES_"); + if ( noteCheck!= null + && noteCheck.getValue() != null + && noteCheck.getValue().getValue() != null + && !noteCheck.getValue().getValue().equals("")) { + Note n = new Note(); + n.setText(stateText + "Supporting Resource changed with id: " + res.getId()); + n.setAuthor( "SIM638-API" ); + n.setDate( OffsetDateTime.now(ZoneOffset.UTC).toString() ); + supd.addNoteItem( n ); + } - Note n = new Note(); - n.setText("Supporting Resource Attribute Changed with id: " + res.getId()); - n.setAuthor( "SIM638-API" ); - n.setDate( OffsetDateTime.now(ZoneOffset.UTC).toString() ); - supd.addNoteItem( n ); - - this.updateService( aService.getId(), supd , true, null, null); //update the service - //} + this.updateService( aService.getId(), supd , true, null, null); //update the service + } @@ -1185,47 +1222,23 @@ public class ServiceRepoService { @Transactional private void updateServiceFromresourceChange(Resource res) { - logger.info("Will update services related to this resource with id = " + res.getId() ); - var aservices = findServicesHavingThisSupportingResourceID(res.getId()); - - for (Service as : aservices) { + updateServicesHavingThisSupportingResource(res); - Service aService = findByUuid(as.getId()); - - - List rlist = new ArrayList(); - for (ResourceRef rref : aService.getSupportingResource()) { - Optional result = resourceRepo.findByUuid(rref.getId()); - if (result.isPresent()) { - rlist.add( result.get() ); - } - } - - rlist.add(res); //add also this one - - ServiceStateType nextState = aService.findNextStateBasedOnSupportingResources(rlist); - - ServiceUpdate supd = new ServiceUpdate(); - supd.setState(nextState); - Note n = new Note(); - n.setText("Supporting Resource " + res.getId() + " State Changed with status: " - + res.getResourceStatus() + ".Next state is " + nextState); - n.setAuthor("SIM638-API"); - n.setDate(OffsetDateTime.now(ZoneOffset.UTC).toString()); - supd.addNoteItem(n); - - this.updateService(aService.getId(), supd, true, null, null); // update the service - } - - - updateResourceFromKubernetesLabel(res); + addAnyNewRelatedResourcesFromKubernetesLabel(res); } + /** + * This function will try to identify if the resource contains + * a characteristic called "org.etsi.osl.serviceId" and will check if there is a related service. + * If it is not it's add the resource back to the service. This is useful in kubernetes deployments, + * in cases of new resources in a namespace that are related to this service + * @param res + */ @Transactional - private void updateResourceFromKubernetesLabel(Resource res) { - logger.debug("updateResourceFromKubernetesLabel for: " + res.getName()); + private void addAnyNewRelatedResourcesFromKubernetesLabel(Resource res) { + logger.debug("updateResourceFromKubernetesLabel for: " + res.getName() + ", version" + res.getResourceVersion()); if (res.getResourceCharacteristicByName("org.etsi.osl.serviceId") != null) { diff --git a/src/main/resources/application-testing.yml b/src/main/resources/application-testing.yml index 719f8c57fedd3186a081820e20377eedd6965e36..20698fde17f6ade4e8f743194fed1ae428aedeb4 100644 --- a/src/main/resources/application-testing.yml +++ b/src/main/resources/application-testing.yml @@ -157,6 +157,13 @@ EVENT_RESOURCE_DELETE: "jms:topic:EVENT.SERVICE.RESOURCE" EVENT_RESOURCE_ATTRIBUTE_VALUE_CHANGED: "jms:topic:EVENT.RESOURCE.ATTRCHANGED" CATALOG_RESOURCES_OF_PARTNERS: "jms:queue:CATALOG.GET.SERVICESOFPARTNERS" +#RESOURCE_ACTIVATION +CATALOG_ADD_RESOURCEACTIVATION: "jms:queue:CATALOG.ADD.RESOURCEACTIVATION" +CATALOG_UPD_RESOURCEACTIVATION: "jms:queue:CATALOG.UPD.RESOURCEACTIVATION" +CATALOG_UPDADD_RESOURCEACTIVATION: "jms:queue:CATALOG.UPDADD.RESOURCEACTIVATION" +CATALOG_GET_RESOURCEACTIVATION_BY_ID: "jms:queue:CATALOG.GET.RESOURCEACTIVATION" + + #LCM MESSAGES CATALOG_GET_LCMRULE_BY_ID: "jms:queue:CATALOG.GET.LCMRULE" CATALOG_GET_LCMRULES_BY_SPECID_PHASE: "jms:queue:CATALOG.GET.LCMRULES_BY_SPECID_PHASE" diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 163f1d379831b166225b0ac421eb8a1998ed8993..a33439166273464b46fbee1a31cc1d077f1b295b 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -189,6 +189,12 @@ EVENT_RESOURCE_DELETE: "jms:topic:EVENT.SERVICE.RESOURCE" EVENT_RESOURCE_ATTRIBUTE_VALUE_CHANGED: "jms:topic:EVENT.RESOURCE.ATTRCHANGED" CATALOG_RESOURCES_OF_PARTNERS: "jms:queue:CATALOG.GET.SERVICESOFPARTNERS" +#RESOURCE_ACTIVATION +CATALOG_ADD_RESOURCEACTIVATION: "jms:queue:CATALOG.ADD.RESOURCEACTIVATION" +CATALOG_UPD_RESOURCEACTIVATION: "jms:queue:CATALOG.UPD.RESOURCEACTIVATION" +CATALOG_UPDADD_RESOURCEACTIVATION: "jms:queue:CATALOG.UPDADD.RESOURCEACTIVATION" +CATALOG_GET_RESOURCEACTIVATION_BY_ID: "jms:queue:CATALOG.GET.RESOURCEACTIVATION" + #LCM MESSAGES CATALOG_GET_LCMRULE_BY_ID: "jms:queue:CATALOG.GET.LCMRULE" CATALOG_GET_LCMRULES_BY_SPECID_PHASE: "jms:queue:CATALOG.GET.LCMRULES_BY_SPECID_PHASE" diff --git a/src/test/java/org/etsi/osl/services/api/ServiceInventoryIntegrationTest.java b/src/test/java/org/etsi/osl/services/api/ServiceInventoryIntegrationTest.java index 16ad168abce52debb68d788ab7467a9a0ea096dd..93e25542960cf7b22af6b7b4fd3188dfcffa60b9 100644 --- a/src/test/java/org/etsi/osl/services/api/ServiceInventoryIntegrationTest.java +++ b/src/test/java/org/etsi/osl/services/api/ServiceInventoryIntegrationTest.java @@ -275,7 +275,7 @@ public class ServiceInventoryIntegrationTest { assertThat( serviceRepoService.findAll().size() ).isEqualTo( 1 ); assertThat( responseSOUpd.getEndDate() ).isNotNull(); - assertThat( responseSOUpd.getNote().size() ).isEqualTo( 5 ); + assertThat( responseSOUpd.getNote().size() ).isEqualTo( 4 ); assertThat( responseSOUpd.getServiceCharacteristic().size() ).isEqualTo( 4 ); assertThat( responseSOUpd.getServiceCharacteristicByName( "ConfigStatus" ).getValue().getValue() ).isEqualTo( "RUNNING" ) ; assertThat( responseSOUpd.getServiceCharacteristicByName( "DeploymentRequestID" ).getValue().getValue() ).isEqualTo( "1007" ) ; @@ -321,7 +321,7 @@ public class ServiceInventoryIntegrationTest { assertThat( serviceRepoService.findAll().size() ).isEqualTo( 1 ); assertThat( responseSOUpd.getEndDate() ).isNotNull(); - assertThat( responseSOUpd.getNote().size() ).isEqualTo( 7 ); + assertThat( responseSOUpd.getNote().size() ).isEqualTo( 6 ); assertThat( responseSOUpd.getServiceCharacteristic().size() ).isEqualTo( 4 ); assertThat( responseSOUpd.getServiceCharacteristicByName( "ConfigStatus" ).getValue().getValue() ).isEqualTo( "RUNNING" ) ; assertThat( responseSOUpd.getServiceCharacteristicByName( "DeploymentRequestID" ).getValue().getValue() ).isEqualTo( "1007" ) ; diff --git a/src/test/java/org/etsi/osl/services/api/sim638/ServiceRepoServiceTest.java b/src/test/java/org/etsi/osl/services/api/sim638/ServiceRepoServiceTest.java index 4309b09e34f96c9967ee763447308b764da46083..32238e90662ef2c698a79b4dddc2f9207c67c1e1 100644 --- a/src/test/java/org/etsi/osl/services/api/sim638/ServiceRepoServiceTest.java +++ b/src/test/java/org/etsi/osl/services/api/sim638/ServiceRepoServiceTest.java @@ -258,7 +258,7 @@ public class ServiceRepoServiceTest { boolean expectedNoteExists = false; for (Note n : noteList) { - if ( n.getText().contains("State Changed with status:") && n.getAuthor().equals("SIM638-API")) { + if ( n.getText().contains("Supporting Resource changed with") && n.getAuthor().equals("SIM638-API")) { expectedNoteExists= true; break; } @@ -291,7 +291,7 @@ public class ServiceRepoServiceTest { Service updatedService = serviceRepoService.findByUuid(id); - assertThat( updatedService.getServiceCharacteristic().size() ).isEqualTo( 6 ); + assertThat( updatedService.getServiceCharacteristic().size() ).isEqualTo( 7 ); assertThat( updatedService.getSupportingResource().size() ).isEqualTo( 1); ResourceUpdate resourceUpdate = new ResourceUpdate(); @@ -313,14 +313,14 @@ public class ServiceRepoServiceTest { System.out.println("STEP 3 - =========================================== " ); updatedService = serviceRepoService.findByUuid(id); assertThat( updatedService.getSupportingResource().size() ).isEqualTo( 1); - assertThat( updatedService.getServiceCharacteristic().size() ).isEqualTo( 7 ); + assertThat( updatedService.getServiceCharacteristic().size() ).isEqualTo( 8 ); Set noteSet = updatedService.getNote(); List noteList = new ArrayList<>(noteSet); boolean expectedNoteExists = false; for (Note n : noteList) { - if ( n.getText().contains("Service Characteristic changed") && n.getAuthor().equals("API")) { + if ( n.getText().contains("Supporting Resource changed with") && n.getAuthor().equals("SIM638-API")) { expectedNoteExists= true; break; } @@ -401,6 +401,12 @@ public class ServiceRepoServiceTest { serviceCharacteristicItem.setName( "long_string" ); serviceCharacteristicItem.setValue( new Any("12345")); aService.addServiceCharacteristicItem(serviceCharacteristicItem); + + + serviceCharacteristicItem = new Characteristic(); + serviceCharacteristicItem.setName( "_DETAILED_NOTES_" ); + serviceCharacteristicItem.setValue( new Any("_DETAILED_NOTES_")); + aService.addServiceCharacteristicItem(serviceCharacteristicItem); ServiceSpecificationRef aServiceSpecificationRef = new ServiceSpecificationRef(); aServiceSpecificationRef.setId(responsesSpec3.getId() );