├── .che ├── modules └── project.json ├── .github ├── FUNDING.yml ├── dependabot.yml └── workflows │ ├── mta-build-push.yml │ └── mta-release.yml ├── .gitignore ├── .npmrc ├── .nvmrc ├── .pipeline └── config.yml ├── .vscode └── settings.json ├── HTML5Module ├── .npmrc ├── package-lock.json ├── package.json ├── ui5-deploy.yaml ├── webapp │ ├── Component.js │ ├── controller │ │ └── Home.controller.js │ ├── css │ │ └── style.css │ ├── i18n │ │ └── i18n.properties │ ├── iframe.html │ ├── index.html │ ├── logout-page.html │ ├── manifest.json │ ├── model │ │ └── models.js │ ├── test │ │ ├── integration │ │ │ ├── AllJourneys.js │ │ │ ├── NavigationJourney.js │ │ │ ├── arrangements │ │ │ │ └── Startup.js │ │ │ ├── opaTests.qunit.html │ │ │ ├── opaTests.qunit.js │ │ │ └── pages │ │ │ │ └── Home.js │ │ ├── testsuite.qunit.html │ │ ├── testsuite.qunit.js │ │ └── unit │ │ │ ├── AllTests.js │ │ │ ├── controller │ │ │ └── Home.controller.js │ │ │ ├── unitTests.qunit.html │ │ │ └── unitTests.qunit.js │ └── view │ │ └── Home.view.xml └── xs-app.json ├── LICENSE ├── Principal-Propagation.md ├── README.md ├── approuter ├── .npmrc ├── approuter-start.js ├── my-ext.js ├── package-lock.json ├── package.json └── xs-app.json ├── mta.yaml ├── package-lock.json ├── package.json ├── srv-java ├── .project ├── .settings │ ├── org.eclipse.core.resources.prefs │ └── org.eclipse.m2e.core.prefs ├── Jenkinsfile ├── application │ ├── .classpath │ ├── .project │ ├── .settings │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.eclipse.jdt.apt.core.prefs │ │ ├── org.eclipse.jdt.core.prefs │ │ └── org.eclipse.m2e.core.prefs │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── rfctest │ │ │ │ ├── HelloWorldServlet.java │ │ │ │ └── RfcServlet.java │ │ └── webapp │ │ │ ├── WEB-INF │ │ │ ├── beans.xml │ │ │ └── web.xml │ │ │ └── index.html │ │ └── test │ │ └── java │ │ └── rfctest │ │ └── UnitTest.java ├── cx-server │ ├── cx-server │ ├── cx-server-completion.bash │ ├── cx-server.bat │ └── server.cfg ├── integration-tests │ ├── .classpath │ ├── .project │ ├── .settings │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.eclipse.jdt.apt.core.prefs │ │ ├── org.eclipse.jdt.core.prefs │ │ └── org.eclipse.m2e.core.prefs │ ├── pom.xml │ └── src │ │ └── test │ │ └── java │ │ └── rfctest │ │ ├── HelloWorldServletTest.java │ │ └── TestUtil.java ├── manifest.yml └── pom.xml ├── srv ├── .npmrc ├── express.js ├── package-lock.json └── package.json ├── test ├── approuter.http ├── basic-auth.http └── call-srv.http └── xs-security.json /.che/modules: -------------------------------------------------------------------------------- 1 | html5userapiforcf-ui 2 | -------------------------------------------------------------------------------- /.che/project.json: -------------------------------------------------------------------------------- 1 | {"type":"mta","builders":{"default":"mtabuilder","configs":{}},"runners":{"configs":{}},"attributes":{"sap.watt.common.setting":["{\"generation\":[{\"templateId\":\"hanatemplates.hcpmtaproject\",\"templateVersion\":\"1.0.0\",\"dateTimeStamp\":\"Sun, 17 Nov 2019 17:07:20 GMT\"}],\"translation\":{\"translationDomain\":\"\",\"supportedLanguages\":\"en,fr,de\",\"defaultLanguage\":\"en\",\"defaultI18NPropertyFile\":\"i18n.properties\",\"resourceModelName\":\"i18n\"},\"basevalidator\":{\"services\":{\"js\":\"jsValidator\",\"json\":\"jsonValidator\",\"xml\":\"xmlValidator\"}}}"]},"mixinTypes":[]} -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [gregorwolf] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: gregorwolf # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Maintain dependencies for GitHub Actions 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | # Maintain dependencies for npm 9 | - package-ecosystem: "npm" 10 | directory: "/" 11 | schedule: 12 | interval: "daily" 13 | # Maintain dependencies for Docker 14 | - package-ecosystem: "docker" 15 | directory: "/" 16 | schedule: 17 | interval: "daily" -------------------------------------------------------------------------------- /.github/workflows/mta-build-push.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths-ignore: 8 | - '.github/**' 9 | - 'README.md' 10 | 11 | jobs: 12 | main: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v3 18 | - name: pwd 19 | run: pwd 20 | - uses: actions/setup-node@v3 21 | with: 22 | node-version: 20 23 | cache: 'npm' 24 | - name: Check node version 25 | run: node --version 26 | - name: Install MTA Build Tool 27 | run: npm install -g mbt 28 | - name: Install Packages 29 | shell: bash 30 | env: 31 | SAP_NPM_AUTH: ${{ secrets.SAP_NPM_AUTH }} 32 | run: npm install ci 33 | - name: MTA build 34 | uses: SAP/project-piper-action@master 35 | with: 36 | command: mtaBuild 37 | - name: Upload archive file 38 | uses: actions/upload-artifact@v3 39 | with: 40 | name: mta 41 | path: html5userapi.mtar 42 | -------------------------------------------------------------------------------- /.github/workflows/mta-release.yml: -------------------------------------------------------------------------------- 1 | name: mta-release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | release: 10 | name: Upload Release Asset 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Download CF artifact 15 | uses: dawidd6/action-download-artifact@v6 16 | with: 17 | workflow: mta-build-push.yml 18 | workflow_conclusion: success 19 | name: mta 20 | - name: Display structure of downloaded files 21 | run: ls -R 22 | - name: Release 23 | uses: softprops/action-gh-release@v1 24 | if: startsWith(github.ref, 'refs/tags/') 25 | with: 26 | files: | 27 | html5userapi.mtar 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | fioriHtmlRunner.html 2 | .*/fioriHtmlRunner.html 3 | visual_ext_index.html 4 | /webapp/visual_ext_index.html 5 | extended_runnable_file.html 6 | .*/extended_runnable_file.html 7 | sap-ui-cachebuster-info.json 8 | mock_preview_sapui5.html 9 | .*/mock_preview_sapui5.html 10 | UIAdaptation_index.html 11 | changes_preview.js 12 | AppVariant_index.html 13 | AppVariantPreviewPayload.zip 14 | mergedManifestDescriptor.json 15 | APIExternalProducer.js 16 | .*/APIExternalProducer.js 17 | /mta_archives/ 18 | node_modules/ 19 | preview.json 20 | cp.project.properties.json 21 | Makefile* 22 | dist/ 23 | *-env.json 24 | resources/ 25 | .mta/ 26 | target 27 | .env -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.com/ 2 | //73555000100200018064.npmsrv.cdn.repositories.cloud.sap/:_auth=${SAP_NPM_AUTH} 3 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v22 2 | -------------------------------------------------------------------------------- /.pipeline/config.yml: -------------------------------------------------------------------------------- 1 | general: 2 | steps: 3 | mtaBuild: 4 | platform: 'CF' 5 | mtarName: html5userapi.mtar 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "java.configuration.updateBuildConfiguration": "automatic", 3 | "java.compile.nullAnalysis.mode": "automatic" 4 | } 5 | -------------------------------------------------------------------------------- /HTML5Module/.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.com/ 2 | -------------------------------------------------------------------------------- /HTML5Module/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "html5userapi-ui", 3 | "version": "1.1.23", 4 | "description": "", 5 | "engines": { 6 | "node": "^22" 7 | }, 8 | "dependencies": {}, 9 | "devDependencies": { 10 | "@sap/approuter": "^20", 11 | "@sap/html5-repo-mock": "^2", 12 | "@sap/ux-specification": "^1.108.2", 13 | "@sap/ux-ui5-tooling": "^1", 14 | "@ui5/cli": "^4", 15 | "@ui5/fs": "^4", 16 | "@ui5/logger": "^4", 17 | "rimraf": "^5", 18 | "ui5-task-zipper": "^3" 19 | }, 20 | "scripts": { 21 | "start": "ui5 serve --config ui5-deploy.yaml", 22 | "build": "npm version patch && ui5 build preload --clean-dest --config ui5-deploy.yaml --include-task=generateManifestBundle generateCachebusterInfo", 23 | "clean": "npx rimraf dist", 24 | "start-local": "export VCAP_SERVICES=`cat default-env.json | jq .VCAP_SERVICES` && node node_modules/@sap/html5-repo-mock/index.js" 25 | }, 26 | "ui5": { 27 | "dependencies": [ 28 | "ui5-task-zipper" 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /HTML5Module/ui5-deploy.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://sap.github.io/ui5-tooling/schema/ui5.yaml.json 2 | specVersion: '3.0' 3 | metadata: 4 | name: com.sap.sapmentors.html5userapiforcf-ui 5 | type: application 6 | resources: 7 | configuration: 8 | propertiesFileSourceEncoding: UTF-8 9 | builder: 10 | resources: 11 | excludes: 12 | - "/test/**" 13 | - "/localService/**" 14 | customTasks: 15 | - name: ui5-task-zipper 16 | afterTask: generateCachebusterInfo 17 | configuration: 18 | archiveName: HTML5Module-content 19 | additionalFiles: 20 | - xs-app.json 21 | -------------------------------------------------------------------------------- /HTML5Module/webapp/Component.js: -------------------------------------------------------------------------------- 1 | sap.ui.define(["sap/ui/core/UIComponent"], function (UIComponent) { 2 | "use strict"; 3 | 4 | return UIComponent.extend( 5 | "com.sap.sapmentors.html5userapiforcf-ui.Component", 6 | { 7 | metadata: { 8 | manifest: "json", 9 | }, 10 | 11 | /** 12 | * The component is initialized by UI5 automatically during the startup of the app and calls the init method once. 13 | * @public 14 | * @override 15 | */ 16 | init: function () { 17 | // call the base component's init function 18 | UIComponent.prototype.init.apply(this, arguments); 19 | 20 | // enable routing 21 | this.getRouter().initialize(); 22 | }, 23 | } 24 | ); 25 | }); 26 | -------------------------------------------------------------------------------- /HTML5Module/webapp/controller/Home.controller.js: -------------------------------------------------------------------------------- 1 | sap.ui.define( 2 | ["sap/ui/core/mvc/Controller", "sap/ui/core/Manifest"], 3 | function (Controller, Manifest) { 4 | "use strict"; 5 | 6 | return Controller.extend( 7 | "com.sap.sapmentors.html5userapiforcf-ui.controller.Home", 8 | { 9 | onInit: function () { 10 | var url = this.getOwnerComponent() 11 | .getManifestObject() 12 | .resolveUri("./"); 13 | console.log(url); 14 | let oManifest = Manifest.load({ manifestUrl: url + "manifest.json" }); 15 | let version = oManifest.getEntry( 16 | "/sap.app/applicationVersion/version" 17 | ); 18 | console.log(version); 19 | let versionText = this.byId("versionText"); 20 | versionText.setText(version); 21 | }, 22 | } 23 | ); 24 | } 25 | ); 26 | -------------------------------------------------------------------------------- /HTML5Module/webapp/css/style.css: -------------------------------------------------------------------------------- 1 | /* Enter your custom styles here */ -------------------------------------------------------------------------------- /HTML5Module/webapp/i18n/i18n.properties: -------------------------------------------------------------------------------- 1 | title=HTML5 User API for Cloud Foundry 2 | appTitle=HTML5 User API for Cloud Foundry 3 | appDescription=HTML5 User API for Cloud Foundry -------------------------------------------------------------------------------- /HTML5Module/webapp/iframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | HTML5UserAPI 8 | 9 | 10 | 11 |

Fiori Launchpad im iFrame

12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /HTML5Module/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | HTML5 User API for Cloud Foundry 7 | 8 | 11 | 21 | 22 | 23 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /HTML5Module/webapp/logout-page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | HTML5 User API for Cloud Foundry - Logged out 7 | 8 | 9 | 10 |

HTML5 User API for Cloud Foundry

11 |

You're now logged out.

12 |

Login again

13 | 14 | 15 | -------------------------------------------------------------------------------- /HTML5Module/webapp/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "_version": "1.12.0", 3 | "sap.cloud": { 4 | "public": true, 5 | "service": "cloud.service" 6 | }, 7 | "sap.app": { 8 | "id": "com.sap.sapmentors.html5userapiforcf-ui", 9 | "type": "application", 10 | "i18n": "i18n/i18n.properties", 11 | "applicationVersion": { 12 | "version": "${version}" 13 | }, 14 | "title": "{{appTitle}}", 15 | "description": "{{appDescription}}", 16 | "sourceTemplate": { 17 | "id": "html5moduletemplates.basicSAPUI5ApplicationProjectModule", 18 | "version": "1.40.12" 19 | }, 20 | "crossNavigation": { 21 | "inbounds": { 22 | "intent1": { 23 | "signature": { 24 | "parameters": {}, 25 | "additionalParameters": "allowed" 26 | }, 27 | "semanticObject": "User", 28 | "action": "display", 29 | "title": "User", 30 | "subTitle": "Details", 31 | "icon": "sap-icon://user-settings" 32 | } 33 | } 34 | } 35 | }, 36 | "sap.ui": { 37 | "technology": "UI5", 38 | "icons": { 39 | "icon": "", 40 | "favIcon": "", 41 | "phone": "", 42 | "phone@2": "", 43 | "tablet": "", 44 | "tablet@2": "" 45 | }, 46 | "deviceTypes": { 47 | "desktop": true, 48 | "tablet": true, 49 | "phone": true 50 | } 51 | }, 52 | "sap.ui5": { 53 | "flexEnabled": false, 54 | "rootView": { 55 | "viewName": "com.sap.sapmentors.html5userapiforcf-ui.view.Home", 56 | "type": "XML", 57 | "async": true, 58 | "id": "Home" 59 | }, 60 | "dependencies": { 61 | "minUI5Version": "1.65.6", 62 | "libs": { 63 | "sap.ui.core": {}, 64 | "sap.m": {}, 65 | "sap.ui.layout": {} 66 | } 67 | }, 68 | "contentDensities": { 69 | "compact": true, 70 | "cozy": true 71 | }, 72 | "models": { 73 | "i18n": { 74 | "type": "sap.ui.model.resource.ResourceModel", 75 | "settings": { 76 | "bundleName": "com.sap.sapmentors.html5userapiforcf-ui.i18n.i18n" 77 | } 78 | } 79 | }, 80 | "resources": { 81 | "css": [ 82 | { 83 | "uri": "css/style.css" 84 | } 85 | ] 86 | }, 87 | "routing": { 88 | "config": { 89 | "routerClass": "sap.m.routing.Router", 90 | "viewType": "XML", 91 | "async": true, 92 | "viewPath": "com.sap.sapmentors.html5userapiforcf-ui.view", 93 | "controlAggregation": "pages", 94 | "controlId": "app", 95 | "clearControlAggregation": false 96 | }, 97 | "routes": [ 98 | { 99 | "name": "RouteHome", 100 | "pattern": "RouteHome", 101 | "target": ["TargetHome"] 102 | } 103 | ], 104 | "targets": { 105 | "TargetHome": { 106 | "viewType": "XML", 107 | "transition": "slide", 108 | "clearControlAggregation": false, 109 | "viewId": "Home", 110 | "viewName": "Home" 111 | } 112 | } 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /HTML5Module/webapp/model/models.js: -------------------------------------------------------------------------------- 1 | sap.ui.define([ 2 | "sap/ui/model/json/JSONModel", 3 | "sap/ui/Device" 4 | ], function (JSONModel, Device) { 5 | "use strict"; 6 | 7 | return { 8 | 9 | createDeviceModel: function () { 10 | var oModel = new JSONModel(Device); 11 | oModel.setDefaultBindingMode("OneWay"); 12 | return oModel; 13 | } 14 | 15 | }; 16 | }); -------------------------------------------------------------------------------- /HTML5Module/webapp/test/integration/AllJourneys.js: -------------------------------------------------------------------------------- 1 | sap.ui.define( 2 | ["sap/ui/test/Opa5", "./arrangements/Startup", "./NavigationJourney"], 3 | function (Opa5, Startup) { 4 | "use strict"; 5 | 6 | Opa5.extendConfig({ 7 | arrangements: new Startup(), 8 | viewNamespace: "com.sap.sapmentors.html5userapiforcf-ui.view.", 9 | autoWait: true, 10 | }); 11 | } 12 | ); 13 | -------------------------------------------------------------------------------- /HTML5Module/webapp/test/integration/NavigationJourney.js: -------------------------------------------------------------------------------- 1 | /*global QUnit*/ 2 | 3 | sap.ui.define([ 4 | "sap/ui/test/opaQunit", 5 | "./pages/Home" 6 | ], function (opaTest) { 7 | "use strict"; 8 | 9 | QUnit.module("Navigation Journey"); 10 | 11 | opaTest("Should see the initial page of the app", function (Given, When, Then) { 12 | // Arrangements 13 | Given.iStartMyApp(); 14 | 15 | // Assertions 16 | Then.onTheAppPage.iShouldSeeTheApp(); 17 | 18 | //Cleanup 19 | Then.iTeardownMyApp(); 20 | }); 21 | }); -------------------------------------------------------------------------------- /HTML5Module/webapp/test/integration/arrangements/Startup.js: -------------------------------------------------------------------------------- 1 | sap.ui.define(["sap/ui/test/Opa5"], function (Opa5) { 2 | "use strict"; 3 | 4 | return Opa5.extend( 5 | "com.sap.sapmentors.html5userapiforcf-ui.test.integration.arrangements.Startup", 6 | { 7 | iStartMyApp: function (oOptionsParameter) { 8 | var oOptions = oOptionsParameter || {}; 9 | 10 | // start the app with a minimal delay to make tests fast but still async to discover basic timing issues 11 | oOptions.delay = oOptions.delay || 50; 12 | 13 | // start the app UI component 14 | this.iStartMyUIComponent({ 15 | componentConfig: { 16 | name: "com.sap.sapmentors.html5userapiforcf-ui", 17 | async: true, 18 | }, 19 | hash: oOptions.hash, 20 | autoWait: oOptions.autoWait, 21 | }); 22 | }, 23 | } 24 | ); 25 | }); 26 | -------------------------------------------------------------------------------- /HTML5Module/webapp/test/integration/opaTests.qunit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Integration tests for Basic Template 6 | 7 | 18 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /HTML5Module/webapp/test/integration/opaTests.qunit.js: -------------------------------------------------------------------------------- 1 | /* global QUnit */ 2 | QUnit.config.autostart = false; 3 | 4 | sap.ui.getCore().attachInit(function () { 5 | "use strict"; 6 | 7 | sap.ui.require( 8 | ["com/sap/sapmentors/html5userapiforcf-ui/test/integration/AllJourneys"], 9 | function () { 10 | QUnit.start(); 11 | } 12 | ); 13 | }); 14 | -------------------------------------------------------------------------------- /HTML5Module/webapp/test/integration/pages/Home.js: -------------------------------------------------------------------------------- 1 | sap.ui.define([ 2 | "sap/ui/test/Opa5" 3 | ], function (Opa5) { 4 | "use strict"; 5 | var sViewName = "Home"; 6 | Opa5.createPageObjects({ 7 | onTheAppPage: { 8 | 9 | actions: {}, 10 | 11 | assertions: { 12 | 13 | iShouldSeeTheApp: function () { 14 | return this.waitFor({ 15 | id: "app", 16 | viewName: sViewName, 17 | success: function () { 18 | Opa5.assert.ok(true, "The Home view is displayed"); 19 | }, 20 | errorMessage: "Did not find the Home view" 21 | }); 22 | } 23 | } 24 | } 25 | }); 26 | 27 | }); -------------------------------------------------------------------------------- /HTML5Module/webapp/test/testsuite.qunit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | QUnit test suite for Basic Template 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /HTML5Module/webapp/test/testsuite.qunit.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line sap-no-global-define 2 | window.suite = function () { 3 | "use strict"; 4 | /* eslint-disable new-cap */ 5 | var oSuite = new parent.jsUnitTestSuite(), 6 | sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1); 7 | 8 | oSuite.addTestPage(sContextPath + "unit/unitTests.qunit.html"); 9 | oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html"); 10 | 11 | return oSuite; 12 | }; -------------------------------------------------------------------------------- /HTML5Module/webapp/test/unit/AllTests.js: -------------------------------------------------------------------------------- 1 | sap.ui.define( 2 | [ 3 | "com/sap/sapmentors/html5userapiforcf-ui/test/unit/controller/Home.controller", 4 | ], 5 | function () { 6 | "use strict"; 7 | } 8 | ); 9 | -------------------------------------------------------------------------------- /HTML5Module/webapp/test/unit/controller/Home.controller.js: -------------------------------------------------------------------------------- 1 | /*global QUnit*/ 2 | 3 | sap.ui.define( 4 | ["com/sap/sapmentors/html5userapiforcf-ui/controller/Home.controller"], 5 | function (Controller) { 6 | "use strict"; 7 | 8 | QUnit.module("Home Controller"); 9 | 10 | QUnit.test("I should test the Home controller", function (assert) { 11 | var oAppController = new Controller(); 12 | oAppController.onInit(); 13 | assert.ok(oAppController); 14 | }); 15 | } 16 | ); 17 | -------------------------------------------------------------------------------- /HTML5Module/webapp/test/unit/unitTests.qunit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Unit tests for com.sap.sapmentors.html5userapiforcf-ui 6 | 7 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /HTML5Module/webapp/test/unit/unitTests.qunit.js: -------------------------------------------------------------------------------- 1 | /* global QUnit */ 2 | QUnit.config.autostart = false; 3 | 4 | sap.ui.getCore().attachInit(function () { 5 | "use strict"; 6 | 7 | sap.ui.require( 8 | ["com/sap/sapmentors/html5userapiforcf-ui/test/unit/AllTests"], 9 | function () { 10 | QUnit.start(); 11 | } 12 | ); 13 | }); 14 | -------------------------------------------------------------------------------- /HTML5Module/webapp/view/Home.view.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 25 | 26 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 73 | 74 | 75 | 76 | 77 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 103 | 104 | 105 | 106 | 107 | 109 | 110 | 111 | 112 | 113 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 123 | 124 | 125 | 126 | 127 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 137 | 138 | 139 | 140 | 141 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /HTML5Module/xs-app.json: -------------------------------------------------------------------------------- 1 | { 2 | "welcomeFile": "index.html", 3 | "authenticationMethod": "route", 4 | "logout": { 5 | "logoutEndpoint": "/do/logout", 6 | "logoutPage": "/logout-page.html" 7 | }, 8 | "routes": [ 9 | { 10 | "source": "^/user-api(.*)", 11 | "target": "$1", 12 | "service": "sap-approuter-userapi" 13 | }, 14 | { 15 | "source": "^/api/(.*)$", 16 | "target": "/api/$1", 17 | "authenticationType": "xsuaa", 18 | "destination": "html5userapi-srv", 19 | "csrfProtection": true 20 | }, 21 | { 22 | "source": "^/rfc(.*)$", 23 | "target": "/rfc$1", 24 | "authenticationType": "xsuaa", 25 | "destination": "html5userapi-srv-java", 26 | "csrfProtection": true 27 | }, 28 | { 29 | "source": "^/destination/([^/]+)/(.*)$", 30 | "target": "$2", 31 | "destination": "$1" 32 | }, 33 | { 34 | "source": "^/sap/(.*)$", 35 | "target": "/sap/$1", 36 | "destination": "SAP_ABAP_BACKEND" 37 | }, 38 | { 39 | "source": "^/sap_basic/(.*)$", 40 | "target": "/sap/$1", 41 | "destination": "SAP_ABAP_BACKEND_BASIC_AUTH" 42 | }, 43 | { 44 | "source": "^/b1s/(.*)$", 45 | "target": "/b1s/$1", 46 | "destination": "SAP_B1_BACKEND" 47 | }, 48 | { 49 | "source": "^/v2/admin/(.*)$", 50 | "target": "/v2/admin/$1", 51 | "authenticationType": "xsuaa", 52 | "destination": "bookshop", 53 | "csrfProtection": true 54 | }, 55 | { 56 | "source": "^/v2/catalog/(.*)$", 57 | "target": "/v2/catalog/$1", 58 | "authenticationType": "xsuaa", 59 | "destination": "bookshop", 60 | "csrfProtection": true 61 | }, 62 | { 63 | "source": "^/admin/(.*)$", 64 | "target": "/admin/$1", 65 | "authenticationType": "xsuaa", 66 | "destination": "bookshop", 67 | "csrfProtection": true 68 | }, 69 | { 70 | "source": "^/catalog/(.*)$", 71 | "target": "/catalog/$1", 72 | "authenticationType": "xsuaa", 73 | "destination": "bookshop", 74 | "csrfProtection": true 75 | }, 76 | { 77 | "source": "^/logout-page.html$", 78 | "service": "html5-apps-repo-rt", 79 | "authenticationType": "none" 80 | }, 81 | { 82 | "source": "^index.html$", 83 | "service": "html5-apps-repo-rt", 84 | "authenticationType": "xsuaa", 85 | "cacheControl": "no-cache, no-store, must-revalidate" 86 | }, 87 | { 88 | "source": "^(.*)$", 89 | "target": "$1", 90 | "service": "html5-apps-repo-rt", 91 | "authenticationType": "xsuaa" 92 | } 93 | ] 94 | } 95 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [2024] [Gregor Wolf] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Principal-Propagation.md: -------------------------------------------------------------------------------- 1 | # Principal Propagation 2 | 3 | ```mermaid 4 | sequenceDiagram 5 | User->>Approuter: sending request 6 | alt has no JWT 7 | Approuter->>Identity Provider: redirecting 8 | Identity Provider->>Identity Provider: authenticating 9 | Identity Provider->>Identity Provider: granting JWT 10 | Identity Provider->>Approuter: redirecting 11 | else has JWT 12 | Approuter->>Destination Service: requests destination details 13 | Destination Service->>Approuter: returns destination details 14 | Approuter->>Connectivity Service: sends request to connectivity service proxy 15 | Connectivity Service->>Cloud Connector: forward request 16 | Cloud Connector->>Cloud Connector: validates JWT 17 | else with Secure Logon Server 18 | Cloud Connector->>Secure Logon Server: requests X.509 Client Certificate 19 | Secure Logon Server->>Cloud Connector: returns X.509 Client Certificate 20 | else without Secure Logon Server 21 | Cloud Connector->>Cloud Connector: creates X.509 Client Certificate 22 | else Backend request 23 | Cloud Connector->>Backend: establishes mTLS connection with System Certificate and sends X.509 Client Certificate in HTTP Header 24 | Backend->>Connectivity Service: returns response 25 | Connectivity Service->>Approuter: returns response 26 | Approuter->>User: returns response 27 | end 28 | ``` 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HTML5UserAPI for Cloud Foundry 2 | 3 | This project provides a simple MTA application which serves links to a Node.js backend that servers some Endpoints showing user information using Express. It can be deployed as an Multi Target Application to the SAP Cloud Platform - Cloud Foundry Environment. 4 | 5 | ## Deploy to SAP Cloud Platform - Cloud Foundry 6 | 7 | ### Prerequisite 8 | 9 | If you want to deploy the latest released version: 10 | 11 | - You have a [SAP Business Technology Platform Platform Trial](https://hanatrial.ondemand.com/), [Free Tier or productive account](https://cockpit.eu10.hana.ondemand.com/) 12 | - The [Cloud Foundry command line tool](https://docs.cloudfoundry.org/cf-cli/install-go-cli.html) is installed 13 | - The [MultiApps CF CLI Plugin](https://github.com/cloudfoundry-incubator/multiapps-cli-plugin) is installed 14 | - You've connected using `cf login`to your BTP subaccount 15 | - You've connected a [SAP Cloud Connector](https://tools.hana.ondemand.com/#cloud) to your subaccount 16 | - [Principal Propagation is setup in the Cloud Connector to the ABAP Backend](https://blogs.sap.com/2017/06/22/how-to-guide-principal-propagation-in-an-https-scenario/) 17 | 18 | If you want to build the current state of the repository: 19 | 20 | - You have the Node.JS version defined in .nvmrc installed 21 | - The [Cloud MTA Build Tool (MBT)](https://sap.github.io/cloud-mta-build-tool/) is installed 22 | 23 | ### Preperation 24 | 25 | Before you can deploy the application to your Cloud Foundry account the destinations to the backend system must be created. Please find here what I've used in my environment: 26 | 27 | If you want to test the connection to a SAP ABAP Backend via HTTP(S), then you have to create the destination SAP_ABAP_BACKEND used by the approuter: 28 | 29 | ``` 30 | URL=http\://npl752.virtual\:44300 31 | Name=SAP_ABAP_BACKEND 32 | ProxyType=OnPremise 33 | Type=HTTP 34 | sap-client=001 35 | Authentication=PrincipalPropagation 36 | ``` 37 | 38 | If you want to test the connection to the SAP ABAP via RFC, then you have to create the destination SAP_ABAP_BACKEND_RFC used by the Java application: 39 | 40 | ``` 41 | Type=RFC 42 | jco.client.ashost=npl752.virtual 43 | jco.destination.repository.user=SAPUSERNAME 44 | Name=SAP_ABAP_BACKEND_RFC 45 | jco.client.user=SAPUSERNAME 46 | jco.client.sysnr=01 47 | jco.destination.proxy_type=OnPremise 48 | jco.client.client=001 49 | ``` 50 | 51 | If you want to test the connection to the SAP Business One Service Layer via HTTP(S), then the destination SAP_B1_BACKEND must be created: 52 | 53 | ``` 54 | URL=http\://b1server.virtual\:44300 55 | Name=SAP_B1_BACKEND 56 | ProxyType=OnPremise 57 | Type=HTTP 58 | Authentication=BasicAuthentication 59 | ``` 60 | 61 | As described in the answer to [B1 Service Layer Login Credentials as Destination Properties](https://answers.sap.com/answers/12688540/view.html) the credentials can be added as shown in this example: 62 | 63 | ``` 64 | username: {"UserName": "manager", "CompanyDB": "SBODEMOUS"} 65 | password: 1234 66 | ``` 67 | 68 | ### Deploy the release version 69 | 70 | - Download the mtar file provided at [releases](https://github.com/gregorwolf/HTML5UserAPIforCF/releases) 71 | - run the command `cf deploy ` 72 | 73 | ### Build and Deploy 74 | 75 | To build and deploy the project run: 76 | 77 | `npm run build:cf` 78 | 79 | and then 80 | 81 | ``` 82 | npm run deploy:cf 83 | ``` 84 | -------------------------------------------------------------------------------- /approuter/.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.com/ 2 | -------------------------------------------------------------------------------- /approuter/approuter-start.js: -------------------------------------------------------------------------------- 1 | const approuter = require("@sap/approuter"); 2 | var ar = approuter(); 3 | ar.first; 4 | ar.start({ 5 | extensions: [require("./my-ext.js")], 6 | }); 7 | -------------------------------------------------------------------------------- /approuter/my-ext.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | insertMiddleware: { 3 | first: [ 4 | function logRequest(req, res, next) { 5 | console.log("Got request %s %s %s", req.method, req.url, req.headers); 6 | return next(); 7 | }, 8 | ], 9 | beforeRequestHandler: [ 10 | { 11 | path: "/services/userapi/currentUser", 12 | handler: function myMiddleware(req, res, next) { 13 | if (!req.user) { 14 | res.statusCode = 403; 15 | res.end(`Missing JWT Token`); 16 | } else { 17 | res.statusCode = 200; 18 | res.setHeader("Content-type", "application/json"); 19 | res.end(JSON.stringify(req.user)); 20 | } 21 | }, 22 | }, 23 | ], 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /approuter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "html5userapi-approuter", 3 | "version": "0.4.1", 4 | "description": "", 5 | "engines": { 6 | "node": "^22" 7 | }, 8 | "dependencies": { 9 | "@sap/approuter": "^20" 10 | }, 11 | "scripts": { 12 | "start": "node ./approuter-start.js", 13 | "start-local": "export VCAP_SERVICES=`cat default-env.json | jq .VCAP_SERVICES` && node ./approuter-start.js", 14 | "default-env": "cf default-env html5userapi-ui" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /approuter/xs-app.json: -------------------------------------------------------------------------------- 1 | { 2 | "welcomeFile": "/comsapsapmentorshtml5userapiforcfui/index.html", 3 | "authenticationMethod": "route", 4 | "logout": { 5 | "logoutEndpoint": "/do/logout", 6 | "logoutPage": "/comsapsapmentorshtml5userapiforcfui/logout-page.html" 7 | }, 8 | "whitelistService": { 9 | "endpoint": "/allowlist/service" 10 | }, 11 | "routes": [ 12 | { 13 | "source": "^/user-api(.*)", 14 | "target": "$1", 15 | "service": "sap-approuter-userapi" 16 | }, 17 | { 18 | "source": "^/fesr$", 19 | "target": "/fesr", 20 | "destination": "html5userapi-srv", 21 | "csrfProtection": false, 22 | "authenticationType": "xsuaa" 23 | }, 24 | { 25 | "source": "^/api/(.*)$", 26 | "target": "/api/$1", 27 | "authenticationType": "xsuaa", 28 | "destination": "html5userapi-srv", 29 | "csrfProtection": true 30 | }, 31 | { 32 | "source": "^/rfc(.*)$", 33 | "target": "/rfc$1", 34 | "authenticationType": "xsuaa", 35 | "destination": "html5userapi-srv-java", 36 | "csrfProtection": true 37 | }, 38 | { 39 | "source": "^/destination/([^/]+)/(.*)$", 40 | "target": "$2", 41 | "destination": "$1" 42 | }, 43 | { 44 | "source": "^/destination-no-auth/([^/]+)/(.*)$", 45 | "authenticationType": "none", 46 | "target": "$2", 47 | "destination": "$1" 48 | }, 49 | { 50 | "source": "^/sap/(.*)$", 51 | "target": "/sap/$1", 52 | "destination": "SAP_ABAP_BACKEND" 53 | }, 54 | { 55 | "source": "^/sap_basic_auth_dyn_idp/(.*)$", 56 | "target": "/sap/$1", 57 | "authenticationType": "basic", 58 | "dynamicIdentityProvider": true, 59 | "destination": "SAP_ABAP_BACKEND" 60 | }, 61 | { 62 | "source": "^/sap_basic_auth/(.*)$", 63 | "target": "/sap/$1", 64 | "authenticationType": "basic", 65 | "destination": "SAP_ABAP_BACKEND", 66 | "csrfProtection": true 67 | }, 68 | { 69 | "source": "^/sap_basic/(.*)$", 70 | "target": "/sap/$1", 71 | "destination": "SAP_ABAP_BACKEND_BASIC_AUTH" 72 | }, 73 | { 74 | "source": "^/b1s/(.*)$", 75 | "target": "/b1s/$1", 76 | "destination": "SAP_B1_BACKEND" 77 | }, 78 | { 79 | "source": "^/v2/admin/(.*)$", 80 | "target": "/v2/admin/$1", 81 | "authenticationType": "xsuaa", 82 | "destination": "bookshop", 83 | "csrfProtection": true 84 | }, 85 | { 86 | "source": "^/v2/catalog/(.*)$", 87 | "target": "/v2/catalog/$1", 88 | "authenticationType": "xsuaa", 89 | "destination": "bookshop", 90 | "csrfProtection": true 91 | }, 92 | { 93 | "source": "^/admin/(.*)$", 94 | "target": "/admin/$1", 95 | "authenticationType": "xsuaa", 96 | "destination": "bookshop", 97 | "csrfProtection": true 98 | }, 99 | { 100 | "source": "^/catalog/(.*)$", 101 | "target": "/catalog/$1", 102 | "authenticationType": "xsuaa", 103 | "destination": "bookshop", 104 | "csrfProtection": true 105 | }, 106 | { 107 | "source": "^/logout-page.html$", 108 | "service": "html5-apps-repo-rt", 109 | "authenticationType": "none" 110 | }, 111 | { 112 | "source": "^/index.html$", 113 | "service": "html5-apps-repo-rt", 114 | "authenticationType": "xsuaa", 115 | "cacheControl": "no-cache, no-store, must-revalidate" 116 | }, 117 | { 118 | "source": "^/html5userapiforcf/(.*)$", 119 | "target": "/comsapsapmentorshtml5userapiforcfui/$1", 120 | "service": "html5-apps-repo-rt", 121 | "authenticationType": "xsuaa" 122 | }, 123 | { 124 | "source": "^(.*)$", 125 | "target": "$1", 126 | "service": "html5-apps-repo-rt", 127 | "authenticationType": "xsuaa" 128 | } 129 | ] 130 | } 131 | -------------------------------------------------------------------------------- /mta.yaml: -------------------------------------------------------------------------------- 1 | ID: html5userapi 2 | _schema-version: "3.1" 3 | version: 0.5.0 4 | parameters: 5 | enable-parallel-deployments: true 6 | 7 | modules: 8 | - name: html5userapi-srv 9 | type: nodejs 10 | path: srv 11 | parameters: 12 | memory: 256M 13 | disk-quota: 1024M 14 | stack: cflinuxfs4 15 | provides: 16 | - name: srv_api 17 | properties: 18 | url: ${default-url} 19 | requires: 20 | - name: html5userapi-uaa 21 | - name: html5userapi-logging 22 | - name: html5userapi-destination-service 23 | - name: html5userapi-connectivity-service 24 | 25 | # - name: html5userapi-srv-java 26 | # type: java 27 | # path: srv-java/application 28 | # parameters: 29 | # memory: 512M 30 | # disk-quota: 1024M 31 | # stack: cflinuxfs4 32 | # provides: 33 | # - name: srv_java_api 34 | # properties: 35 | # url: ${default-url} 36 | # requires: 37 | # - name: html5userapi-uaa 38 | # - name: html5userapi-logging 39 | # - name: html5userapi-destination-service 40 | # - name: html5userapi-connectivity-service 41 | # properties: 42 | # USE_JCO: true 43 | 44 | - name: html5userapi-ui 45 | type: approuter.nodejs 46 | path: approuter 47 | parameters: 48 | memory: 256M 49 | disk-quota: 1024M 50 | stack: cflinuxfs4 51 | properties: 52 | CJ_PROTECT_WHITELIST: > 53 | [ 54 | { 55 | "protocol": "https", 56 | "host": "*.ondemand.com" 57 | }, 58 | { 59 | "protocol": "https", 60 | "host": "*.hcs.cloud.sap" 61 | } 62 | ] 63 | COOKIES: > 64 | { "SameSite":"None" } 65 | httpHeaders: > 66 | [ 67 | { 68 | "X-Frame-Options": "DENY" 69 | }, 70 | { 71 | "Content-Security-Policy": "frame-ancestors iframe frame object embed 'self' https://*.hcs.cloud.sap;" 72 | }, 73 | { 74 | "Access-Control-Allow-Origin": "https://localhost:3000" 75 | }, 76 | { 77 | "Access-Control-Allow-Credentials": "true" 78 | }, 79 | { 80 | "Access-Control-Allow-Headers": "Authorization,Content-Type" 81 | } 82 | ] 83 | CORS: > 84 | [ 85 | { 86 | "uriPattern":"^/destination-no-auth$", 87 | "allowedOrigin":[ 88 | { 89 | "protocol": "https", 90 | "host": "localhost", 91 | "port": 3000 92 | } 93 | ], 94 | "allowedHeaders": [ 95 | "Authorization", 96 | "Content-Type" 97 | ], 98 | "allowedCredentials": true 99 | } 100 | ] 101 | build-parameters: 102 | ignore: ["node_modules/"] 103 | requires: 104 | - name: html5userapi-destination-service 105 | - name: html5userapi-connectivity-service 106 | - name: html5userapi-uaa 107 | - name: html5userapi-logging 108 | - name: html5userapi-repo-runtime 109 | - name: srv_api 110 | group: destinations 111 | properties: 112 | forwardAuthToken: true 113 | strictSSL: false 114 | name: html5userapi-srv 115 | url: ~{url} 116 | # - name: srv_java_api 117 | # group: destinations 118 | # properties: 119 | # forwardAuthToken: true 120 | # strictSSL: false 121 | # name: html5userapi-srv-java 122 | # url: ~{url} 123 | - name: html5userapi-deployer 124 | type: com.sap.application.content 125 | path: . 126 | requires: 127 | - name: html5userapi-repo-host 128 | parameters: 129 | content-target: true 130 | build-parameters: 131 | build-result: resources 132 | requires: 133 | - artifacts: 134 | - dist/HTML5Module-content.zip 135 | name: html5userapi-HTML5Module 136 | target-path: resources/ 137 | 138 | - name: html5userapi-HTML5Module 139 | type: html5 140 | path: HTML5Module 141 | build-parameters: 142 | builder: custom 143 | commands: 144 | - npm i 145 | - npm run build 146 | supported-platforms: [] 147 | - name: html5userapi-destination-content 148 | type: com.sap.application.content 149 | requires: 150 | - name: html5userapi-uaa 151 | parameters: 152 | service-key: 153 | name: html5userapi-uaa-key 154 | - name: html5userapi-repo-host 155 | parameters: 156 | service-key: 157 | name: html5userapi-repo-host-key 158 | # - name: html5userapi-uaa-apiaccess 159 | # parameters: 160 | # service-key: 161 | # name: html5userapi-uaa-apiaccess-key 162 | - name: html5userapi-destination-service 163 | parameters: 164 | content-target: true 165 | - name: html5userapi-connectivity-service 166 | parameters: 167 | content: 168 | instance: 169 | existing_destinations_policy: update 170 | destinations: 171 | - Name: html5userapi-repo-host 172 | ServiceInstanceName: html5userapi-repo-host 173 | ServiceKeyName: html5userapi-repo-host-key 174 | sap.cloud.service: cloud.service 175 | - Authentication: OAuth2UserTokenExchange 176 | Name: html5userapi-uaa 177 | ServiceInstanceName: html5userapi-uaa 178 | ServiceKeyName: html5userapi-uaa-key 179 | sap.cloud.service: cloud.service 180 | # - Authentication: OAuth2ClientCredentials 181 | # Name: html5userapi-uaa-apiaccess 182 | # ServiceInstanceName: html5userapi-uaa-apiaccess 183 | # ServiceKeyName: html5userapi-uaa-apiaccess-key 184 | build-parameters: 185 | no-source: true 186 | 187 | resources: 188 | - name: html5userapi-uaa 189 | parameters: 190 | path: ./xs-security.json 191 | service-plan: application 192 | service: xsuaa 193 | type: org.cloudfoundry.managed-service 194 | # - name: html5userapi-uaa-apiaccess 195 | # type: org.cloudfoundry.managed-service 196 | # parameters: 197 | # service-plan: apiaccess 198 | # service: xsuaa 199 | - name: html5userapi-destination-service 200 | type: org.cloudfoundry.managed-service 201 | parameters: 202 | service-plan: lite 203 | service: destination 204 | config: 205 | init_data: 206 | instance: 207 | existing_destinations_policy: update 208 | destinations: 209 | - Name: html5userapi-srv 210 | Description: html5userapi NodeJS backend service 211 | Authentication: NoAuthentication 212 | ProxyType: Internet 213 | Type: HTTP 214 | URL: ~{srv_api/url} 215 | HTML5.DynamicDestination: true 216 | HTML5.ForwardAuthToken: true 217 | # - Name: html5userapi-srv-java 218 | # Description: html5userapi Java backend service 219 | # Authentication: NoAuthentication 220 | # ProxyType: Internet 221 | # Type: HTTP 222 | # URL: ~{srv_java_api/url} 223 | # HTML5.DynamicDestination: true 224 | # HTML5.ForwardAuthToken: true 225 | requires: 226 | - name: srv_api 227 | # - name: srv_java_api 228 | - name: html5userapi-connectivity-service 229 | parameters: 230 | service-plan: lite 231 | service: connectivity 232 | type: org.cloudfoundry.managed-service 233 | - name: html5userapi-repo-host 234 | type: org.cloudfoundry.managed-service 235 | parameters: 236 | service: html5-apps-repo 237 | service-plan: app-host 238 | - name: html5userapi-repo-runtime 239 | type: org.cloudfoundry.managed-service 240 | parameters: 241 | service-plan: app-runtime 242 | service: html5-apps-repo 243 | - name: html5userapi-logging 244 | type: org.cloudfoundry.managed-service 245 | parameters: 246 | service: application-logs 247 | service-plan: lite 248 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "html5userapi-cf", 3 | "version": "0.5.0", 4 | "description": "HTML5 User API for Cloud Foundry", 5 | "repository": "https://github.com/gregorwolf/HTML5UserAPIforCF.git ", 6 | "license": "Apache 2.0", 7 | "engines": { 8 | "node": "^22" 9 | }, 10 | "dependencies": { 11 | "@html5userapi-cf/approuter": "file:approuter", 12 | "@html5userapi-cf/HTML5Module": "file:HTML5Module", 13 | "@html5userapi-cf/srv": "file:srv" 14 | }, 15 | "devDependencies": { 16 | "npm-run-all": "^4.1.5" 17 | }, 18 | "scripts": { 19 | "update": "run-p update:**", 20 | "update:root": "npm update", 21 | "update:approuter": "cd approuter && npm update", 22 | "update:HTML5Module": "cd HTML5Module && npm update", 23 | "update:srv": "cd srv && npm update", 24 | "build:cf": "mbt build -p=cf", 25 | "build:cf:docker": "docker run -it --rm -v \"$(pwd):/project\" devxci/mbtci:latest mbt build -p=cf", 26 | "deploy:cf": "cf deploy mta_archives/html5userapi_0.5.0.mtar", 27 | "deploy:cf:approuter": "cf deploy mta_archives/html5userapi_0.5.0.mtar -m html5userapi-ui", 28 | "deploy:cf:srv": "cf deploy mta_archives/html5userapi_0.5.0.mtar -m html5userapi-srv", 29 | "deploy:cf:srv-java": "cf deploy mta_archives/html5userapi_0.5.0.mtar -m html5userapi-srv-java", 30 | "deploy:cf:html5repo": "cf deploy mta_archives/html5userapi_0.5.0.mtar -m html5userapi-deployer", 31 | "html5:build": "cd HTML5Module && rm -rf dist && npm run build:ui5 && cd ..", 32 | "html5:push": "cf html5-push -r HTML5Module/dist", 33 | "debug:cf": "cf ssh html5userapi-srv -N -T -L 9229:127.0.0.1:9229", 34 | "uaa:update": "cf update-service html5userapi-uaa -c xs-security.json", 35 | "undeploy:cf": "cf undeploy html5userapi --delete-service-keys --delete-services --delete-service-brokers" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /srv-java/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | rfctest 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.m2e.core.maven2Builder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.m2e.core.maven2Nature 16 | 17 | 18 | 19 | 1666295353073 20 | 21 | 30 22 | 23 | org.eclipse.core.resources.regexFilterMatcher 24 | node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /srv-java/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding/=UTF-8 3 | -------------------------------------------------------------------------------- /srv-java/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /srv-java/Jenkinsfile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | /* 4 | * This file bootstraps the codified Continuous Delivery pipeline for extensions of SAP solutions such as SAP S/4HANA. 5 | * The pipeline helps you to deliver software changes quickly and in a reliable manner. 6 | * A suitable Jenkins instance is required to run the pipeline. 7 | * The Jenkins can easily be bootstraped using the life-cycle script located inside the 'cx-server' directory. 8 | * 9 | * More information on getting started with Continuous Delivery can be found here: https://sap.github.io/jenkins-library/ 10 | */ 11 | 12 | @Library('piper-lib-os') _ 13 | 14 | piperPipeline script: this 15 | -------------------------------------------------------------------------------- /srv-java/application/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /srv-java/application/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | rfctest-application 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | 25 | 1666295353078 26 | 27 | 30 28 | 29 | org.eclipse.core.resources.regexFilterMatcher 30 | node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /srv-java/application/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/test/java=UTF-8 5 | encoding/=UTF-8 6 | -------------------------------------------------------------------------------- /srv-java/application/.settings/org.eclipse.jdt.apt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.apt.aptEnabled=false 3 | -------------------------------------------------------------------------------- /srv-java/application/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | enableParallelJavaIndexSearch=true 3 | org.eclipse.jdt.core.builder.annotationPath.allLocations=disabled 4 | org.eclipse.jdt.core.builder.cleanOutputFolder=clean 5 | org.eclipse.jdt.core.builder.duplicateResourceTask=warning 6 | org.eclipse.jdt.core.builder.invalidClasspath=abort 7 | org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore 8 | org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= 9 | org.eclipse.jdt.core.circularClasspath=warning 10 | org.eclipse.jdt.core.classpath.exclusionPatterns=enabled 11 | org.eclipse.jdt.core.classpath.mainOnlyProjectHasTestOnlyDependency=error 12 | org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled 13 | org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error 14 | org.eclipse.jdt.core.codeComplete.argumentPrefixes= 15 | org.eclipse.jdt.core.codeComplete.argumentSuffixes= 16 | org.eclipse.jdt.core.codeComplete.camelCaseMatch=enabled 17 | org.eclipse.jdt.core.codeComplete.deprecationCheck=disabled 18 | org.eclipse.jdt.core.codeComplete.discouragedReferenceCheck=disabled 19 | org.eclipse.jdt.core.codeComplete.fieldPrefixes= 20 | org.eclipse.jdt.core.codeComplete.fieldSuffixes= 21 | org.eclipse.jdt.core.codeComplete.forbiddenReferenceCheck=enabled 22 | org.eclipse.jdt.core.codeComplete.forceImplicitQualification=disabled 23 | org.eclipse.jdt.core.codeComplete.localPrefixes= 24 | org.eclipse.jdt.core.codeComplete.localSuffixes= 25 | org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= 26 | org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= 27 | org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= 28 | org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= 29 | org.eclipse.jdt.core.codeComplete.subwordMatch=disabled 30 | org.eclipse.jdt.core.codeComplete.suggestStaticImports=enabled 31 | org.eclipse.jdt.core.codeComplete.visibilityCheck=enabled 32 | org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled 33 | org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore 34 | org.eclipse.jdt.core.compiler.annotation.nonnull=javax.annotation.Nonnull 35 | org.eclipse.jdt.core.compiler.annotation.nonnull.secondary= 36 | org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=javax.annotation.ParametersAreNonnullByDefault 37 | org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary= 38 | org.eclipse.jdt.core.compiler.annotation.nullable=javax.annotation.Nullable 39 | org.eclipse.jdt.core.compiler.annotation.nullable.secondary= 40 | org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled 41 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 42 | org.eclipse.jdt.core.compiler.codegen.lambda.genericSignature=do not generate 43 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate 44 | org.eclipse.jdt.core.compiler.codegen.shareCommonFinallyBlocks=disabled 45 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 46 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 47 | org.eclipse.jdt.core.compiler.compliance=1.8 48 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 49 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 50 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 51 | org.eclipse.jdt.core.compiler.doc.comment.support=enabled 52 | org.eclipse.jdt.core.compiler.emulateJavacBug8031744=enabled 53 | org.eclipse.jdt.core.compiler.generateClassFiles=enabled 54 | org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 55 | org.eclipse.jdt.core.compiler.problem.APILeak=warning 56 | org.eclipse.jdt.core.compiler.problem.annotatedTypeArgumentToUnannotated=info 57 | org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning 58 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 59 | org.eclipse.jdt.core.compiler.problem.autoboxing=ignore 60 | org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning 61 | org.eclipse.jdt.core.compiler.problem.deadCode=warning 62 | org.eclipse.jdt.core.compiler.problem.deadCodeInTrivialIfStatement=disabled 63 | org.eclipse.jdt.core.compiler.problem.deprecation=warning 64 | org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled 65 | org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled 66 | org.eclipse.jdt.core.compiler.problem.discouragedReference=warning 67 | org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore 68 | org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled 69 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 70 | org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore 71 | org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore 72 | org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled 73 | org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore 74 | org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning 75 | org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning 76 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 77 | org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning 78 | org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled 79 | org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning 80 | org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning 81 | org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore 82 | org.eclipse.jdt.core.compiler.problem.invalidJavadoc=ignore 83 | org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=disabled 84 | org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled 85 | org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=disabled 86 | org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=public 87 | org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore 88 | org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning 89 | org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore 90 | org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore 91 | org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled 92 | org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore 93 | org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore 94 | org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled 95 | org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public 96 | org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag 97 | org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore 98 | org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled 99 | org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled 100 | org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public 101 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore 102 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled 103 | org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore 104 | org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore 105 | org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning 106 | org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning 107 | org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore 108 | org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning 109 | org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning 110 | org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning 111 | org.eclipse.jdt.core.compiler.problem.nullReference=warning 112 | org.eclipse.jdt.core.compiler.problem.nullSpecViolation=warning 113 | org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=ignore 114 | org.eclipse.jdt.core.compiler.problem.overridingMethodWithoutSuperInvocation=ignore 115 | org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning 116 | org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore 117 | org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning 118 | org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore 119 | org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning 120 | org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore 121 | org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning 122 | org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning 123 | org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore 124 | org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore 125 | org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning 126 | org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore 127 | org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore 128 | org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore 129 | org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled 130 | org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning 131 | org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled 132 | org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled 133 | org.eclipse.jdt.core.compiler.problem.suppressWarningsNotFullyAnalysed=info 134 | org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled 135 | org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore 136 | org.eclipse.jdt.core.compiler.problem.tasks=warning 137 | org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning 138 | org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning 139 | org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled 140 | org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning 141 | org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning 142 | org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore 143 | org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore 144 | org.eclipse.jdt.core.compiler.problem.uninternedIdentityComparison=disabled 145 | org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning 146 | org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled 147 | org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info 148 | org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore 149 | org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore 150 | org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore 151 | org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning 152 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore 153 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled 154 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled 155 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled 156 | org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore 157 | org.eclipse.jdt.core.compiler.problem.unusedImport=warning 158 | org.eclipse.jdt.core.compiler.problem.unusedLabel=warning 159 | org.eclipse.jdt.core.compiler.problem.unusedLocal=warning 160 | org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore 161 | org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore 162 | org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled 163 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled 164 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled 165 | org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning 166 | org.eclipse.jdt.core.compiler.problem.unusedTypeArgumentsForMethodInvocation=warning 167 | org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore 168 | org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning 169 | org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning 170 | org.eclipse.jdt.core.compiler.processAnnotations=disabled 171 | org.eclipse.jdt.core.compiler.release=disabled 172 | org.eclipse.jdt.core.compiler.source=1.8 173 | org.eclipse.jdt.core.compiler.storeAnnotations=disabled 174 | org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled 175 | org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL 176 | org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX 177 | org.eclipse.jdt.core.computeJavaBuildOrder=ignore 178 | org.eclipse.jdt.core.encoding=utf8 179 | org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false 180 | org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 181 | org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line=true 182 | org.eclipse.jdt.core.formatter.align_type_members_on_columns=false 183 | org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false 184 | org.eclipse.jdt.core.formatter.align_with_spaces=false 185 | org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 186 | org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant=49 187 | org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field=49 188 | org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable=49 189 | org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method=49 190 | org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package=49 191 | org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter=0 192 | org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type=49 193 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 194 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 195 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 196 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 197 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 198 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 199 | org.eclipse.jdt.core.formatter.alignment_for_assertion_message=16 200 | org.eclipse.jdt.core.formatter.alignment_for_assignment=0 201 | org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 202 | org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 203 | org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16 204 | org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 205 | org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0 206 | org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16 207 | org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 208 | org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 209 | org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_arrow=16 210 | org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon=16 211 | org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 212 | org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 213 | org.eclipse.jdt.core.formatter.alignment_for_module_statements=16 214 | org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 215 | org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 216 | org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 217 | org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 218 | org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 219 | org.eclipse.jdt.core.formatter.alignment_for_record_components=16 220 | org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0 221 | org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 222 | org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 223 | org.eclipse.jdt.core.formatter.alignment_for_shift_operator=0 224 | org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 225 | org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 226 | org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 227 | org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration=16 228 | org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 229 | org.eclipse.jdt.core.formatter.alignment_for_switch_case_with_arrow=20 230 | org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 231 | org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 232 | org.eclipse.jdt.core.formatter.alignment_for_type_annotations=0 233 | org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 234 | org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 235 | org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 236 | org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 237 | org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration=0 238 | org.eclipse.jdt.core.formatter.blank_lines_after_package=1 239 | org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method=1 240 | org.eclipse.jdt.core.formatter.blank_lines_before_field=0 241 | org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 242 | org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 243 | org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 244 | org.eclipse.jdt.core.formatter.blank_lines_before_method=1 245 | org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 246 | org.eclipse.jdt.core.formatter.blank_lines_before_package=0 247 | org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 248 | org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch=0 249 | org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 250 | org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line 251 | org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line 252 | org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line 253 | org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line 254 | org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line 255 | org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line 256 | org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line 257 | org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line 258 | org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line 259 | org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line 260 | org.eclipse.jdt.core.formatter.brace_position_for_record_constructor=end_of_line 261 | org.eclipse.jdt.core.formatter.brace_position_for_record_declaration=end_of_line 262 | org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line 263 | org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line 264 | org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=true 265 | org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions=false 266 | org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false 267 | org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false 268 | org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=true 269 | org.eclipse.jdt.core.formatter.comment.format_block_comments=true 270 | org.eclipse.jdt.core.formatter.comment.format_header=false 271 | org.eclipse.jdt.core.formatter.comment.format_html=true 272 | org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true 273 | org.eclipse.jdt.core.formatter.comment.format_line_comments=true 274 | org.eclipse.jdt.core.formatter.comment.format_source_code=true 275 | org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false 276 | org.eclipse.jdt.core.formatter.comment.indent_root_tags=false 277 | org.eclipse.jdt.core.formatter.comment.indent_tag_description=false 278 | org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert 279 | org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags=do not insert 280 | org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert 281 | org.eclipse.jdt.core.formatter.comment.line_length=80 282 | org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true 283 | org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true 284 | org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false 285 | org.eclipse.jdt.core.formatter.compact_else_if=true 286 | org.eclipse.jdt.core.formatter.continuation_indentation=2 287 | org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 288 | org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off 289 | org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on 290 | org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false 291 | org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=false 292 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true 293 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true 294 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true 295 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header=true 296 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true 297 | org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true 298 | org.eclipse.jdt.core.formatter.indent_empty_lines=false 299 | org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true 300 | org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true 301 | org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true 302 | org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true 303 | org.eclipse.jdt.core.formatter.indentation.size=4 304 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert 305 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert 306 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert 307 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert 308 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert 309 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert 310 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert 311 | org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert 312 | org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert 313 | org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert 314 | org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert 315 | org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert 316 | org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert 317 | org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert 318 | org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert 319 | org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert 320 | org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert 321 | org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert 322 | org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case=insert 323 | org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default=insert 324 | org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert 325 | org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert 326 | org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert 327 | org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert 328 | org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert 329 | org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert 330 | org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert 331 | org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert 332 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert 333 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert 334 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert 335 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert 336 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert 337 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert 338 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert 339 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert 340 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert 341 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert 342 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert 343 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert 344 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert 345 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert 346 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert 347 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert 348 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert 349 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert 350 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert 351 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert 352 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert 353 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_permitted_types=insert 354 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components=insert 355 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert 356 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions=insert 357 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert 358 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert 359 | org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert 360 | org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert 361 | org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert 362 | org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert 363 | org.eclipse.jdt.core.formatter.insert_space_after_not_operator=do not insert 364 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert 365 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert 366 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert 367 | org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert 368 | org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert 369 | org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert 370 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert 371 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert 372 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert 373 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert 374 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert 375 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert 376 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert 377 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert 378 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert 379 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert 380 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration=do not insert 381 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert 382 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert 383 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert 384 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert 385 | org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert 386 | org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert 387 | org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert 388 | org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert 389 | org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert 390 | org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert 391 | org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert 392 | org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert 393 | org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert 394 | org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert 395 | org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert 396 | org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert 397 | org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case=insert 398 | org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default=insert 399 | org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert 400 | org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert 401 | org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert 402 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert 403 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert 404 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert 405 | org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert 406 | org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert 407 | org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert 408 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert 409 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert 410 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert 411 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert 412 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert 413 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert 414 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert 415 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert 416 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert 417 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert 418 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration=do not insert 419 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert 420 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert 421 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert 422 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert 423 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert 424 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert 425 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert 426 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert 427 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert 428 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert 429 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert 430 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert 431 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert 432 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert 433 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert 434 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert 435 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert 436 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert 437 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert 438 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert 439 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert 440 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert 441 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert 442 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert 443 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert 444 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert 445 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_permitted_types=do not insert 446 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components=do not insert 447 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert 448 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions=do not insert 449 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert 450 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert 451 | org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert 452 | org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert 453 | org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert 454 | org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert 455 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert 456 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert 457 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert 458 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert 459 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert 460 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert 461 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert 462 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert 463 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert 464 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert 465 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert 466 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor=insert 467 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration=insert 468 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert 469 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert 470 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert 471 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert 472 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert 473 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert 474 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert 475 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert 476 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert 477 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert 478 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert 479 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert 480 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert 481 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert 482 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert 483 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration=do not insert 484 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert 485 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert 486 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert 487 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert 488 | org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert 489 | org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert 490 | org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert 491 | org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert 492 | org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert 493 | org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert 494 | org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert 495 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert 496 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert 497 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert 498 | org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert 499 | org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert 500 | org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert 501 | org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert 502 | org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert 503 | org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert 504 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert 505 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert 506 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert 507 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert 508 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert 509 | org.eclipse.jdt.core.formatter.join_lines_in_comments=false 510 | org.eclipse.jdt.core.formatter.join_wrapped_lines=false 511 | org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line=one_line_never 512 | org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_never 513 | org.eclipse.jdt.core.formatter.keep_code_block_on_one_line=one_line_never 514 | org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false 515 | org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false 516 | org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line=one_line_never 517 | org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line=one_line_never 518 | org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line=one_line_never 519 | org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false 520 | org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line=one_line_never 521 | org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line=one_line_never 522 | org.eclipse.jdt.core.formatter.keep_method_body_on_one_line=one_line_never 523 | org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line=one_line_never 524 | org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line=one_line_never 525 | org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false 526 | org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false 527 | org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=false 528 | org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false 529 | org.eclipse.jdt.core.formatter.keep_switch_body_block_on_one_line=one_line_never 530 | org.eclipse.jdt.core.formatter.keep_switch_case_with_arrow_on_one_line=one_line_never 531 | org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false 532 | org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never 533 | org.eclipse.jdt.core.formatter.lineSplit=120 534 | org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false 535 | org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false 536 | org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block=0 537 | org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block=0 538 | org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 539 | org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block=0 540 | org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body=0 541 | org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block=0 542 | org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 543 | org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines 544 | org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines 545 | org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines 546 | org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines 547 | org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines 548 | org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines 549 | org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines 550 | org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines 551 | org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration=common_lines 552 | org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines 553 | org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines 554 | org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true 555 | org.eclipse.jdt.core.formatter.tabulation.char=space 556 | org.eclipse.jdt.core.formatter.tabulation.size=4 557 | org.eclipse.jdt.core.formatter.text_block_indentation=0 558 | org.eclipse.jdt.core.formatter.use_on_off_tags=true 559 | org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false 560 | org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true 561 | org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator=true 562 | org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false 563 | org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true 564 | org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true 565 | org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true 566 | org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true 567 | org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true 568 | org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true 569 | org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true 570 | org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true 571 | org.eclipse.jdt.core.formatter.wrap_before_switch_case_arrow_operator=false 572 | org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true 573 | org.eclipse.jdt.core.incompatibleJDKLevel=ignore 574 | org.eclipse.jdt.core.incompleteClasspath=error 575 | org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter 576 | org.eclipse.jdt.core.timeoutForParameterNameFromAttachedJavadoc=50 577 | -------------------------------------------------------------------------------- /srv-java/application/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /srv-java/application/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | rfctest - Application 7 | rfctest - Application 8 | 9 | rfctest-application 10 | 1.0-SNAPSHOT 11 | war 12 | 13 | 14 | rfctest 15 | rfctest 16 | 1.0-SNAPSHOT 17 | 18 | 19 | 20 | false 21 | 1 22 | * 23 | 24 | 25 | 26 | 1024m 27 | info 28 | 29 | 37 | -Xmx${surefire.maxMemorySize} -Dorg.slf4j.simpleLogger.defaultLogLevel=${surefire.logLevel} 38 | 39 | ${project.build.directory}/coverage-reports/jacoco.exec 40 | * 41 | org.apache.* 42 | 43 | 44 | 45 | 46 | 47 | com.google.guava 48 | guava 49 | 50 | 51 | org.checkerframework 52 | checker-qual 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | com.sap.cloud.sdk.cloudplatform 62 | scp-cf 63 | 64 | 65 | com.sap.cloud.sdk.s4hana 66 | s4hana-all 67 | 68 | 69 | com.sap.cloud.sdk.cloudplatform 70 | security-servlet 71 | runtime 72 | 73 | 74 | 75 | org.slf4j 76 | slf4j-api 77 | 78 | 79 | org.slf4j 80 | jcl-over-slf4j 81 | runtime 82 | 83 | 84 | ch.qos.logback 85 | logback-classic 86 | 87 | 88 | 89 | javax.inject 90 | javax.inject 91 | provided 92 | 93 | 94 | 95 | javax.servlet 96 | javax.servlet-api 97 | provided 98 | 99 | 100 | 101 | com.sap.cloud.sdk.testutil 102 | testutil-core 103 | test 104 | 105 | 106 | 107 | org.slf4j 108 | slf4j-simple 109 | test 110 | 111 | 112 | 113 | junit 114 | junit 115 | test 116 | 117 | 118 | 119 | 120 | ${project.artifactId} 121 | 122 | 123 | 124 | org.apache.maven.plugins 125 | maven-war-plugin 126 | 3.3.1 127 | 128 | true 129 | 130 | 131 | 132 | 133 | org.apache.tomee.maven 134 | tomee-maven-plugin 135 | 8.0.6 136 | 137 | webprofile 138 | ROOT 139 | 140 | remove:slf4j-jdk14 141 | 142 | 8006 143 | 144 | 145 | 146 | org.jacoco 147 | jacoco-maven-plugin 148 | 0.8.6 149 | 150 | ${jacoco.executionDataFile} 151 | ${jacoco.executionDataFile} 152 | ${jacoco.includes} 153 | ${jacoco.excludes} 154 | 155 | 156 | 157 | prepare-agent 158 | 159 | prepare-agent 160 | 161 | 162 | 163 | 164 | 165 | 166 | org.apache.maven.plugins 167 | maven-surefire-plugin 168 | 3.0.0-M5 169 | 170 | ${surefire.skipTests} 171 | 172 | ${surefire.include} 173 | 174 | 175 | ${surefire.exclude} 176 | 177 | ${surefire.forkCount} 178 | false 179 | ${surefire.groups} 180 | ${surefire.excludedGroups} 181 | 182 | ${project.build.directory}/surefire-fork/${surefire.forkNumber}/ 183 | 184 | 185 | 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /srv-java/application/src/main/java/rfctest/HelloWorldServlet.java: -------------------------------------------------------------------------------- 1 | package rfctest; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import javax.servlet.annotation.HttpConstraint; 7 | import javax.servlet.annotation.ServletSecurity; 8 | import javax.servlet.annotation.WebServlet; 9 | import javax.servlet.http.HttpServlet; 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | import java.io.IOException; 13 | 14 | 15 | 16 | @WebServlet("/hello") 17 | @ServletSecurity(@HttpConstraint(rolesAllowed = { "Display" })) 18 | public class HelloWorldServlet extends HttpServlet 19 | { 20 | private static final long serialVersionUID = 1L; 21 | private static final Logger logger = LoggerFactory.getLogger(HelloWorldServlet.class); 22 | 23 | @Override 24 | protected void doGet( final HttpServletRequest request, final HttpServletResponse response ) 25 | throws IOException 26 | { 27 | logger.info("I am running!"); 28 | response.getWriter().write("Hello World!"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /srv-java/application/src/main/java/rfctest/RfcServlet.java: -------------------------------------------------------------------------------- 1 | package rfctest; 2 | 3 | import com.google.gson.Gson; 4 | import com.sap.cloud.sdk.cloudplatform.connectivity.Destination; 5 | import com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor; 6 | import com.sap.cloud.sdk.s4hana.connectivity.exception.RequestExecutionException; 7 | import com.sap.cloud.sdk.s4hana.connectivity.rfc.RfmRequest; 8 | import com.sap.cloud.sdk.s4hana.connectivity.rfc.RfmRequestResult; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import javax.servlet.annotation.HttpConstraint; 13 | import javax.servlet.annotation.ServletSecurity; 14 | import javax.servlet.annotation.WebServlet; 15 | import javax.servlet.http.HttpServlet; 16 | import javax.servlet.http.HttpServletRequest; 17 | import javax.servlet.http.HttpServletResponse; 18 | import java.io.IOException; 19 | 20 | @WebServlet("/rfc") 21 | @ServletSecurity(@HttpConstraint(rolesAllowed = { "Display" })) 22 | public class RfcServlet extends HttpServlet { 23 | private static final long serialVersionUID = 1L; 24 | private static final Logger logger = LoggerFactory.getLogger(RfcServlet.class); 25 | private static final Destination destinationRfc = 26 | DestinationAccessor.getDestination("SAP_ABAP_BACKEND_RFC"); 27 | 28 | @Override 29 | protected void doGet(final HttpServletRequest request, final HttpServletResponse response) 30 | throws IOException { 31 | 32 | logger.info("Start get method: " + request.getRequestURI()); 33 | String parameter = request.getParameter("name"); 34 | logger.info("Get parameter 'name': " + parameter); 35 | if (parameter == null) { 36 | parameter = "USER_NAME_GET"; 37 | } 38 | Iterable names = destinationRfc.getPropertyNames(); 39 | logger.info(new Gson().toJson(names)); 40 | 41 | try { 42 | final RfmRequestResult rfmTest = new RfmRequest(parameter, false) //false is for non-commit 43 | .execute(destinationRfc); 44 | response.setContentType("application/json"); 45 | response.setCharacterEncoding("UTF-8"); 46 | response.getWriter().write(new Gson().toJson(rfmTest)); 47 | } catch (RequestExecutionException e) { 48 | e.printStackTrace(); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /srv-java/application/src/main/webapp/WEB-INF/beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /srv-java/application/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 20 9 | 10 | 11 | 12 | XSUAA 13 | 14 | 15 | 16 | 17 | Baseline Security 18 | /* 19 | 20 | 21 | * 22 | 23 | 24 | 25 | 26 | Display 27 | 28 | 29 | 30 | RestCsrfPreventionFilter 31 | org.apache.catalina.filters.RestCsrfPreventionFilter 32 | 33 | 34 | RestCsrfPreventionFilter 35 | /* 36 | 37 | 38 | 39 | HttpSecurityHeadersFilter 40 | com.sap.cloud.sdk.cloudplatform.security.servlet.HttpSecurityHeadersFilter 41 | 42 | 43 | HttpSecurityHeadersFilter 44 | /* 45 | 46 | 47 | 48 | HttpCachingHeaderFilter 49 | com.sap.cloud.sdk.cloudplatform.security.servlet.HttpCachingHeaderFilter 50 | 51 | 52 | HttpCachingHeaderFilter 53 | /* 54 | 55 | 56 | -------------------------------------------------------------------------------- /srv-java/application/src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Welcome to the RFC Test Application! 4 | 25 | 26 | 27 |

Welcome to the RFC Test Application!

28 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /srv-java/application/src/test/java/rfctest/UnitTest.java: -------------------------------------------------------------------------------- 1 | package rfctest; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class UnitTest { 8 | @Test 9 | public void test() { 10 | assertTrue(true); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /srv-java/cx-server/cx-server: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Ensure that Docker is installed 4 | command -v docker > /dev/null 2>&1 || { echo >&2 "Docker does not seem to be installed. Please install Docker and ensure that the 'docker' command is included in \$PATH."; exit 1; } 5 | 6 | source server.cfg 7 | 8 | if [ -z "${DEVELOPER_MODE}" ]; then 9 | docker pull ppiper/cx-server-companion; 10 | fi 11 | 12 | docker_arguments=(--rm 13 | --mount "source=${PWD},target=/cx-server/mount,type=bind" 14 | --workdir /cx-server/mount 15 | --volume /var/run/docker.sock:/var/run/docker.sock 16 | --env DEVELOPER_MODE 17 | --env JENKINS_USERNAME 18 | --env JENKINS_PASSWORD 19 | --env "host_os=unix" 20 | --env "cx_server_path=${PWD}") 21 | 22 | # Run Docker without '-it' flag on Jenkins to prevent our integration test from getting stuck 23 | if docker run --rm -it hello-world > /dev/null 2>&1 ; then 24 | docker_arguments+=('-it') 25 | else 26 | echo No interactive terminal, run Docker without '-it' flag 27 | fi 28 | 29 | 30 | # Environment file is required for integration tests 31 | readonly env_file='custom-environment.list' 32 | if [ -f ${env_file} ]; then 33 | docker_arguments+=(--env-file "${env_file}") 34 | fi 35 | 36 | # These braces ensure that the block in them cannot be overridden by updating this file on the fly. 37 | # The exit inside protects against unintended effect when the new script file is bigger than its old version. 38 | # See: https://stackoverflow.com/questions/3398258/edit-shell-script-while-its-running 39 | { 40 | docker run "${docker_arguments[@]}" ppiper/cx-server-companion /cx-server/cx-server-companion.sh "$@" 41 | exit $? 42 | } 43 | -------------------------------------------------------------------------------- /srv-java/cx-server/cx-server-completion.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | complete -W "start status stop remove backup restore update image script help initial-credentials" cx-server 3 | -------------------------------------------------------------------------------- /srv-java/cx-server/cx-server.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | ECHO Please note that Cx Server on Windows is for convenient development and evaluation. 4 | ECHO For running an productive Cx Server, please use a Linux System. 5 | 6 | IF "%~1"==backup GOTO NOT_SUPPORTED 7 | IF "%~1"==restore GOTO NOT_SUPPORTED 8 | IF "%~1"==update ( 9 | IF "%~2"=="image" GOTO NOT_SUPPORTED 10 | ) 11 | 12 | IF "%CD%"=="" GOTO WORKING_DIR_EMPTY 13 | 14 | IF "%DEVELOPER_MODE%"=="" docker pull ppiper/cx-server-companion 15 | 16 | ( 17 | docker run --rm -it --workdir /cx-server/mount --volume //var/run/docker.sock:/var/run/docker.sock --mount source="%CD%",target=/cx-server/mount,type=bind --env DEVELOPER_MODE --env host_os=windows --env cx_server_path="%CD%" ppiper/cx-server-companion /cx-server/cx-server-companion.sh %~1 %~2 18 | IF NOT %ERRORLEVEL% == 0 GOTO RUN_ERROR 19 | GOTO END 20 | ) 21 | 22 | :NOT_SUPPORTED 23 | ECHO "backup", "restore" and "update image" are currently not supported on Windows. 24 | GOTO END 25 | 26 | :RUN_ERROR 27 | ECHO Could not run the Cx Server Docker container. 28 | ECHO Please ensure that docker is running (with "docker run hello-world") 29 | ECHO Also, please make sure that the Windows drive where your project is located (usually C:) is shared with Docker as described in https://docs.docker.com/docker-for-windows/#shared-drives. 30 | GOTO END 31 | 32 | :WORKING_DIR_EMPTY 33 | ECHO The environment variable CD is not set. It is required that this variable points to the directory where cx-server.bat resides. 34 | GOTO END 35 | 36 | :END -------------------------------------------------------------------------------- /srv-java/cx-server/server.cfg: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #---------------------------------------------# 3 | #-- General configuration --------------------# 4 | #---------------------------------------------# 5 | 6 | #>> Specify effective value of 'http_proxy' / 'https_proxy' environment variables. 7 | #>> The specified proxy will also be used for the Jenkins and Nexus (Download Cache) processes. 8 | #>> Jenkins only supports one proxy server. In this case, https_proxy will have precedence over http_proxy. 9 | # http_proxy="http://username:password@proxy:8080" 10 | # https_proxy="http://username:password@proxy:8080" 11 | 12 | #>> Specify effective value of 'no_proxy' environment variable (overwrites value in base image) 13 | # no_proxy="localhost,.corp" 14 | 15 | #>> Specify additional no values of 'no_proxy' environment variable (appended to value in base image) 16 | # x_no_proxy="localhost,.corp" 17 | 18 | #---------------------------------------------# 19 | #-- Build server configuration ---------------# 20 | #---------------------------------------------# 21 | 22 | #>> Address of the used docker registry. Override if you do not want to use Docker's default registry. 23 | # docker_registry="your-custom-registry.corp" 24 | 25 | #>> Name of the used docker image 26 | # docker_image="ppiper/jenkins-master:latest" 27 | 28 | #>> Enable TLS encryption 29 | # tls_enabled=true 30 | 31 | #>> Port on which jenkins will be reachable via http. 32 | #>> This port will be only opened when TLS is not active. 33 | # http_port="80" 34 | 35 | #>> Port on which jenkins will be reachable via https when TLS is activated. 36 | # https_port="443" 37 | 38 | #>> Name of the docker volume holding the jenkins_home folder. 39 | # jenkins_home="jenkins_home_volume" 40 | 41 | #>> Name of the backup file in backup directory. 42 | # backup_file_name="jenkins_home_$(date -u +%Y-%m-%dT%H%M%Z).tar.gz" 43 | 44 | #>> Additional JAVA_OPTS for the jenkins container. The value will be appended to the standard value. 45 | # x_java_opts="-Xmx1024m" 46 | 47 | 48 | #---------------------------------------------# 49 | #-- Download cache configuration -------------# 50 | #---------------------------------------------# 51 | 52 | #>> Toggle for turning the download cache on and off. 53 | # cache_enabled=false 54 | 55 | #>> Maven repository that will be cached via the download cache (default is maven central) 56 | # mvn_repository_url="https://your-local-maven-repo.corp/maven2/" 57 | 58 | #>> npm repository that will be cached via the download cache (default is central npm registy) 59 | # npm_registry_url="https://your-local-npm-registry.corp/" 60 | 61 | #>> Additional JAVA_OPTS for the download cache server. The value will be appended to the standard value. 62 | # x_nexus_java_opts="-Xms256m -Xmx2048m" 63 | -------------------------------------------------------------------------------- /srv-java/integration-tests/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /srv-java/integration-tests/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | rfctest-integration-tests 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | 25 | 1666295353082 26 | 27 | 30 28 | 29 | org.eclipse.core.resources.regexFilterMatcher 30 | node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /srv-java/integration-tests/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/test/java=UTF-8 3 | encoding//src/test/resources=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /srv-java/integration-tests/.settings/org.eclipse.jdt.apt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.apt.aptEnabled=false 3 | -------------------------------------------------------------------------------- /srv-java/integration-tests/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull 3 | org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable 4 | org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled 5 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 6 | org.eclipse.jdt.core.compiler.compliance=1.8 7 | org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled 8 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 9 | org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error 10 | org.eclipse.jdt.core.compiler.problem.nullReference=warning 11 | org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error 12 | org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore 13 | org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore 14 | org.eclipse.jdt.core.compiler.processAnnotations=disabled 15 | org.eclipse.jdt.core.compiler.release=disabled 16 | org.eclipse.jdt.core.compiler.source=1.8 17 | -------------------------------------------------------------------------------- /srv-java/integration-tests/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /srv-java/integration-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | rfctest - Integration Tests 7 | rfctest - Integration Tests 8 | 9 | rfctest-integration-tests 10 | 1.0-SNAPSHOT 11 | 12 | 13 | rfctest 14 | rfctest 15 | 1.0-SNAPSHOT 16 | 17 | 18 | 19 | false 20 | 1 21 | * 22 | 23 | 24 | 25 | 1024m 26 | info 27 | 28 | 36 | -Xmx${surefire.maxMemorySize} -Dorg.slf4j.simpleLogger.defaultLogLevel=${surefire.logLevel} 37 | 38 | ${project.build.directory}/coverage-reports/jacoco.exec 39 | * 40 | org.apache.* 41 | 42 | 43 | 44 | 45 | rfctest 46 | rfctest-application 47 | classes 48 | 1.0-SNAPSHOT 49 | 50 | 51 | ch.qos.logback 52 | logback-classic 53 | 54 | 55 | 56 | 57 | 58 | com.sap.cloud.sdk.cloudplatform 59 | scp-cf 60 | test 61 | 62 | 63 | com.sap.cloud.sdk.s4hana 64 | s4hana-all 65 | test 66 | 67 | 68 | com.sap.cloud.sdk.testutil 69 | testutil-core 70 | test 71 | 72 | 73 | 74 | org.slf4j 75 | slf4j-api 76 | test 77 | 78 | 79 | org.slf4j 80 | jcl-over-slf4j 81 | test 82 | 83 | 84 | org.slf4j 85 | slf4j-simple 86 | test 87 | 88 | 89 | 90 | junit 91 | junit 92 | test 93 | 94 | 95 | 96 | io.rest-assured 97 | rest-assured 98 | 4.0.0 99 | test 100 | 101 | 102 | commons-logging 103 | commons-logging 104 | 105 | 106 | 107 | org.hamcrest 108 | hamcrest-core 109 | 110 | 111 | org.hamcrest 112 | hamcrest-library 113 | 114 | 115 | 116 | 117 | 118 | org.apache.tomee 119 | arquillian-tomee-embedded 120 | test 121 | 122 | 123 | org.apache.tomee 124 | tomee-embedded 125 | test 126 | 127 | 128 | org.slf4j 129 | slf4j-jdk14 130 | 131 | 132 | commons-logging 133 | commons-logging 134 | 135 | 136 | 137 | 138 | org.apache.tomee 139 | tomee-jaxrs 140 | test 141 | 142 | 143 | 144 | 145 | 146 | 147 | org.jacoco 148 | jacoco-maven-plugin 149 | 0.8.6 150 | 151 | ${jacoco.executionDataFile} 152 | ${jacoco.executionDataFile} 153 | ${jacoco.includes} 154 | ${jacoco.excludes} 155 | 156 | 157 | 158 | prepare-agent 159 | 160 | prepare-agent 161 | 162 | 163 | 164 | 165 | 166 | 167 | org.apache.maven.plugins 168 | maven-surefire-plugin 169 | 3.0.0-M5 170 | 171 | ${surefire.skipTests} 172 | 173 | ${surefire.include} 174 | 175 | 176 | ${surefire.exclude} 177 | 178 | ${surefire.forkCount} 179 | false 180 | ${surefire.groups} 181 | ${surefire.excludedGroups} 182 | 183 | ${project.build.directory}/surefire-fork/${surefire.forkNumber}/ 184 | 185 | 186 | 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /srv-java/integration-tests/src/test/java/rfctest/HelloWorldServletTest.java: -------------------------------------------------------------------------------- 1 | package rfctest; 2 | 3 | import io.restassured.RestAssured; 4 | import org.jboss.arquillian.container.test.api.Deployment; 5 | import org.jboss.arquillian.junit.Arquillian; 6 | import org.jboss.arquillian.test.api.ArquillianResource; 7 | import org.jboss.shrinkwrap.api.spec.WebArchive; 8 | import org.junit.Before; 9 | import org.junit.BeforeClass; 10 | import org.junit.Test; 11 | import org.junit.runner.RunWith; 12 | import java.net.URL; 13 | 14 | import rfctest.HelloWorldServlet; 15 | import com.sap.cloud.sdk.testutil.MockUtil; 16 | 17 | import static io.restassured.RestAssured.given; 18 | import static org.assertj.core.api.Assertions.assertThat; 19 | 20 | @RunWith( Arquillian.class ) 21 | public class HelloWorldServletTest 22 | { 23 | private static final MockUtil mockUtil = new MockUtil(); 24 | 25 | @ArquillianResource 26 | private URL baseUrl; 27 | 28 | @Deployment 29 | public static WebArchive createDeployment() 30 | { 31 | return TestUtil.createDeployment(HelloWorldServlet.class); 32 | } 33 | 34 | @BeforeClass 35 | public static void beforeClass() 36 | { 37 | mockUtil.mockDefaults(); 38 | } 39 | 40 | @Before 41 | public void before() 42 | { 43 | RestAssured.baseURI = baseUrl.toExternalForm(); 44 | } 45 | 46 | @Test 47 | public void testService() 48 | { 49 | final String body = given().get("/hello").body().asString(); 50 | assertThat(body).isEqualToIgnoringCase("Hello World!"); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /srv-java/integration-tests/src/test/java/rfctest/TestUtil.java: -------------------------------------------------------------------------------- 1 | package rfctest; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.sap.cloud.sdk.cloudplatform.connectivity.HttpClientsThreadContextListener; 6 | import com.sap.cloud.sdk.cloudplatform.exception.ShouldNotHappenException; 7 | import com.sap.cloud.sdk.cloudplatform.security.principal.PrincipalThreadContextListener; 8 | import com.sap.cloud.sdk.cloudplatform.servlet.RequestAccessorFilter; 9 | import com.sap.cloud.sdk.cloudplatform.tenant.TenantThreadContextListener; 10 | import io.restassured.mapper.ObjectMapperType; 11 | import org.jboss.shrinkwrap.api.ArchivePaths; 12 | import org.jboss.shrinkwrap.api.ShrinkWrap; 13 | import org.jboss.shrinkwrap.api.asset.ByteArrayAsset; 14 | import org.jboss.shrinkwrap.api.spec.WebArchive; 15 | 16 | public class TestUtil 17 | { 18 | public static WebArchive createDeployment( final Class... classesUnderTest ) 19 | { 20 | return ShrinkWrap 21 | .create(WebArchive.class) 22 | .addClasses(classesUnderTest) 23 | .addClass(RequestAccessorFilter.class) 24 | .addClass(TenantThreadContextListener.class) 25 | .addClass(PrincipalThreadContextListener.class) 26 | .addClass(HttpClientsThreadContextListener.class) 27 | .addAsManifestResource("arquillian.xml") 28 | .addAsWebInfResource(new ByteArrayAsset("".getBytes()), ArchivePaths.create("beans.xml")); 29 | } 30 | 31 | public static ObjectMapperType objectMapperType() 32 | { 33 | return ObjectMapperType.JACKSON_2; 34 | } 35 | 36 | public static String toJson( final Object obj ) 37 | { 38 | try { 39 | return new ObjectMapper().writeValueAsString(obj); 40 | } 41 | catch( final JsonProcessingException e ) { 42 | throw new ShouldNotHappenException(e); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /srv-java/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | applications: 3 | 4 | - name: rfctest 5 | memory: 1024M 6 | timeout: 300 7 | random-route: true 8 | path: application/target/rfctest-application.war 9 | buildpacks: 10 | - sap_java_buildpack 11 | env: 12 | TARGET_RUNTIME: tomee7 13 | SET_LOGGING_LEVEL: '{ROOT: INFO, com.sap.cloud.sdk: INFO}' 14 | JBP_CONFIG_SAPJVM_MEMORY_SIZES: 'metaspace:128m..' 15 | # services: 16 | # - my-application-logs 17 | # - my-xsuaa 18 | # - my-destination 19 | # - my-connectivity 20 | -------------------------------------------------------------------------------- /srv-java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 4.0.0 7 | 8 | rfctest - Root 9 | rfctest - Root 10 | 11 | rfctest 12 | rfctest 13 | 1.0-SNAPSHOT 14 | pom 15 | 16 | 17 | 18 | 19 | com.sap.cloud.sdk 20 | sdk-bom 21 | 3.78.0 22 | pom 23 | import 24 | 25 | 26 | 27 | 28 | 29 | 1.8 30 | 31 | ${java.version} 32 | ${java.version} 33 | ${java.version} 34 | ${java.version} 35 | 36 | UTF-8 37 | UTF-8 38 | UTF-8 39 | 40 | 41 | 42 | application 43 | integration-tests 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.apache.maven.plugins 51 | maven-pmd-plugin 52 | 3.16.0 53 | 54 | 55 | rulesets/cloud-sdk-qualities.xml 56 | rulesets/java/maven-pmd-plugin-default.xml 57 | 58 | 59 | 60 | 61 | com.sap.cloud.sdk.quality 62 | pmd-rules 63 | 3.66.0 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | org.apache.maven.plugins 72 | maven-enforcer-plugin 73 | 3.0.0 74 | 75 | 76 | SAP Cloud SDK Project Structure Checks 77 | 78 | enforce 79 | 80 | 81 | 82 | 83 | 3.5 84 | 85 | 86 | ${java.version} 87 | 88 | 89 | project.artifactId 90 | [^_]+ 91 | "The artifactId should not contain underscores (_) 92 | as this causes issues when deploying to Cloud Foundry." 93 | 94 | 95 | 96 | true 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /srv/.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.com/ 2 | //73555000100200018064.npmsrv.cdn.repositories.cloud.sap/:_auth=${SAP_NPM_AUTH} 3 | -------------------------------------------------------------------------------- /srv/express.js: -------------------------------------------------------------------------------- 1 | // load modules 2 | const express = require("express"); 3 | // const fesr = require("@sap/fesr-to-otel-js"); 4 | 5 | // For authentication test 6 | const passport = require("passport"); 7 | const xsenv = require("@sap/xsenv"); 8 | xsenv.loadEnv(); 9 | const { XssecPassportStrategy, XsuaaService } = require("@sap/xssec"); 10 | const services = xsenv.getServices({ xsuaa: { tags: "xsuaa" } }); 11 | const authService = new XsuaaService(services.xsuaa); 12 | // console.log(services.xsuaa); 13 | const { jwtDecode } = require("jwt-decode"); 14 | const { executeHttpRequest } = require("@sap-cloud-sdk/http-client"); 15 | const { sendMail } = require("@sap-cloud-sdk/mail-client"); 16 | const { retrieveJwt, getDestination } = require("@sap-cloud-sdk/connectivity"); 17 | 18 | // config 19 | const host = process.env.HOST || "0.0.0.0"; 20 | const port = process.env.PORT || 4004; 21 | 22 | (async () => { 23 | // create new app 24 | const app = express(); 25 | // fesr.registerFesrEndpoint(app); 26 | // Authentication using JWT 27 | passport.use(new XssecPassportStrategy(authService)); 28 | app.use(passport.initialize()); 29 | app.use(passport.authenticate("JWT", { session: false })); 30 | 31 | await app.get("/api/userInfo", function (req, res) { 32 | res.header("Content-Type", "application/json"); 33 | res.send(JSON.stringify(req.user)); 34 | }); 35 | 36 | await app.get("/api/jwt", function (req, res) { 37 | res.header("Content-Type", "application/json"); 38 | res.send(JSON.stringify({ JWT: retrieveJwt(req) })); 39 | }); 40 | await app.get("/api/jwtdecode", function (req, res) { 41 | if (!req.user) { 42 | res.statusCode = 403; 43 | res.end(`Missing JWT Token`); 44 | } else { 45 | res.statusCode = 200; 46 | res.header("Content-Type", "application/json"); 47 | res.end(`${JSON.stringify(jwtDecode(retrieveJwt(req)))}`); 48 | } 49 | }); 50 | 51 | await app.get("/api/public/ping", async function (req, res) { 52 | try { 53 | const resultServiceCollection = await executeHttpRequest( 54 | getDestination(req), 55 | { 56 | method: "get", 57 | url: "/sap/public/ping", 58 | } 59 | ); 60 | res.send(resultServiceCollection.data); 61 | } catch (error) { 62 | let message = error.message; 63 | if (error.rootCause && error.rootCause.message) { 64 | message += " Root Cause: " + error.rootCause.message; 65 | } 66 | res.send(message); 67 | } 68 | }); 69 | 70 | await app.get("/api/bc/ping", async function (req, res) { 71 | try { 72 | const resultServiceCollection = await executeHttpRequest( 73 | { 74 | destinationName: process.env.DESTINATION || "SAP_ABAP_BACKEND", 75 | jwt: retrieveJwt(req), 76 | }, 77 | { 78 | method: "get", 79 | url: "/sap/bc/ping", 80 | } 81 | ); 82 | res.send(resultServiceCollection.data); 83 | } catch (error) { 84 | let message = error.message; 85 | if (error.rootCause && error.rootCause.message) { 86 | message += " Root Cause: " + error.rootCause.message; 87 | } 88 | res.send(message); 89 | } 90 | }); 91 | 92 | await app.get("/api/sendmail", async function (req, res) { 93 | const from = req.query.from || "sender@dummy.com"; 94 | const to = req.query.to || "receiver@dummy.com"; 95 | const destination = req.query.destination || "inbucket"; 96 | console.log("Destination to send mail: " + destination); 97 | try { 98 | const mailConfig = { 99 | from, 100 | to, 101 | subject: "Test from HTML5UserAPIforCF", 102 | text: "Test Body from HTML5UserAPIforCF", 103 | }; 104 | console.log("Mail Config: " + JSON.stringify(mailConfig)); 105 | const resolvedDestination = await getDestination({ 106 | destinationName: destination, 107 | jwt: retrieveJwt(req), 108 | }); 109 | 110 | const mailClientOptions = {}; 111 | // mail. properties allow only lowercase 112 | if ( 113 | resolvedDestination.originalProperties[ 114 | "mail.clientoptions.ignoretls" 115 | ] === "true" 116 | ) { 117 | mailClientOptions.ignoreTLS = true; 118 | } 119 | console.log("Mail Client Options: " + JSON.stringify(mailClientOptions)); 120 | // use sendmail as you should use it in nodemailer 121 | const result = await sendMail( 122 | { destinationName: destination, jwt: retrieveJwt(req) }, 123 | [mailConfig], 124 | mailClientOptions 125 | ); 126 | res.send(JSON.stringify(result)); 127 | } catch (error) { 128 | res.send(error); 129 | } 130 | }); 131 | 132 | // start server 133 | const server = app.listen(port, host, () => { 134 | console.info(`app is listing at ${port}`); 135 | const used = process.memoryUsage().heapUsed / 1024 / 1024; 136 | console.log( 137 | `The script uses approximately ${Math.round(used * 100) / 100} MB` 138 | ); 139 | }); 140 | server.on("error", (error) => console.error(error.stack)); 141 | })(); 142 | -------------------------------------------------------------------------------- /srv/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "html5userapi-srv", 3 | "engines": { 4 | "node": "^22" 5 | }, 6 | "dependenciesx": { 7 | "@sap/fesr-to-otel-js": "https://73555000100200018064.npmsrv.cdn.repositories.cloud.sap/@sap/fesr-to-otel-js/-/fesr-to-otel-js-1.5.3.tgz" 8 | }, 9 | "dependencies": { 10 | "@sap-cloud-sdk/connectivity": "^3", 11 | "@sap-cloud-sdk/http-client": "^3", 12 | "@sap-cloud-sdk/mail-client": "^3", 13 | "@sap-cloud-sdk/util": "^3", 14 | "@sap/xsenv": "^5.4.0", 15 | "@sap/xssec": "^4.2.7", 16 | "express": "^4.21.1", 17 | "jwt-decode": "^4.0.0", 18 | "lodash": "^4.17.21", 19 | "passport": "^0.7.0" 20 | }, 21 | "devDependencies": {}, 22 | "scripts": { 23 | "postinstall": "npm dedupe", 24 | "start": "node --inspect express.js" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/approuter.http: -------------------------------------------------------------------------------- 1 | ### 2 | GET http://localhost:5000/services/userapi/currentUser 3 | Authorization: Bearer {{$dotenv bearerToken}} -------------------------------------------------------------------------------- /test/basic-auth.http: -------------------------------------------------------------------------------- 1 | @requestId=hello\ntest 2 | ### 3 | GET {{$dotenv approuter_url}}/sap_basic_auth/bc/ping 4 | x-request-id: {{requestId}} 5 | x-vcap-request-id: {{requestId}} 6 | Authorization: Basic {{$dotenv username_ias}}:{{$dotenv password_ias}} 7 | ### dynamicIdentityProvider = true seems not to apply for routes with basic auth 8 | GET {{$dotenv approuter_url}}/sap_basic_auth_dyn_idp/bc/ping?sap_idp=sap.custom 9 | Authorization: Basic {{$dotenv username_ias}}:{{$dotenv password_ias}} 10 | ### login_hint also does not work for routes with basic auth 11 | GET {{$dotenv approuter_url}}/sap_basic_auth/bc/ping?login_hint=%7B%22origin%22%3A%22sap.custom%22%7D 12 | Authorization: Basic {{$dotenv username_ias}}:{{$dotenv password_ias}} 13 | ### Routes with basic auth only authenticate via the custom IDP when the security settings where changed 14 | ### according to SAP Note: https://me.sap.com/notes/3042924 15 | ### 3042924 - How to change the default identity provider for password grant flow on Cloud Foundry 16 | ### Use the script: 17 | ### https://github.com/gregorwolf/bookshop-demo/blob/main/tests/xsuaa-configure.http#L28 18 | ### 19 | GET {{$dotenv approuter_url}}/sap_basic_auth/bc/ping 20 | Authorization: Basic {{$dotenv username_ias}}:{{$dotenv password_ias}} 21 | ### 22 | GET {{$dotenv approuter_url}}/sap_basic_auth/opu/odata/SAP/EPM_REF_APPS_SHOP_SRV/$metadata 23 | Authorization: Basic {{$dotenv username_ias}}:{{$dotenv password_ias}} 24 | ### 25 | GET {{$dotenv approuter_url}}/sap_basic_auth/opu/odata/SAP/EPM_REF_APPS_SHOP_SRV/ 26 | Authorization: Basic {{$dotenv username_ias}}:{{$dotenv password_ias}} 27 | Accept: application/json 28 | ### 29 | GET {{$dotenv approuter_url}}/sap_basic_auth/opu/odata/SAP/EPM_REF_APPS_SHOP_SRV/MainCategories 30 | Authorization: Basic {{$dotenv username_ias}}:{{$dotenv password_ias}} 31 | Accept: application/json 32 | ### 33 | # @name getProducts 34 | GET {{$dotenv approuter_url}}/sap_basic_auth/opu/odata/SAP/EPM_REF_APPS_SHOP_SRV/Products 35 | ?$top=10 36 | &$inlinecount=allpages 37 | &$filter=MainCategoryId eq 'Meeting %26 Presenting' 38 | &$orderby=StockQuantity desc 39 | Authorization: Basic {{$dotenv username_ias}}:{{$dotenv password_ias}} 40 | Accept: application/json 41 | ### 42 | @productId={{getProducts.response.body.$.d.results.0.Id}} 43 | ### Get CSRF Token 44 | # @name getCSRF 45 | HEAD {{$dotenv approuter_url}}/sap_basic_auth/opu/odata/SAP/EPM_REF_APPS_SHOP_SRV/ 46 | X-CSRF-Token: Fetch 47 | Authorization: Basic {{$dotenv username_ias}}:{{$dotenv password_ias}} 48 | ### Read Token to Variable 49 | @CSRF={{getCSRF.response.headers.x-csrf-token}} 50 | ### 51 | POST {{$dotenv approuter_url}}/sap_basic_auth/opu/odata/SAP/EPM_REF_APPS_SHOP_SRV/AddProductToShoppingCart?ProductId='{{productId}} 52 | Authorization: Basic {{$dotenv username_ias}}:{{$dotenv password_ias}} 53 | X-CSRF-Token: {{CSRF}} 54 | Accept: application/json 55 | ### 56 | GET {{$dotenv approuter_url}}/sap_basic_auth/opu/odata/sap/ZAPI_USER_NAME_SRV/UserDetailsSet 57 | Authorization: Basic {{$dotenv username_ias}}:{{$dotenv password_ias}} 58 | Accept: application/json 59 | ### 60 | GET {{$dotenv approuter_url}}/sap_basic_auth/opu/odata/sap/ZEPM_BP_GW_SRV/ 61 | Authorization: Basic {{$dotenv username_ias}}:{{$dotenv password_ias}} 62 | Accept: application/json 63 | -------------------------------------------------------------------------------- /test/call-srv.http: -------------------------------------------------------------------------------- 1 | ### Request Access Token 2 | # @name requestAccessToken 3 | POST {{$dotenv btp_tokenendpoint}}/oauth/token 4 | Accept: application/json 5 | Authorization: Basic {{$dotenv btp_clientid}}:{{$dotenv btp_clientsecret}} 6 | Content-Type: application/x-www-form-urlencoded 7 | 8 | grant_type=password 9 | #&username={{$dotenv username}} 10 | #&password={{$dotenv password}} 11 | &username={{$dotenv username_ias}} 12 | &password={{$dotenv password_ias}} 13 | &client_id={{$dotenv btp_clientid}} 14 | &response_type=token 15 | &login_hint={"origin":"sap.custom"} 16 | ### Fill Variables from Response 17 | @access_token = {{requestAccessToken.response.body.$.access_token}} 18 | ### 19 | GET {{$dotenv server}}/api/userInfo 20 | Authorization: Bearer {{access_token}} 21 | 22 | ### 23 | GET {{$dotenv server}}/api/jwt 24 | Authorization: Bearer {{access_token}} 25 | 26 | ### 27 | GET {{$dotenv server}}/api/jwtdecode 28 | Authorization: Bearer {{access_token}} 29 | 30 | ### 31 | GET {{$dotenv server}}/api/public/ping 32 | Authorization: Bearer {{access_token}} 33 | 34 | ### 35 | GET {{$dotenv server}}/api/bc/ping 36 | Authorization: Bearer {{access_token}} 37 | ### 38 | GET {{$dotenv server}}/api/sendmail 39 | Authorization: Bearer {{access_token}} 40 | ### 41 | GET {{$dotenv server}}/api/sendmail 42 | ?destination=inbucket_direct 43 | &from=absender@dummy.com 44 | &to=empfaenger@dummy.com 45 | Authorization: Bearer {{access_token}} 46 | ### 47 | GET {{$dotenv approuter_url}}/sap/opu/odata/SAP/EPM_REF_APPS_SHOP_SRV/ 48 | x-approuter-authorization: Bearer {{access_token}} 49 | Accept: application/json 50 | ### 51 | GET {{$dotenv approuter_url}}/sap/opu/odata/SAP/EPM_REF_APPS_SHOP_SRV/MainCategories 52 | x-approuter-authorization: Bearer {{access_token}} 53 | Accept: application/json 54 | ### 55 | GET {{$dotenv approuter_url}}/sap/opu/odata/SAP/EPM_REF_APPS_SHOP_SRV/Products 56 | ?$top=10 57 | &$inlinecount=allpages 58 | &$filter=MainCategoryId eq 'Meeting %26 Presenting' 59 | &$orderby=StockQuantity desc 60 | x-approuter-authorization: Bearer {{access_token}} 61 | Accept: application/json 62 | -------------------------------------------------------------------------------- /xs-security.json: -------------------------------------------------------------------------------- 1 | { 2 | "xsappname": "HTML5UserAPIforCF", 3 | "tenant-mode": "dedicated", 4 | "description": "Security profile of called application", 5 | "scopes": [ 6 | { 7 | "name": "uaa.user", 8 | "description": "UAA" 9 | }, 10 | { 11 | "name": "$XSAPPNAME.Display", 12 | "description": "display" 13 | } 14 | ], 15 | "attributes": [ 16 | { 17 | "name": "company", 18 | "description": "Company", 19 | "valueType": "string" 20 | }, 21 | { 22 | "name": "department", 23 | "description": "Department", 24 | "valueType": "string" 25 | }, 26 | { 27 | "name": "country", 28 | "description": "Country", 29 | "valueType": "s" 30 | }, 31 | { 32 | "name": "city", 33 | "description": "City", 34 | "valueType": "string" 35 | }, 36 | { 37 | "name": "groups", 38 | "description": "Groups", 39 | "valueType": "s" 40 | } 41 | ], 42 | "role-templates": [ 43 | { 44 | "name": "Token_Exchange", 45 | "description": "UAA", 46 | "scope-references": [ 47 | "uaa.user" 48 | ] 49 | }, 50 | { 51 | "name": "Viewer", 52 | "description": "View all", 53 | "scope-references": [ 54 | "$XSAPPNAME.Display" 55 | ], 56 | "attribute-references": [ 57 | "company", 58 | "department", 59 | "country", 60 | "city", 61 | "groups" 62 | ] 63 | } 64 | ], 65 | "oauth2-configuration": { 66 | "redirect-uris": [ 67 | "https://localhost:5000/**", 68 | "http://localhost:5000/**", 69 | "https://*.hana.ondemand.com/**", 70 | "https://*.cloud.sap/**" 71 | ] 72 | } 73 | } 74 | --------------------------------------------------------------------------------