Loading src/main/java/org/etsi/osl/osom/management/AutomationCheck.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -89,6 +89,8 @@ public class AutomationCheck implements JavaDelegate { execution.setVariable("brokeActivity", "RFS_OSM" ); execution.setVariable("brokeActivity", "RFS_OSM" ); } else if ( spec.getType().equals("ResourceFacingServiceSpecification") && ( spec.findSpecCharacteristicByName( "_CR_SPEC" ) != null ) ) { } else if ( spec.getType().equals("ResourceFacingServiceSpecification") && ( spec.findSpecCharacteristicByName( "_CR_SPEC" ) != null ) ) { execution.setVariable("brokeActivity", "RFS_CRSPEC" ); execution.setVariable("brokeActivity", "RFS_CRSPEC" ); } else if ( spec.getType().equals("ResourceFacingServiceSpecification") ) { execution.setVariable("brokeActivity", "GRSPEC" ); } } } } Loading src/main/java/org/etsi/osl/osom/management/GCOrchestrationCheckDeploymentService.java 0 → 100644 +130 −0 Original line number Original line Diff line number Diff line /*- * ========================LICENSE_START================================= * org.etsi.osl.osom * %% * Copyright (C) 2019 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.osom.management; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.etsi.osl.tmf.common.model.service.Note; import org.etsi.osl.tmf.common.model.service.ResourceRef; import org.etsi.osl.tmf.common.model.service.ServiceStateType; import org.etsi.osl.tmf.ri639.model.Resource; import org.etsi.osl.tmf.sim638.model.Service; import org.etsi.osl.tmf.sim638.model.ServiceUpdate; import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.delegate.JavaDelegate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import jakarta.validation.Valid; @Component(value = "gcOrchestrationCheckDeploymentService") //bean name public class GCOrchestrationCheckDeploymentService implements JavaDelegate { private static final transient Log logger = LogFactory.getLog(GCOrchestrationCheckDeploymentService.class.getName()); @Value("${spring.application.name}") private String compname; @Autowired private ServiceOrderManager serviceOrderManager; public void execute(DelegateExecution execution) { logger.info( "CROrchestrationCheckDeploymentService" ); logger.info( execution.getVariableNames().toString() ); if ( execution.getVariable("contextServiceId") == null) { logger.error( "Variable contextServiceId is NULL!" ); execution.setVariable("serviceDeploymentFinished", Boolean.TRUE ); return; } Service aService = serviceOrderManager.retrieveService( (String) execution.getVariable("contextServiceId") ); if ( aService == null ) { logger.info( "aService is null for contextServiceId = " +(String) execution.getVariable("contextServiceId") ); execution.setVariable("serviceDeploymentFinished", Boolean.TRUE ); return; } execution.setVariable("serviceDeploymentFinished", Boolean.FALSE ); ServiceUpdate supd = new ServiceUpdate(); boolean propagateToSO = false; //retrieve the related supporting resource by id and check its status //ResourceRef supresourceRef = aService.getSupportingResource().stream().findFirst().get();//we assume for now we have only one related resource List<Resource> rlist = new ArrayList<Resource>(); for (ResourceRef rref : aService.getSupportingResource()) { Resource res = serviceOrderManager.retrieveResource(rref.getId()); if ( res == null ) { supd.setState( ServiceStateType.TERMINATED); execution.setVariable("serviceDeploymentFinished", Boolean.TRUE); Service serviceResult = serviceOrderManager.updateService( aService.getId(), supd, propagateToSO ); return; } rlist.add(res); } @Valid ServiceStateType currentState = aService.getState(); ServiceStateType nextState = aService.findNextStateBasedOnSupportingResources(rlist); if (!currentState.equals(nextState)) { supd.setState( nextState ); Note n = new Note(); n.setText("Service Status Changed to: " + nextState); n.setAuthor(compname); n.setDate(OffsetDateTime.now(ZoneOffset.UTC).toString()); supd.addNoteItem(n); aService = serviceOrderManager.updateService( aService.getId(), supd, propagateToSO ); } if ( aService!= null ) { if ( aService.getState().equals(ServiceStateType.ACTIVE) || aService.getState().equals(ServiceStateType.TERMINATED)) { logger.info("Deployment Status OK. Service state = " + aService.getState() ); execution.setVariable("serviceDeploymentFinished", Boolean.TRUE); return; } } logger.info("Wait For Deployment Status. "); } } src/main/java/org/etsi/osl/osom/management/GCOrchestrationService.java 0 → 100644 +390 −0 Original line number Original line Diff line number Diff line /*- * ========================LICENSE_START================================= * org.etsi.osl.osom * %% * Copyright (C) 2019 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.osom.management; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.etsi.osl.tmf.common.model.Any; import org.etsi.osl.tmf.common.model.EValueType; import org.etsi.osl.tmf.common.model.service.Characteristic; import org.etsi.osl.tmf.common.model.service.Note; import org.etsi.osl.tmf.common.model.service.ResourceRef; import org.etsi.osl.tmf.common.model.service.ServiceStateType; import org.etsi.osl.tmf.rcm634.model.ResourceSpecification; import org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCharacteristic; import org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCharacteristicValue; import org.etsi.osl.tmf.rcm634.model.ResourceSpecificationRef; import org.etsi.osl.tmf.ri639.model.Resource; import org.etsi.osl.tmf.ri639.model.ResourceCreate; import org.etsi.osl.tmf.scm633.model.ServiceSpecCharacteristic; import org.etsi.osl.tmf.scm633.model.ServiceSpecification; import org.etsi.osl.tmf.sim638.model.Service; import org.etsi.osl.tmf.sim638.model.ServiceUpdate; import org.etsi.osl.tmf.so641.model.ServiceOrder; import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.delegate.JavaDelegate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import jakarta.validation.Valid; @Component(value = "gcOrchestrationService") // bean name public class GCOrchestrationService implements JavaDelegate { private static final transient Log logger = LogFactory.getLog(GCOrchestrationService.class.getName()); @Value("${spring.application.name}") private String compname; @Autowired private ServiceOrderManager serviceOrderManager; public void execute(DelegateExecution execution) { logger.info("Ceneric Controller OrchestrationService"); logger.info("VariableNames:" + execution.getVariableNames().toString()); logger.info("orderid:" + execution.getVariable("orderid").toString()); logger.info("contextServiceId:" + execution.getVariable("contextServiceId").toString()); try { ServiceUpdate su = new ServiceUpdate();// the object to update the service Note noteItem = new Note(); noteItem.setText(""); if (execution.getVariable("contextServiceId") instanceof String contextServiceId) { ServiceOrder sorder = serviceOrderManager.retrieveServiceOrder(execution.getVariable("orderid").toString()); Service aService = serviceOrderManager.retrieveService( contextServiceId ); logger.info("Service name:" + aService.getName()); logger.info("Service state:" + aService.getState()); logger.info("Request for a Custom Resource creation for Service: " + aService.getId()); // we need to retrieve here the Service Spec of this service ServiceSpecification spec = serviceOrderManager.retrieveServiceSpec(aService.getServiceSpecificationRef().getId()); if (spec != null) { //we need to get the equivalent resource spec. since ServiceSpec is an RFS ResourceSpecificationRef rSpecRef = spec.getResourceSpecification().stream().findFirst().get(); ResourceSpecification rspec = serviceOrderManager.retrieveResourceSpec(rSpecRef.getId()); //we will create a resource based on the values of resourcepsecificationRef Resource resourceCR = createRelatedResource( rspec, sorder, aService ); ResourceRef rr = new ResourceRef(); rr.setId( resourceCR.getId() ); rr.setName( resourceCR.getName()); rr.setType( resourceCR.getType()); su.addSupportingResourceItem( rr ); Resource response = null; response = createNewResourceDeploymentRequest(aService, resourceCR, rspec, sorder.getId(), sorder.getStartDate(), sorder.getExpectedCompletionDate() ); if ( response!=null ) { su.setState(ServiceStateType.RESERVED); Note successNoteItem = new Note(); successNoteItem.setText(String.format("Requesting Controller of "+ rSpecRef.getName() +" to deploy resource")); successNoteItem.setDate(OffsetDateTime.now(ZoneOffset.UTC).toString()); successNoteItem.setAuthor(compname); su.addNoteItem(successNoteItem); } else { su.setState(ServiceStateType.TERMINATED); Note errNoteItem = new Note(); errNoteItem.setText(String.format("Requesting Controller to deploy resource failed ")); errNoteItem.setDate(OffsetDateTime.now(ZoneOffset.UTC).toString()); errNoteItem.setAuthor(compname); su.addNoteItem(errNoteItem); } Service supd = serviceOrderManager.updateService(aService.getId(), su, false); return; } else { logger.error("Cannot retrieve ServiceSpecification for service :" + (String) execution.getVariable("contextServiceId")); } } else { logger.error("Cannot retrieve variable contextServiceId"); } // if we get here something is wrong so we need to terminate the service. }catch (Exception e) { e.printStackTrace(); } try { Note noteItem = new Note(); noteItem.setText("Request to CR FAILED." + noteItem.getText()); noteItem.setAuthor(compname); noteItem.setDate(OffsetDateTime.now(ZoneOffset.UTC).toString()); ServiceUpdate su = new ServiceUpdate();// the object to update the service su.addNoteItem(noteItem); su.setState(ServiceStateType.TERMINATED); serviceOrderManager.updateService(execution.getVariable("contextServiceId").toString(), su, false); }catch (Exception e) { e.printStackTrace(); } } /** * * THe resource has a temporary name. * later on the name and its characteristics are updated via the generic controller * * * @param rSpecRef * @param sOrder * @param aService * @return */ private Resource createRelatedResource(ResourceSpecification rspec, ServiceOrder sOrder, Service aService) { /** * In future releases, it is better to create some helper function in the TMF model that * Creates a resource from a resource specification, (or a service from a servic spec). * There are similar functions in other places, so it is better to move them in one place */ ResourceCreate resCreate = new ResourceCreate(); resCreate.setName( rspec.getName()+"-" + aService.getId() ); resCreate.setCategory( rspec.getCategory() ); resCreate.resourceVersion( rspec.getVersion() ); resCreate.setStartOperatingDate( aService.getStartDate() ); resCreate.setEndOperatingDate(aService.getEndDate()); ResourceSpecificationRef rSpecRefObj = new ResourceSpecificationRef() ; rSpecRefObj.id(rspec.getId()) .version(rspec.getVersion()) .name( rspec.getName()) .setType(rspec.getType()); resCreate.setResourceSpecification(rSpecRefObj); for (ResourceSpecificationCharacteristic c : rspec.getResourceSpecCharacteristic()) { for (Characteristic orderCharacteristic : aService.getServiceCharacteristic() ) { String specCharacteristicToSearch = c.getName(); if ( orderCharacteristic.getName().equals( specCharacteristicToSearch )) { //copy only characteristics that are related from the order resCreate.addResourceCharacteristicItem( addResourceCharacteristicItem(c, orderCharacteristic) ); break; } } } //copy to resource the rest of the characteristics that do not exists yet from the above search copyRemainingSpecCharacteristicsToResourceCharacteristic(rspec , resCreate.getResourceCharacteristic() ); return serviceOrderManager.createResource( resCreate, sOrder, rspec.getId() ); } private org.etsi.osl.tmf.ri639.model.Characteristic addResourceCharacteristicItem(ResourceSpecificationCharacteristic c, Characteristic orderCharacteristic) { org.etsi.osl.tmf.ri639.model.Characteristic resCharacteristicItem = new org.etsi.osl.tmf.ri639.model.Characteristic(); resCharacteristicItem.setName( c.getName() ); resCharacteristicItem.setValueType( c.getValueType() ); Any val = new Any(); val.setValue( orderCharacteristic.getValue().getValue() ); val.setAlias( orderCharacteristic.getValue().getAlias() ); resCharacteristicItem.setValue( val ); return resCharacteristicItem; } /** * * This helper function it is better in future to be moved in the TMF model. * There is similar in resource order * * @param spec * @param list */ private void copyRemainingSpecCharacteristicsToResourceCharacteristic(ResourceSpecification spec, @Valid List<org.etsi.osl.tmf.ri639.model.Characteristic> list) { for (ResourceSpecificationCharacteristic sourceCharacteristic : spec.getResourceSpecCharacteristic()) { if ( sourceCharacteristic.getValueType() != null ) { boolean charfound = false; for (org.etsi.osl.tmf.ri639.model.Characteristic destchar : list) { if ( destchar.getName().equals(sourceCharacteristic.getName())) { charfound = true; break; } } if (!charfound) { org.etsi.osl.tmf.ri639.model.Characteristic newChar = new org.etsi.osl.tmf.ri639.model.Characteristic(); newChar.setName( sourceCharacteristic.getName() ); newChar.setValueType( sourceCharacteristic.getValueType() ); if ( sourceCharacteristic.getValueType() != null && sourceCharacteristic.getValueType().equals( EValueType.ARRAY.getValue() ) || sourceCharacteristic.getValueType() != null && sourceCharacteristic.getValueType().equals( EValueType.SET.getValue() ) ) { String valString = ""; for (ResourceSpecificationCharacteristicValue specchar : sourceCharacteristic.getResourceSpecCharacteristicValue()) { if ( ( specchar.isIsDefault()!= null) && specchar.isIsDefault() ) { if ( !valString.equals("")) { valString = valString + ","; } valString = valString + "{\"value\":\"" + specchar.getValue().getValue() + "\",\"alias\":\"" + specchar.getValue().getAlias() + "\"}"; } } newChar.setValue( new Any( "[" + valString + "]", "") ); } else { for (ResourceSpecificationCharacteristicValue specchar : sourceCharacteristic.getResourceSpecCharacteristicValue()) { if ( ( specchar.isIsDefault()!= null) && specchar.isIsDefault() ) { newChar.setValue( new Any( specchar.getValue().getValue(), specchar.getValue().getAlias()) ); break; }else { if (specchar.isIsDefault()== null){ logger.info("specchar is null value: " + sourceCharacteristic.getName() ); } } } } if ( newChar.getValue() !=null) { list.add(newChar ); } else { newChar.setValue( new Any( "", "") ); list.add(newChar ); } } } } } /** * * This function makes a new deployment resource request for a resource specification. * The request is performed via the message queue. * The function sends also some headers that maybe are needed for deployment * These are the headers * <br> * <br><b>org.etsi.osl.serviceId:</b> This is the related service id that the created resource has a reference * <br><b>org.etsi.osl.resourceId:</b> This is the related resource id that the created CR will wrap and reference. There * <br><b>org.etsi.osl.prefixName:</b> we need to add a short prefix (default is cr) to various places. For example in K8s cannot start with a number * <br><b>org.etsi.osl.serviceOrderId:</b> the related service order id of this deployment request * <br> * * @param aService reference to the service that the resource and the CR belongs to * @param aResource reference the equivalent resource in TMF repo of the target CR. One to one mapping * @param orderId related service order ID * @param startDate start date of the deployment (not used currently) * @param endDate end date of the deployment (not used currently) * @return a Resource as updated. It might return "OK" if everything is ok. * "SEE OTHER" if there are multiple CRIDGEs then some other cridge will handle the request for the equivalent cluster. * Any other response is handled as error */ private Resource createNewResourceDeploymentRequest( Service aService, Resource aResource, ResourceSpecification rRef, String orderId, OffsetDateTime startDate, OffsetDateTime endDate) { try { Map<String, Object> map = new HashMap<>(); map.put("org.etsi.osl.serviceId", aService.getId() ); map.put("org.etsi.osl.resourceId", aResource.getId() ); map.put("org.etsi.osl.prefixName", "gr" + aResource.getId().substring(0, 8) ); map.put("org.etsi.osl.serviceOrderId", orderId ); logger.debug("createNewResourceDeploymentRequest "); String queueName = "jms:queue:CREATE/"+aResource.getCategory() + "/" + rRef.getVersion() ; Resource response = serviceOrderManager.gcGenericResourceDeploymentRequest(queueName , map, aResource); return response; } catch (Exception e) { logger.error("cridgeDeploymentRequest failed"); e.printStackTrace(); } return null; } private Object getServiceCharacteristic(Service aService, String val) { if (aService.getServiceCharacteristicByName( val ) !=null ) { return aService.getServiceCharacteristicByName( val ).getValue().getValue(); } return ""; } } src/main/java/org/etsi/osl/osom/management/ServiceOrderManager.java +57 −1 Original line number Original line Diff line number Diff line Loading @@ -36,6 +36,8 @@ import org.etsi.osl.model.nfv.NetworkServiceDescriptor; import org.etsi.osl.model.nfv.ScaleDescriptor; import org.etsi.osl.model.nfv.ScaleDescriptor; import org.etsi.osl.osom.serviceactions.NSActionRequestPayload; import org.etsi.osl.osom.serviceactions.NSActionRequestPayload; import org.etsi.osl.tmf.pm632.model.Organization; import org.etsi.osl.tmf.pm632.model.Organization; import org.etsi.osl.tmf.rcm634.model.LogicalResourceSpecification; import org.etsi.osl.tmf.rcm634.model.ResourceSpecification; import org.etsi.osl.tmf.ri639.model.LogicalResource; import org.etsi.osl.tmf.ri639.model.LogicalResource; import org.etsi.osl.tmf.ri639.model.PhysicalResource; import org.etsi.osl.tmf.ri639.model.PhysicalResource; import org.etsi.osl.tmf.ri639.model.Resource; import org.etsi.osl.tmf.ri639.model.Resource; Loading Loading @@ -189,6 +191,8 @@ public class ServiceOrderManager { private String CATALOG_GET_RESOURCE_BY_ID = ""; private String CATALOG_GET_RESOURCE_BY_ID = ""; @Value("${CATALOG_GET_RESOURCESPEC_BY_ID}") private String CATALOG_GET_RESOURCESPEC_BY_ID = ""; @Transactional @Transactional public void processOrder(ServiceOrder serviceOrder) { public void processOrder(ServiceOrder serviceOrder) { Loading Loading @@ -1082,6 +1086,58 @@ public class ServiceOrderManager { } } public Resource gcGenericResourceDeploymentRequest(String queueName, Map<String, Object> map, Resource aResource) { try { logger.debug("gcGenericResourceDeploymentRequest queueName=" + queueName); String req = toJsonString(aResource); Object response = template.requestBodyAndHeaders( queueName, req , map ); if ( !(response instanceof String)) { logger.error("gcGenericResourceDeploymentRequest response object is wrong."); return null; } logger.debug("gcGenericResourceDeploymentRequest response is: " + response); Resource res = toJsonObj( (String)response, LogicalResource.class); return res; }catch (Exception e) { logger.error("Cannot retrieve gcGenericResourceDeploymentRequest response. " + e.toString()); e.printStackTrace(); } return null; } /** * get service spec by id from model via bus * @param id * @return * @throws IOException */ public ResourceSpecification retrieveResourceSpec(String specid) { logger.info("will retrieve Resource Specification id=" + specid ); try { Object response = template. requestBody( CATALOG_GET_RESOURCESPEC_BY_ID, specid); if ( !(response instanceof String)) { logger.error("Resource Specification object is wrong."); return null; } LogicalResourceSpecification sor = toJsonObj( (String)response, LogicalResourceSpecification.class); //logger.debug("retrieveSpec response is: " + response); return sor; }catch (Exception e) { logger.error("Cannot retrieve Resource Specification details from catalog. " + e.toString()); } return null; } } } src/main/resources/GenericResourceController.md 0 → 100644 +90 −0 File added.Preview size limit exceeded, changes collapsed. Show changes Loading
src/main/java/org/etsi/osl/osom/management/AutomationCheck.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -89,6 +89,8 @@ public class AutomationCheck implements JavaDelegate { execution.setVariable("brokeActivity", "RFS_OSM" ); execution.setVariable("brokeActivity", "RFS_OSM" ); } else if ( spec.getType().equals("ResourceFacingServiceSpecification") && ( spec.findSpecCharacteristicByName( "_CR_SPEC" ) != null ) ) { } else if ( spec.getType().equals("ResourceFacingServiceSpecification") && ( spec.findSpecCharacteristicByName( "_CR_SPEC" ) != null ) ) { execution.setVariable("brokeActivity", "RFS_CRSPEC" ); execution.setVariable("brokeActivity", "RFS_CRSPEC" ); } else if ( spec.getType().equals("ResourceFacingServiceSpecification") ) { execution.setVariable("brokeActivity", "GRSPEC" ); } } } } Loading
src/main/java/org/etsi/osl/osom/management/GCOrchestrationCheckDeploymentService.java 0 → 100644 +130 −0 Original line number Original line Diff line number Diff line /*- * ========================LICENSE_START================================= * org.etsi.osl.osom * %% * Copyright (C) 2019 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.osom.management; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.etsi.osl.tmf.common.model.service.Note; import org.etsi.osl.tmf.common.model.service.ResourceRef; import org.etsi.osl.tmf.common.model.service.ServiceStateType; import org.etsi.osl.tmf.ri639.model.Resource; import org.etsi.osl.tmf.sim638.model.Service; import org.etsi.osl.tmf.sim638.model.ServiceUpdate; import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.delegate.JavaDelegate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import jakarta.validation.Valid; @Component(value = "gcOrchestrationCheckDeploymentService") //bean name public class GCOrchestrationCheckDeploymentService implements JavaDelegate { private static final transient Log logger = LogFactory.getLog(GCOrchestrationCheckDeploymentService.class.getName()); @Value("${spring.application.name}") private String compname; @Autowired private ServiceOrderManager serviceOrderManager; public void execute(DelegateExecution execution) { logger.info( "CROrchestrationCheckDeploymentService" ); logger.info( execution.getVariableNames().toString() ); if ( execution.getVariable("contextServiceId") == null) { logger.error( "Variable contextServiceId is NULL!" ); execution.setVariable("serviceDeploymentFinished", Boolean.TRUE ); return; } Service aService = serviceOrderManager.retrieveService( (String) execution.getVariable("contextServiceId") ); if ( aService == null ) { logger.info( "aService is null for contextServiceId = " +(String) execution.getVariable("contextServiceId") ); execution.setVariable("serviceDeploymentFinished", Boolean.TRUE ); return; } execution.setVariable("serviceDeploymentFinished", Boolean.FALSE ); ServiceUpdate supd = new ServiceUpdate(); boolean propagateToSO = false; //retrieve the related supporting resource by id and check its status //ResourceRef supresourceRef = aService.getSupportingResource().stream().findFirst().get();//we assume for now we have only one related resource List<Resource> rlist = new ArrayList<Resource>(); for (ResourceRef rref : aService.getSupportingResource()) { Resource res = serviceOrderManager.retrieveResource(rref.getId()); if ( res == null ) { supd.setState( ServiceStateType.TERMINATED); execution.setVariable("serviceDeploymentFinished", Boolean.TRUE); Service serviceResult = serviceOrderManager.updateService( aService.getId(), supd, propagateToSO ); return; } rlist.add(res); } @Valid ServiceStateType currentState = aService.getState(); ServiceStateType nextState = aService.findNextStateBasedOnSupportingResources(rlist); if (!currentState.equals(nextState)) { supd.setState( nextState ); Note n = new Note(); n.setText("Service Status Changed to: " + nextState); n.setAuthor(compname); n.setDate(OffsetDateTime.now(ZoneOffset.UTC).toString()); supd.addNoteItem(n); aService = serviceOrderManager.updateService( aService.getId(), supd, propagateToSO ); } if ( aService!= null ) { if ( aService.getState().equals(ServiceStateType.ACTIVE) || aService.getState().equals(ServiceStateType.TERMINATED)) { logger.info("Deployment Status OK. Service state = " + aService.getState() ); execution.setVariable("serviceDeploymentFinished", Boolean.TRUE); return; } } logger.info("Wait For Deployment Status. "); } }
src/main/java/org/etsi/osl/osom/management/GCOrchestrationService.java 0 → 100644 +390 −0 Original line number Original line Diff line number Diff line /*- * ========================LICENSE_START================================= * org.etsi.osl.osom * %% * Copyright (C) 2019 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.osom.management; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.etsi.osl.tmf.common.model.Any; import org.etsi.osl.tmf.common.model.EValueType; import org.etsi.osl.tmf.common.model.service.Characteristic; import org.etsi.osl.tmf.common.model.service.Note; import org.etsi.osl.tmf.common.model.service.ResourceRef; import org.etsi.osl.tmf.common.model.service.ServiceStateType; import org.etsi.osl.tmf.rcm634.model.ResourceSpecification; import org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCharacteristic; import org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCharacteristicValue; import org.etsi.osl.tmf.rcm634.model.ResourceSpecificationRef; import org.etsi.osl.tmf.ri639.model.Resource; import org.etsi.osl.tmf.ri639.model.ResourceCreate; import org.etsi.osl.tmf.scm633.model.ServiceSpecCharacteristic; import org.etsi.osl.tmf.scm633.model.ServiceSpecification; import org.etsi.osl.tmf.sim638.model.Service; import org.etsi.osl.tmf.sim638.model.ServiceUpdate; import org.etsi.osl.tmf.so641.model.ServiceOrder; import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.delegate.JavaDelegate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import jakarta.validation.Valid; @Component(value = "gcOrchestrationService") // bean name public class GCOrchestrationService implements JavaDelegate { private static final transient Log logger = LogFactory.getLog(GCOrchestrationService.class.getName()); @Value("${spring.application.name}") private String compname; @Autowired private ServiceOrderManager serviceOrderManager; public void execute(DelegateExecution execution) { logger.info("Ceneric Controller OrchestrationService"); logger.info("VariableNames:" + execution.getVariableNames().toString()); logger.info("orderid:" + execution.getVariable("orderid").toString()); logger.info("contextServiceId:" + execution.getVariable("contextServiceId").toString()); try { ServiceUpdate su = new ServiceUpdate();// the object to update the service Note noteItem = new Note(); noteItem.setText(""); if (execution.getVariable("contextServiceId") instanceof String contextServiceId) { ServiceOrder sorder = serviceOrderManager.retrieveServiceOrder(execution.getVariable("orderid").toString()); Service aService = serviceOrderManager.retrieveService( contextServiceId ); logger.info("Service name:" + aService.getName()); logger.info("Service state:" + aService.getState()); logger.info("Request for a Custom Resource creation for Service: " + aService.getId()); // we need to retrieve here the Service Spec of this service ServiceSpecification spec = serviceOrderManager.retrieveServiceSpec(aService.getServiceSpecificationRef().getId()); if (spec != null) { //we need to get the equivalent resource spec. since ServiceSpec is an RFS ResourceSpecificationRef rSpecRef = spec.getResourceSpecification().stream().findFirst().get(); ResourceSpecification rspec = serviceOrderManager.retrieveResourceSpec(rSpecRef.getId()); //we will create a resource based on the values of resourcepsecificationRef Resource resourceCR = createRelatedResource( rspec, sorder, aService ); ResourceRef rr = new ResourceRef(); rr.setId( resourceCR.getId() ); rr.setName( resourceCR.getName()); rr.setType( resourceCR.getType()); su.addSupportingResourceItem( rr ); Resource response = null; response = createNewResourceDeploymentRequest(aService, resourceCR, rspec, sorder.getId(), sorder.getStartDate(), sorder.getExpectedCompletionDate() ); if ( response!=null ) { su.setState(ServiceStateType.RESERVED); Note successNoteItem = new Note(); successNoteItem.setText(String.format("Requesting Controller of "+ rSpecRef.getName() +" to deploy resource")); successNoteItem.setDate(OffsetDateTime.now(ZoneOffset.UTC).toString()); successNoteItem.setAuthor(compname); su.addNoteItem(successNoteItem); } else { su.setState(ServiceStateType.TERMINATED); Note errNoteItem = new Note(); errNoteItem.setText(String.format("Requesting Controller to deploy resource failed ")); errNoteItem.setDate(OffsetDateTime.now(ZoneOffset.UTC).toString()); errNoteItem.setAuthor(compname); su.addNoteItem(errNoteItem); } Service supd = serviceOrderManager.updateService(aService.getId(), su, false); return; } else { logger.error("Cannot retrieve ServiceSpecification for service :" + (String) execution.getVariable("contextServiceId")); } } else { logger.error("Cannot retrieve variable contextServiceId"); } // if we get here something is wrong so we need to terminate the service. }catch (Exception e) { e.printStackTrace(); } try { Note noteItem = new Note(); noteItem.setText("Request to CR FAILED." + noteItem.getText()); noteItem.setAuthor(compname); noteItem.setDate(OffsetDateTime.now(ZoneOffset.UTC).toString()); ServiceUpdate su = new ServiceUpdate();// the object to update the service su.addNoteItem(noteItem); su.setState(ServiceStateType.TERMINATED); serviceOrderManager.updateService(execution.getVariable("contextServiceId").toString(), su, false); }catch (Exception e) { e.printStackTrace(); } } /** * * THe resource has a temporary name. * later on the name and its characteristics are updated via the generic controller * * * @param rSpecRef * @param sOrder * @param aService * @return */ private Resource createRelatedResource(ResourceSpecification rspec, ServiceOrder sOrder, Service aService) { /** * In future releases, it is better to create some helper function in the TMF model that * Creates a resource from a resource specification, (or a service from a servic spec). * There are similar functions in other places, so it is better to move them in one place */ ResourceCreate resCreate = new ResourceCreate(); resCreate.setName( rspec.getName()+"-" + aService.getId() ); resCreate.setCategory( rspec.getCategory() ); resCreate.resourceVersion( rspec.getVersion() ); resCreate.setStartOperatingDate( aService.getStartDate() ); resCreate.setEndOperatingDate(aService.getEndDate()); ResourceSpecificationRef rSpecRefObj = new ResourceSpecificationRef() ; rSpecRefObj.id(rspec.getId()) .version(rspec.getVersion()) .name( rspec.getName()) .setType(rspec.getType()); resCreate.setResourceSpecification(rSpecRefObj); for (ResourceSpecificationCharacteristic c : rspec.getResourceSpecCharacteristic()) { for (Characteristic orderCharacteristic : aService.getServiceCharacteristic() ) { String specCharacteristicToSearch = c.getName(); if ( orderCharacteristic.getName().equals( specCharacteristicToSearch )) { //copy only characteristics that are related from the order resCreate.addResourceCharacteristicItem( addResourceCharacteristicItem(c, orderCharacteristic) ); break; } } } //copy to resource the rest of the characteristics that do not exists yet from the above search copyRemainingSpecCharacteristicsToResourceCharacteristic(rspec , resCreate.getResourceCharacteristic() ); return serviceOrderManager.createResource( resCreate, sOrder, rspec.getId() ); } private org.etsi.osl.tmf.ri639.model.Characteristic addResourceCharacteristicItem(ResourceSpecificationCharacteristic c, Characteristic orderCharacteristic) { org.etsi.osl.tmf.ri639.model.Characteristic resCharacteristicItem = new org.etsi.osl.tmf.ri639.model.Characteristic(); resCharacteristicItem.setName( c.getName() ); resCharacteristicItem.setValueType( c.getValueType() ); Any val = new Any(); val.setValue( orderCharacteristic.getValue().getValue() ); val.setAlias( orderCharacteristic.getValue().getAlias() ); resCharacteristicItem.setValue( val ); return resCharacteristicItem; } /** * * This helper function it is better in future to be moved in the TMF model. * There is similar in resource order * * @param spec * @param list */ private void copyRemainingSpecCharacteristicsToResourceCharacteristic(ResourceSpecification spec, @Valid List<org.etsi.osl.tmf.ri639.model.Characteristic> list) { for (ResourceSpecificationCharacteristic sourceCharacteristic : spec.getResourceSpecCharacteristic()) { if ( sourceCharacteristic.getValueType() != null ) { boolean charfound = false; for (org.etsi.osl.tmf.ri639.model.Characteristic destchar : list) { if ( destchar.getName().equals(sourceCharacteristic.getName())) { charfound = true; break; } } if (!charfound) { org.etsi.osl.tmf.ri639.model.Characteristic newChar = new org.etsi.osl.tmf.ri639.model.Characteristic(); newChar.setName( sourceCharacteristic.getName() ); newChar.setValueType( sourceCharacteristic.getValueType() ); if ( sourceCharacteristic.getValueType() != null && sourceCharacteristic.getValueType().equals( EValueType.ARRAY.getValue() ) || sourceCharacteristic.getValueType() != null && sourceCharacteristic.getValueType().equals( EValueType.SET.getValue() ) ) { String valString = ""; for (ResourceSpecificationCharacteristicValue specchar : sourceCharacteristic.getResourceSpecCharacteristicValue()) { if ( ( specchar.isIsDefault()!= null) && specchar.isIsDefault() ) { if ( !valString.equals("")) { valString = valString + ","; } valString = valString + "{\"value\":\"" + specchar.getValue().getValue() + "\",\"alias\":\"" + specchar.getValue().getAlias() + "\"}"; } } newChar.setValue( new Any( "[" + valString + "]", "") ); } else { for (ResourceSpecificationCharacteristicValue specchar : sourceCharacteristic.getResourceSpecCharacteristicValue()) { if ( ( specchar.isIsDefault()!= null) && specchar.isIsDefault() ) { newChar.setValue( new Any( specchar.getValue().getValue(), specchar.getValue().getAlias()) ); break; }else { if (specchar.isIsDefault()== null){ logger.info("specchar is null value: " + sourceCharacteristic.getName() ); } } } } if ( newChar.getValue() !=null) { list.add(newChar ); } else { newChar.setValue( new Any( "", "") ); list.add(newChar ); } } } } } /** * * This function makes a new deployment resource request for a resource specification. * The request is performed via the message queue. * The function sends also some headers that maybe are needed for deployment * These are the headers * <br> * <br><b>org.etsi.osl.serviceId:</b> This is the related service id that the created resource has a reference * <br><b>org.etsi.osl.resourceId:</b> This is the related resource id that the created CR will wrap and reference. There * <br><b>org.etsi.osl.prefixName:</b> we need to add a short prefix (default is cr) to various places. For example in K8s cannot start with a number * <br><b>org.etsi.osl.serviceOrderId:</b> the related service order id of this deployment request * <br> * * @param aService reference to the service that the resource and the CR belongs to * @param aResource reference the equivalent resource in TMF repo of the target CR. One to one mapping * @param orderId related service order ID * @param startDate start date of the deployment (not used currently) * @param endDate end date of the deployment (not used currently) * @return a Resource as updated. It might return "OK" if everything is ok. * "SEE OTHER" if there are multiple CRIDGEs then some other cridge will handle the request for the equivalent cluster. * Any other response is handled as error */ private Resource createNewResourceDeploymentRequest( Service aService, Resource aResource, ResourceSpecification rRef, String orderId, OffsetDateTime startDate, OffsetDateTime endDate) { try { Map<String, Object> map = new HashMap<>(); map.put("org.etsi.osl.serviceId", aService.getId() ); map.put("org.etsi.osl.resourceId", aResource.getId() ); map.put("org.etsi.osl.prefixName", "gr" + aResource.getId().substring(0, 8) ); map.put("org.etsi.osl.serviceOrderId", orderId ); logger.debug("createNewResourceDeploymentRequest "); String queueName = "jms:queue:CREATE/"+aResource.getCategory() + "/" + rRef.getVersion() ; Resource response = serviceOrderManager.gcGenericResourceDeploymentRequest(queueName , map, aResource); return response; } catch (Exception e) { logger.error("cridgeDeploymentRequest failed"); e.printStackTrace(); } return null; } private Object getServiceCharacteristic(Service aService, String val) { if (aService.getServiceCharacteristicByName( val ) !=null ) { return aService.getServiceCharacteristicByName( val ).getValue().getValue(); } return ""; } }
src/main/java/org/etsi/osl/osom/management/ServiceOrderManager.java +57 −1 Original line number Original line Diff line number Diff line Loading @@ -36,6 +36,8 @@ import org.etsi.osl.model.nfv.NetworkServiceDescriptor; import org.etsi.osl.model.nfv.ScaleDescriptor; import org.etsi.osl.model.nfv.ScaleDescriptor; import org.etsi.osl.osom.serviceactions.NSActionRequestPayload; import org.etsi.osl.osom.serviceactions.NSActionRequestPayload; import org.etsi.osl.tmf.pm632.model.Organization; import org.etsi.osl.tmf.pm632.model.Organization; import org.etsi.osl.tmf.rcm634.model.LogicalResourceSpecification; import org.etsi.osl.tmf.rcm634.model.ResourceSpecification; import org.etsi.osl.tmf.ri639.model.LogicalResource; import org.etsi.osl.tmf.ri639.model.LogicalResource; import org.etsi.osl.tmf.ri639.model.PhysicalResource; import org.etsi.osl.tmf.ri639.model.PhysicalResource; import org.etsi.osl.tmf.ri639.model.Resource; import org.etsi.osl.tmf.ri639.model.Resource; Loading Loading @@ -189,6 +191,8 @@ public class ServiceOrderManager { private String CATALOG_GET_RESOURCE_BY_ID = ""; private String CATALOG_GET_RESOURCE_BY_ID = ""; @Value("${CATALOG_GET_RESOURCESPEC_BY_ID}") private String CATALOG_GET_RESOURCESPEC_BY_ID = ""; @Transactional @Transactional public void processOrder(ServiceOrder serviceOrder) { public void processOrder(ServiceOrder serviceOrder) { Loading Loading @@ -1082,6 +1086,58 @@ public class ServiceOrderManager { } } public Resource gcGenericResourceDeploymentRequest(String queueName, Map<String, Object> map, Resource aResource) { try { logger.debug("gcGenericResourceDeploymentRequest queueName=" + queueName); String req = toJsonString(aResource); Object response = template.requestBodyAndHeaders( queueName, req , map ); if ( !(response instanceof String)) { logger.error("gcGenericResourceDeploymentRequest response object is wrong."); return null; } logger.debug("gcGenericResourceDeploymentRequest response is: " + response); Resource res = toJsonObj( (String)response, LogicalResource.class); return res; }catch (Exception e) { logger.error("Cannot retrieve gcGenericResourceDeploymentRequest response. " + e.toString()); e.printStackTrace(); } return null; } /** * get service spec by id from model via bus * @param id * @return * @throws IOException */ public ResourceSpecification retrieveResourceSpec(String specid) { logger.info("will retrieve Resource Specification id=" + specid ); try { Object response = template. requestBody( CATALOG_GET_RESOURCESPEC_BY_ID, specid); if ( !(response instanceof String)) { logger.error("Resource Specification object is wrong."); return null; } LogicalResourceSpecification sor = toJsonObj( (String)response, LogicalResourceSpecification.class); //logger.debug("retrieveSpec response is: " + response); return sor; }catch (Exception e) { logger.error("Cannot retrieve Resource Specification details from catalog. " + e.toString()); } return null; } } }
src/main/resources/GenericResourceController.md 0 → 100644 +90 −0 File added.Preview size limit exceeded, changes collapsed. Show changes