diff --git a/.github/workflows/sync-and-deploy.yml b/.github/workflows/sync-and-deploy.yml new file mode 100644 index 0000000..134a7bf --- /dev/null +++ b/.github/workflows/sync-and-deploy.yml @@ -0,0 +1,57 @@ +# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions +name: sync-and-deploy +on: + workflow_dispatch: + push: + branches: + - devtober-demo + +jobs: +# Unit test + unit_test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + java-version: '8' + distribution: 'temurin' + - name: 'Local unit test with Maven' + run: mvn clean test + +# Sync designtime artifact to tenant + sync: + runs-on: ubuntu-latest + needs: unit_test + container: + image: engswee/flashpipe:latest + steps: + - uses: actions/checkout@v4 + + - name: 'Update/Upload Groovy XML Transformation to design time' + uses: engswee/flashpipe-action/sync@v1 + with: + tmn-host: equaliseit.it-cpi023.cfapps.eu20-001.hana.ondemand.com + oauth-host: equaliseit.authentication.eu20.hana.ondemand.com + oauth-clientid: ${{ secrets.DEV_CLIENT_ID }} + oauth-clientsecret: ${{ secrets.DEV_CLIENT_SECRET }} + target: tenant + package-id: FlashPipeDemo + + # Deploy to runtime + deploy: + runs-on: ubuntu-latest + needs: sync + container: + image: engswee/flashpipe:latest + steps: + - uses: actions/checkout@v4 + + - name: 'Deploy Groovy XML Transformation to runtime' + uses: engswee/flashpipe-action/deploy@v1 + with: + tmn-host: equaliseit.it-cpi023.cfapps.eu20-001.hana.ondemand.com + oauth-host: equaliseit.authentication.eu20.hana.ondemand.com + oauth-clientid: ${{ secrets.DEV_CLIENT_ID }} + oauth-clientsecret: ${{ secrets.DEV_CLIENT_SECRET }} + artifact-ids: GroovyXMLTransformation diff --git a/Demo_Flow/META-INF/MANIFEST.MF b/Demo_Flow/META-INF/MANIFEST.MF index e907819..a7abfbb 100644 --- a/Demo_Flow/META-INF/MANIFEST.MF +++ b/Demo_Flow/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Demo Flow Bundle-SymbolicName: Demo_Flow; singleton:=true -Bundle-Version: 0.1.0 +Bundle-Version: 0.1.1 SAP-BundleType: IntegrationFlow SAP-NodeType: IFLMAP SAP-RuntimeProfile: iflmap diff --git a/Demo_Flow/pom.xml b/Demo_Flow/pom.xml new file mode 100644 index 0000000..fe590a8 --- /dev/null +++ b/Demo_Flow/pom.xml @@ -0,0 +1,14 @@ + + 4.0.0 + + + com.equaliseit + flashpipe-demo + 1.0.0 + + + Demo_Flow + 1.0.0 + + \ No newline at end of file diff --git a/Demo_Flow/src/main/resources/scenarioflows/integrationflow/Demo Flow.iflw b/Demo_Flow/src/main/resources/scenarioflows/integrationflow/Demo Flow.iflw index 13a344f..5f80111 100644 --- a/Demo_Flow/src/main/resources/scenarioflows/integrationflow/Demo Flow.iflw +++ b/Demo_Flow/src/main/resources/scenarioflows/integrationflow/Demo Flow.iflw @@ -217,7 +217,7 @@ script - script1.groovy + XMLTransformation.groovy SequenceFlow_3 diff --git a/Demo_Flow/src/main/resources/script/XMLTransformation.groovy b/Demo_Flow/src/main/resources/script/XMLTransformation.groovy new file mode 100644 index 0000000..c7f1762 --- /dev/null +++ b/Demo_Flow/src/main/resources/script/XMLTransformation.groovy @@ -0,0 +1,37 @@ +import com.sap.gateway.ip.core.customdev.util.Message +import com.sap.it.api.ITApiFactory +import com.sap.it.api.mapping.ValueMappingApi +import groovy.xml.MarkupBuilder + +import java.text.SimpleDateFormat + +def Message processData(Message message) { + Reader reader = message.getBody(Reader) + def Order = new XmlSlurper().parse(reader) + Writer writer = new StringWriter() + def builder = new MarkupBuilder(writer) + + def sourceDocType = message.getProperty('DocType') + ValueMappingApi api = ITApiFactory.getService(ValueMappingApi, null) + + def items = Order.Item.findAll { it.Valid.text() == 'true' } + builder.PurchaseOrder { + 'Header' { + 'ID' Order.Header.OrderNumber + 'DocumentDate' new SimpleDateFormat('yyyy-MM-dd').format(new SimpleDateFormat('yyyyMMdd').parse(Order.Header.Date.text())) + if (!items.size()) + 'DocumentType' api.getMappedValue('S4', 'DocType', sourceDocType, 'ACME', 'DocumentType') + } + + items.each { item -> + 'Item' { + 'ItemNumber' item.ItemNumber.text().padLeft(3, '0') + 'ProductCode' item.MaterialNumber + 'Quantity' item.Quantity + } + } + } + + message.setBody(writer.toString()) + return message +} \ No newline at end of file diff --git a/Demo_Flow/src/main/resources/script/script1.groovy b/Demo_Flow/src/main/resources/script/script1.groovy deleted file mode 100644 index 42c0f9e..0000000 --- a/Demo_Flow/src/main/resources/script/script1.groovy +++ /dev/null @@ -1,24 +0,0 @@ -/* Refer the link below to learn more about the use cases of script. -https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/Cloud/en-GB/148851bf8192412cba1f9d2c17f4bd25.html - -If you want to know more about the SCRIPT APIs, refer the link below -https://help.sap.com/doc/a56f52e1a58e4e2bac7f7adbf45b2e26/Cloud/en-GB/index.html */ -import com.sap.gateway.ip.core.customdev.util.Message; -import java.util.HashMap; -def Message processData(Message message) { - //Body - def body = message.getBody(); -/*To set the body, you can use the following method. Refer SCRIPT APIs document for more detail*/ - //message.setBody(body + " Body is modified"); - //Headers - def headers = message.getHeaders(); - def value = headers.get("oldHeader"); - message.setHeader("oldHeader", value + " modified"); - message.setHeader("newHeader", "newHeader"); - //Properties - def properties = message.getProperties(); - value = properties.get("oldProperty"); - message.setProperty("oldProperty", value + " modified"); - message.setProperty("newProperty", "newProperty"); - return message; -} \ No newline at end of file diff --git a/Demo_Flow/src/test/groovy/XMLTransformationSpec.groovy b/Demo_Flow/src/test/groovy/XMLTransformationSpec.groovy new file mode 100644 index 0000000..e3d94b4 --- /dev/null +++ b/Demo_Flow/src/test/groovy/XMLTransformationSpec.groovy @@ -0,0 +1,61 @@ +import com.sap.gateway.ip.core.customdev.util.Message +import com.sap.it.api.mapping.ValueMappingApi +import spock.lang.Shared +import spock.lang.Specification + +class XMLTransformationSpec extends Specification { + @Shared + Script script + Message msg + + def setupSpec() { + GroovyShell shell = new GroovyShell() + script = shell.parse(this.getClass().getResource('/script/XMLTransformation.groovy').toURI()) + } + + def setup() { + msg = new Message() + } + + def 'Scenario 1 - Order has items'() { + given: 'the message body is initialized' + msg.setBody(this.getClass().getResource('input1.xml').newInputStream()) + + when: 'we execute the Groovy script' + script.processData(msg) + + then: 'the output message body is as expected' + def root = new XmlSlurper().parse(msg.getBody(Reader)) + verifyAll { + root.Header.ID.text() == 'ORD60001' + root.Header.DocumentDate.text() == '2019-02-18' + root.Header.DocumentType.text() == '' + root.Item.size() == 1 + root.Item.ItemNumber.text() == '010' + root.Item.ProductCode.text() == 'MT70001' + root.Item.Quantity.text() == '57' + } + } + + def 'Scenario 2 - Order does not have items'() { + given: 'the message body and property are initialized' + msg.setBody(this.getClass().getResource('input2.xml').newInputStream()) + msg.setProperty('DocType', 'HDR') + + // Set up value mapping entries + ValueMappingApi vmapi = ValueMappingApi.getInstance() + vmapi.addEntry('S4', 'DocType', 'HDR', 'ACME', 'DocumentType', 'ACME-HDR') + + when: 'we execute the Groovy script' + script.processData(msg) + + then: 'the output message body is as expected' + def root = new XmlSlurper().parse(msg.getBody(Reader)) + verifyAll { + root.Header.ID.text() == 'ORD80002' + root.Header.DocumentDate.text() == '2020-02-18' + root.Header.DocumentType.text() == 'ACME-HDR' + root.Item.size() == 0 + } + } +} \ No newline at end of file diff --git a/Demo_Flow/src/test/resources/input1.xml b/Demo_Flow/src/test/resources/input1.xml new file mode 100644 index 0000000..489e661 --- /dev/null +++ b/Demo_Flow/src/test/resources/input1.xml @@ -0,0 +1,18 @@ + +
+ ORD60001 + 20190218 +
+ + 10 + MT70001 + 57 + true + + + 20 + MT80001 + 28 + false + +
\ No newline at end of file diff --git a/Demo_Flow/src/test/resources/input2.xml b/Demo_Flow/src/test/resources/input2.xml new file mode 100644 index 0000000..f3e630e --- /dev/null +++ b/Demo_Flow/src/test/resources/input2.xml @@ -0,0 +1,12 @@ + +
+ ORD80002 + 20200218 +
+ + 10 + MT90001 + 55 + false + +
\ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..74da3d5 --- /dev/null +++ b/pom.xml @@ -0,0 +1,159 @@ + + 4.0.0 + + com.equaliseit + flashpipe-demo + 1.0.0 + pom + + + UTF-8 + 8 + 2.4.21 + 2.17.1 + 1.3-groovy-2.4 + 2.24.2 + + + + Demo_Flow + + + + + + org.codehaus.groovy + groovy-all + ${groovy.all.version} + + + org.spockframework + spock-core + ${spock.version} + test + + + + + + + org.codehaus.groovy + groovy-all + + + org.spockframework + spock-core + + + org.apache.camel + camel-core + ${camel.core.version} + + + org.apache.logging.log4j + log4j-api + ${log4j.version} + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + + + org.apache.logging.log4j + log4j-slf4j-impl + ${log4j.version} + + + com.equaliseit + sap-cpi-mocks + 1.0.2 + + + + + + + + + + + src/main/resources/script + + + maven-surefire-plugin + + false + + **/*Spec.java + **/*Test.java + + + + + org.codehaus.gmavenplus + gmavenplus-plugin + 1.9.0 + + + + addSources + addTestSources + compile + compileTests + + + + + + + + + maven-dependency-plugin + 3.1.2 + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.1.0 + + + maven-compiler-plugin + 3.8.1 + + ${jdk.version} + + + + maven-surefire-plugin + 2.22.2 + + + maven-jar-plugin + 3.2.0 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + + + + gitlab-maven + https://gitlab.com/api/v4/groups/12926885/-/packages/maven + + + \ No newline at end of file