Hay que ser muy friki para escribir un blog, pero m谩s friki hay que ser para seguirlo 馃槣

C贸mo crear una Task Service con SAP Cloud Platform Workflow y API

Hoy os traigo c贸mo crear una task service de SAP Cloud Platform usando una API desde el Portal API.

[wp-svg-icons icon=”checkmark” wrap=”i”]聽Prerrequisito: Tener activo y configurado el Integration Suit de Cloud Foundry.

  1. Para ello, lo primero que debemos hacer es elegir una API de https://api.sap.com/. La que yo he elegido es SAP SuccessFactors Employee Central>Employment Information
  2. Ejecutamos la entidad /EmpEmployment para obtener la URL:
  3. Creamos un nuevo API en nuestro API Portal introduciendo la URL del sandbox:
  4. Una vez creado el API vamos a copiarnos el API Key del API que hayamos seleccionado en聽https://api.sap.com
  5. Crearemos un Key Value Map en nuestro API portal para guardar el API key:

  6. Entramos en el modo de edici贸n del API reci茅n creado y modificamos Policies para a帽adir a hardcode el API Key que hemos copiado en el paso previo:
  7. En TargetEndpoint > PreFlow y creamos Key Value Map Operations

    En la caja de c贸digo a帽adimos lo siguiente para recuperar la clave/valor dada de alta como Key Value Map:

    <KeyValueMapOperations mapIdentifier="SF_Employment" async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
    <Get assignTo="hc_apikey">
     <Key>
    <Parameter>hc_apikey</Parameter>
     </Key>
    </Get>
        <!-- the scope of the key value map. Valid values are environment, organization, apiproxy and policy -->
        <Scope>environment</Scope>
    </KeyValueMapOperations>
    
  8. Creamos un Assign Message para pasarle el API Key que hemos recuperado en la variable {hc_apikey}
  9. En la caja de c贸digo a帽adimos o siguiente sustituyendo API KEY por la que hemos copiado en pasos anteriores:
    <AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
     
        <!-- Sets a new value to the existing parameter -->
        <Add>
            <Headers>
                <Header name="apikey">{hc_apikey}</Header>
            </Headers>
    </Add>
        <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
        <AssignTo/>
    </AssignMessage>

  10. Hacemos click en update en la parte superior derecha de la pantalla y deplegamos el API (si no lo hemos hecho ya).
  11. Ahora que ya tenemos listo el API, vamos a probarlo, en este caso es tan sencillo como hacer click en el link API Proxy URL:

    Si ejecutamos la siguiente URI https://XXXXXX-trial.integrationsuitetrial-apim.eu10.hana.ondemand.com/XXXXXX/EmpEmployment?$top=1&$format=json obtendremos el siguiente JSON:

    {
    "d": {
    "results": [
    {
    "__metadata": {
    "uri": "https://sandbox.api.sap.com/successfactors/odata/v2/EmpEmployment(personIdExternal='109031',userId='109031')",
    "type": "SFOData.EmpEmployment"
    },
    "personIdExternal": "109031",
    "userId": "109031",
    "hiringNotCompleted": false,
    "isECRecord": true,
    "lastModifiedDateTime": "/Date(1442368786000+0000)/",
    "serviceDate": "/Date(858556800000)/",
    "endDate": null,
    "bonusPayExpirationDate": null,
    "createdDateTime": "/Date(1442367865000+0000)/",
    "isContingentWorker": false,
    "prevEmployeeId": null,
    "regretTermination": null,
    "createdOn": "/Date(1442353465000)/",
    "lastDateWorked": null,
    "firstDateWorked": "/Date(858556800000)/",
    "originalStartDate": "/Date(858556800000)/",
    "payrollEndDate": null,
    "benefitsEligibilityStartDate": "/Date(858556800000)/",
    "initialOptionGrant": null,
    "StockEndDate": null,
    "initialStockGrant": null,
    "employeeFirstEmployment": null,
    "benefitsEndDate": null,
    "eligibleForStock": false,
    "eligibleForSalContinuation": null,
    "assignmentClass": "ST",
    "lastModifiedBy": "admindlr",
    "okToRehire": null,
    "assignmentIdExternal": "109031",
    "lastModifiedOn": "/Date(1442354386000)/",
    "createdBy": "admindlr",
    "professionalServiceDate": null,
    "salaryEndDate": null,
    "seniorityDate": "/Date(858556800000)/",
    "startDate": "/Date(858556800000)/",
    "empGlobalAssignmentNav": {
    "__deferred": {
    "uri": "https://sandbox.api.sap.com/successfactors/odata/v2/EmpEmployment(personIdExternal='109031',userId='109031')/empGlobalAssignmentNav"
    }
    },
    "paymentInformationNav": {
    "__deferred": {
    "uri": "https://sandbox.api.sap.com/successfactors/odata/v2/EmpEmployment(personIdExternal='109031',userId='109031')/paymentInformationNav"
    }
    },
    "empJobRelationshipNav": {
    "__deferred": {
    "uri": "https://sandbox.api.sap.com/successfactors/odata/v2/EmpEmployment(personIdExternal='109031',userId='109031')/empJobRelationshipNav"
    }
    },
    "personNav": {
    "__deferred": {
    "uri": "https://sandbox.api.sap.com/successfactors/odata/v2/EmpEmployment(personIdExternal='109031',userId='109031')/personNav"
    }
    },
    "empWorkPermitNav": {
    "__deferred": {
    "uri": "https://sandbox.api.sap.com/successfactors/odata/v2/EmpEmployment(personIdExternal='109031',userId='109031')/empWorkPermitNav"
    }
    },
    "compInfoNav": {
    "__deferred": {
    "uri": "https://sandbox.api.sap.com/successfactors/odata/v2/EmpEmployment(personIdExternal='109031',userId='109031')/compInfoNav"
    }
    },
    "userNav": {
    "__deferred": {
    "uri": "https://sandbox.api.sap.com/successfactors/odata/v2/EmpEmployment(personIdExternal='109031',userId='109031')/userNav"
    }
    },
    "jobInfoNav": {
    "__deferred": {
    "uri": "https://sandbox.api.sap.com/successfactors/odata/v2/EmpEmployment(personIdExternal='109031',userId='109031')/jobInfoNav"
    }
    },
    "wfRequestNav": {
    "__deferred": {
    "uri": "https://sandbox.api.sap.com/successfactors/odata/v2/EmpEmployment(personIdExternal='109031',userId='109031')/wfRequestNav"
    }
    },
    "empPayCompNonRecurringNav": {
    "__deferred": {
    "uri": "https://sandbox.api.sap.com/successfactors/odata/v2/EmpEmployment(personIdExternal='109031',userId='109031')/empPayCompNonRecurringNav"
    }
    }
    }
    ]
    }
    }

Ahora vamos a modelar nuestro workflow, para ello accedemos a nuestro espacio de desarrollo de SAP Business Application Studio y creamos un proyecto de workflow (importando m贸dulos necesarios para workflows y con su archivo .workflow)

  • Creamos una tarea de tipo聽Service Task con los siguientes datos:

  1. Destination de nuestro portal API.
    [wp-svg-icons icon=”bubbles-4″ wrap=”i”] Recuerda que una service task necesita un servicio para ejecutarse. Este servicio se dar谩 por una destination. Tambi茅n puedes crear una nueva destination en el workflow service configuration cockpit en lugar de usar la destination a nivel de subcuenta. De esta manera puedes definir una detination que estar谩 disponible para seleccionar la aplicaci贸n.
  2. Aqu铆 podemos jugar con la consulta que queramos realizar en la URI.
    [wp-svg-icons icon=”bubbles-4″ wrap=”i”] Este es el recurso al que la service task acceder谩 de la destination. No es un campo obligatorio, pero puedes dar el nombre del recurso al que se va a acceder. El path puede consistir en variables. Por ejemplo, servicios que se llaman desde una service task pueden soportar el formato JSON para el cuerpo de la petici贸n y la respuesta. Por lo que, el servicio del workflow env铆a el header聽Content-Type: application/json en cada petici贸n HTTP y espera el retorno del servicio聽Accept:application/json. El servicio de workflow en tiempo de ejecuci贸n rechaza otras respuestas, que pueden llevar a error. Aseg煤rate que la URL que se concatena desde la destination y el path sean v谩lidos. El servicio de workflow en tiempo de ejecuci贸n asegura la codificaci贸n adecuada de la URL final que ser谩 llamada. Para evitar la codificaci贸n doble, no introduzcas la URL especificada en la destination, el valor para la propiedad path, o la propiedad path XSRF en un formato codificado.
  3. En este caso vamos a ejecutar una operaci贸n GET
    [wp-svg-icons icon=”bubbles-4″ wrap=”i”] Estos son los m茅todos de la llamada del servicio. Por ejemplo, escoger el m茅todo聽POST asegura la modificaci贸n del dato. O, por ejemplo, elegir聽GET asegura que obtienes algo en el return de la llamada al servicio.
  4. Variable donde queremos guardar los resultados de la consulta.
  • [Opcional] He a帽adido una task script para modificar el valor del campo createdBy para poner el nombre completo del usuario y probar este tipo de tarea. En el Script que se asocia a la tarea he a帽adido un c贸digo simple:
    // read from existing workflow context 
    for (let i = 0; i < $.context.EmpEmployment.d.results.length; i++) {
        if (i = 0) {
            $.context.EmpEmployment.d.results[i].createdBy = "Conchita Brust";
        }else{
            $.context.EmpEmployment.d.results[i].createdBy = "Roc铆o Jurado"
        }
    }
  • [Opcional] He creado una tarea de usuario para visualizar los datos en un formulario, pero igualmente se podr谩 ver el context en el servicio de Workflow Management con el siguiente form:
  • Hacemos Build en nuestro archivo mta.yaml para generar el archivo .mtar. Despues desplegamos el archivo .mtar en nuestra cuenta de CF.
  • Accedemos a Workflow Management > Monitor Workflows (Workflow definition) e iniciamos una nueva instancia.
  • Para ver los datos recuperados podemos entrar en Workflow Management > Monitor Workflows (Workflow instances) y en la variable que indicamos en el modelado de nuestro workflow (context.EmpEmployment).

    Tambi茅n podemos ver los pasos ejecutados en el workflow y cu谩nto tiempo ha tardado nuestra consulta:
  • [Opcional] Si hemos creado la pantalla para visualizar datos en una tarea de usuarios, podemos entrar en My Inbox para visualizar el work item.

Con esto ya habr铆amos creado un workflow con una task service asociada a un OData de nuestro API Management 隆Espero que os haya sido de ayuda!

[wp-svg-icons icon=”github-3″ wrap=”i”]https://github.com/saradasilva/sapworkbench-WF-serviceTask

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *