Commit 4c6bdf5d authored by Christos Tranoris's avatar Christos Tranoris
Browse files

Fix for Create generic controlller resources

parent 37a1be09
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -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" );                      
          }		
          }		
		}
		}


+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. ");
		
		

		
		
	}


	
}
+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 "";
  }


}
+57 −1
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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) {
@@ -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;
  }
  





}
}
+90 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading