Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions template/open-abap/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ COPY index.js ./
RUN npm i

# Trigger the transpilation
COPY scripts ./scripts
COPY function ./function
RUN npm run build

# TODO: Add parameter to toggle tessting during docker build
# TODO: Add parameter to toggle testing during docker build
# # Run any tests that may be available
# RUN npm test

Expand Down
8 changes: 8 additions & 0 deletions template/open-abap/abap_loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const transpiler = require("@abaplint/transpiler");

module.exports = async function(source, map, meta) {
const t = new transpiler.Transpiler();
const result = await t.run([{filename: this.resourcePath, contents: source}]);
return "const abap = require('@abaplint/runtime');\n" +
"export " + result.js[0].contents;
}
41 changes: 41 additions & 0 deletions template/open-abap/function/zcl_handler.clas.abap
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
CLASS zcl_handler DEFINITION PUBLIC.

PUBLIC SECTION.
TYPES: BEGIN OF ty_header,
field TYPE string,
value TYPE string,
END OF ty_header.

TYPES ty_headers TYPE STANDARD TABLE OF ty_header WITH DEFAULT KEY.

TYPES: BEGIN OF ty_http,
headers TYPE ty_headers,
body TYPE string,
END OF ty_http.

METHODS:
run
IMPORTING
method TYPE string OPTIONAL
path TYPE string OPTIONAL
query TYPE string OPTIONAL
" request TYPE ty_http OPTIONAL
body TYPE string OPTIONAL "TODO: Remove in favor of request once structures are supported RETURNING
VALUE(response) TYPE ty_http
RAISING
cx_static_check.

ENDCLASS.

CLASS zcl_handler IMPLEMENTATION.

METHOD run.
* Put your ABAP code here.
* In the end, move the (stringified) result to the body of the response

* response-body = my-result


ENDMETHOD.

ENDCLASS.
53 changes: 31 additions & 22 deletions template/open-abap/index.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,33 @@
"use strict"

import "regenerator-runtime/runtime";

const express = require('express')
const app = express()
const handler = require('./build/handler'); // this is the JS source which has been transpiled from ABAP
const abap = require('./function/zcl_handler.clas.abap'); // this is the JS source which has been transpiled from ABAP
const bodyParser = require('body-parser')

if (process.env.RAW_BODY === 'true') {
app.use(bodyParser.raw({ type: '*/*' }))
} else {
var jsonLimit = process.env.MAX_JSON_SIZE || '100kb' //body-parser default
app.use(bodyParser.json({ limit: jsonLimit}));
app.use(bodyParser.json({ limit: jsonLimit }));
app.use(bodyParser.raw()); // "Content-Type: application/octet-stream"
app.use(bodyParser.text({ type : "text/*" }));
app.use(bodyParser.text({ type: "text/*" }));
}

app.disable('x-powered-by');

class FunctionEvent {
constructor(req) {
this.body = req.body;
this.headers = req.headers;
this.method = req.method;
this.query = req.query;
// this.query = req.query; //TODO: Stringify query parameters - it's a string in the handler
this.path = req.path;
// this.request = { // TODO: Re-enable once structures are supported
// body: req.body,
// headers: req.headers
// }
this.body = req.body;
}
}

Expand All @@ -35,7 +40,7 @@ class FunctionContext {
}

status(value) {
if(!value) {
if (!value) {
return this.value;
}

Expand All @@ -44,12 +49,12 @@ class FunctionContext {
}

headers(value) {
if(!value) {
if (!value) {
return this.headerValues;
}

this.headerValues = value;
return this;
return this;
}

succeed(value) {
Expand All @@ -73,27 +78,30 @@ var middleware = async (req, res) => {
return res.status(500).send(err.toString ? err.toString() : err);
}

if(isArray(functionResult) || isObject(functionResult)) {
if (isArray(functionResult) || isObject(functionResult)) {
res.set(fnContext.headers()).status(fnContext.status()).send(JSON.stringify(functionResult));
} else {
res.set(fnContext.headers()).status(fnContext.status()).send({result: functionResult});
res.set(fnContext.headers()).status(fnContext.status()).send({ result: functionResult });
}
};

let fnEvent = new FunctionEvent(req);
let fnContext = new FunctionContext(cb);

Promise.resolve(handler(fnEvent))
.then(res => {
if(!fnContext.cbCalled) {
fnContext
.status(200)
.succeed(res)
}
})
.catch(e => {
cb(e);
});
/* Invoke the ABAP handler */
const response = await new abap.zcl_handler().run(fnEvent);

const headers = {};
for (const h of response.get().headers.array()) {
headers[h.get().field.get()] = h.get().value.get();
}

if (!fnContext.cbCalled) {
fnContext
.status(200)
.headers(headers)
.succeed(response.get().body.get())
}
};

app.post('/*', middleware);
Expand All @@ -106,6 +114,7 @@ const port = process.env.http_port || 3000;

app.listen(port, () => {
console.log(`OpenFaaS Node.js to execute ABAP listening on port: ${port}`)
app.emit( "app_started" )
});

let isArray = (a) => {
Expand Down
Loading