-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from felix-reck/dev
New Minor Version
- Loading branch information
Showing
8 changed files
with
332 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
function workplaceBody(workplace,state,timestamp){ | ||
|
||
let ts = timestamp ?? new Date(); //either provide date or current date is being used | ||
|
||
const body = { | ||
"params": [ | ||
{ | ||
"acronym": "service.logging_ts", | ||
"value": ts, | ||
"operator": "EQUAL" | ||
}, | ||
{ | ||
"acronym": "workplace.id", | ||
"value": workplace, | ||
"operator": "EQUAL" | ||
}, | ||
{ | ||
"acronym": "workplace.status.id", | ||
"value": state, | ||
"operator": "EQUAL" | ||
} | ||
], | ||
"columns": [], | ||
"returnAsObject": false | ||
} | ||
|
||
return body; | ||
} | ||
|
||
function customBody(body){ | ||
|
||
if (typeof body == 'string') { | ||
try { | ||
body = JSON.parse(body) | ||
} catch (error) { | ||
|
||
} | ||
} | ||
return body; | ||
} | ||
|
||
|
||
|
||
module.exports = { | ||
workplaceBody, | ||
customBody | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
const cookieJar = {}; // Shared Cookie Storage | ||
const axios = require('axios'); | ||
const https = require('https'); | ||
const responseHandler = require('./response-handler.js'); | ||
|
||
module.exports = { | ||
// Cookie Management | ||
getCookie: function (accessId) { | ||
return cookieJar[accessId]; | ||
}, | ||
setCookie: function (accessId, cookie) { | ||
cookieJar[accessId] = cookie; | ||
}, | ||
updateSessionCookie: function (responseHeaders, accessId) { | ||
const setCookieHeader = responseHeaders['set-cookie']; | ||
if (setCookieHeader) { | ||
const sessionCookie = setCookieHeader.find(cookie => cookie.startsWith('JSESSIONID')); | ||
if (sessionCookie) { | ||
this.setCookie(accessId, sessionCookie.split(';')[0]); | ||
} | ||
} | ||
}, | ||
|
||
// Helper Functions | ||
createOptions: function (config, requestBody) { | ||
const agent = new https.Agent({ rejectUnauthorized: config.sslVerify === 'true' }); | ||
const endpoint = new URL(config.servicetype + '/' + config.service, config.url); | ||
|
||
const optionsBase = { | ||
method: config.method, | ||
url: endpoint.href, | ||
data: requestBody, | ||
httpsAgent: agent | ||
} | ||
|
||
const optionsCookie = { | ||
headers: { | ||
'Cookie': this.getCookie(config.accessId), | ||
'Content-Type': 'application/json' | ||
} | ||
}; | ||
|
||
const optionsAuth = { | ||
auth: { | ||
username: config.user, | ||
password: config.password | ||
}, | ||
headers: { | ||
'X-Access-Id': config.accessId, | ||
'Content-Type': 'application/json' | ||
} | ||
}; | ||
return { optionsCookie: { ...optionsBase, ...optionsCookie }, optionsAuth: { ...optionsBase, ...optionsAuth } }; | ||
}, | ||
|
||
performRequest: async function (node, requestOptions) { | ||
let info = requestOptions.auth ? 'Requesting with credentials' : 'Requesting with cookie'; | ||
node.status({ fill: 'blue', shape: 'dot', text: info }); | ||
try { | ||
return await axios(requestOptions); | ||
} catch (error) { | ||
if (error.response) { | ||
// Der Request wurde ausgeführt und der Server hat eine Antwort gegeben | ||
const status = error.response.status; | ||
const errorMessage = `Error: Received ${status} - ${error.response.statusText}`; | ||
//node.error(errorMessage, { payload: error.response.data }); | ||
return { success: false, status, errorMessage }; // Rückgabe eines Fehlerobjekts | ||
} else { | ||
// Fehler, der nicht durch den Server zurückgegeben wurde | ||
node.error(`Error: ${error.message}`, { payload: error.message }); | ||
return { success: false, errorMessage: error.message }; // Rückgabe eines Fehlerobjekts | ||
} | ||
} | ||
}, | ||
|
||
// Response Handling | ||
handleResponse: function (response, format, servicetype, accessId) { | ||
let payload; | ||
if (format === 'modified' && servicetype === 'data') { | ||
payload = responseHandler.formatData(response.data); | ||
} else { | ||
payload = response.data; | ||
} | ||
|
||
this.updateSessionCookie(response.headers, accessId); // Update the session cookie | ||
|
||
return { | ||
payload, | ||
request: response.request._header, | ||
status: response.status | ||
}; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,125 +1,60 @@ | ||
const mipclient = require('./mip-client.js'); | ||
const bodyCreator = require('./body-creator.js'); | ||
const responseHandler = require('./response-handler.js'); | ||
|
||
module.exports = function (RED) { | ||
function HttpNode(config) { | ||
function httpNode(config) { | ||
RED.nodes.createNode(this, config); | ||
let node = this; | ||
let cookieJar = {}; // Cookie Storage | ||
|
||
node.on('input', async function (msg) { | ||
const axios = require('axios'); | ||
const https = require('https'); | ||
const responseHandler = require('./responseHandler.js'); | ||
node.name = config.name || 'mip-node'; | ||
|
||
node.name = config.name || 'HX'; | ||
// Input parameters | ||
const server = RED.nodes.getNode(config.server); | ||
const service = (config.service || msg.service || '').replace(/\./g, '/'); | ||
const method = config.method || 'GET'; | ||
const format = config.format; // || 'original'; | ||
const servicetype = config.servicetype; //meta oder data | ||
|
||
//Input parameters | ||
const server = RED.nodes.getNode(config.server); | ||
const url = server.url; | ||
const user = server.user; | ||
const password = server.password; | ||
const accessId = server.accessId; | ||
const sslVerify = server.sslVerify == 'true'; | ||
|
||
const agent = new https.Agent({ rejectUnauthorized: sslVerify }); | ||
const endpoint = new URL(servicetype + '/' + service, url); | ||
|
||
|
||
|
||
let payload = msg.payload; | ||
|
||
if (typeof payload == 'string') { | ||
try { | ||
payload = JSON.parse(payload) | ||
} catch (error) { | ||
|
||
} | ||
} | ||
|
||
payload = format == 'original' ? payload : { ...payload, ...{ returnAsObject: false } }; | ||
|
||
const optionsCookie = { | ||
const format = config.format; | ||
const servicetype = config.servicetype; | ||
|
||
// Create request body | ||
let requestBody = bodyCreator.customBody(msg.payload); | ||
requestBody = format === 'original' ? requestBody : { ...requestBody, returnAsObject: false }; | ||
|
||
// Create options for the request using the mip-client helper | ||
const options = mipclient.createOptions({ | ||
url: server.url, | ||
user: server.user, | ||
password: server.password, | ||
accessId: server.accessId, | ||
sslVerify: server.sslVerify, | ||
method: method, | ||
url: endpoint.href, | ||
headers: { | ||
'Cookie': cookieJar[accessId], | ||
'Content-Type': 'application/json' | ||
}, | ||
data: payload, | ||
httpsAgent: agent | ||
}; | ||
|
||
const optionsAuth = { | ||
auth: { | ||
username: user, | ||
password: password | ||
}, | ||
headers: { | ||
'X-Access-Id': accessId, | ||
'Content-Type': 'application/json' | ||
} | ||
}; | ||
|
||
const options = cookieJar[accessId] ? optionsCookie : { ...optionsCookie, ...optionsAuth }; | ||
|
||
try { | ||
const response = await performRequest(options); | ||
handleResponse(response, msg); | ||
} catch (error) { | ||
await handleRetry(error, optionsCookie, optionsAuth, msg); | ||
} | ||
service: service, | ||
servicetype: servicetype | ||
}, requestBody); | ||
|
||
|
||
async function performRequest(requestOptions) { | ||
let info = requestOptions.auth ? 'Requesting with credentials' : 'Requesting with cookie'; | ||
node.status({ fill: 'blue', shape: 'dot', text: info }); | ||
return await axios(requestOptions); | ||
let response = await mipclient.performRequest(node, options.optionsCookie); | ||
if (response.status === 401) { | ||
response = await mipclient.performRequest(node, options.optionsAuth); | ||
} | ||
if (response.status === 200) { | ||
const result = mipclient.handleResponse(response, format, servicetype, server.accessId); | ||
msg.payload = result.payload; | ||
msg.request = result.request; | ||
|
||
function handleResponse(response, msg) { | ||
|
||
if (format == 'modified' && servicetype == 'data') { | ||
msg.payload = responseHandler.formatData(response.data) | ||
} else { | ||
msg.payload = response.data | ||
|
||
} | ||
|
||
msg.request = response.request._header; | ||
const setCookieHeader = response.headers['set-cookie']; | ||
if (setCookieHeader) { | ||
const sessionCookie = setCookieHeader.find(cookie => cookie.startsWith('JSESSIONID')); | ||
if (sessionCookie) { | ||
cookieJar[accessId] = sessionCookie.split(';')[0]; | ||
} | ||
} | ||
node.status({ fill: 'green', shape: 'dot', text: 'Success, HTTP ' + response.status }); | ||
node.send(msg); | ||
} | ||
} else { | ||
node.status({ fill: 'red', shape: 'dot', text: 'Fail' }); | ||
node.error('FAIL') | ||
|
||
async function handleRetry(error, optionsCookie, optionsAuth, msg) { | ||
if (error.response && error.response.status === 401) { | ||
node.warn('Retry with Auth'); | ||
try { | ||
const response = await performRequest({ ...optionsCookie, ...optionsAuth }); | ||
handleResponse(response, msg); | ||
} catch (retryError) { | ||
node.status({ fill: 'red', shape: 'dot', text: 'Fail HTTP:' + retryError.status }); | ||
node.error(retryError.message, msg); | ||
node.send(retryError); | ||
} | ||
} else { | ||
node.status({ fill: 'red', shape: 'dot', text: 'Fail' }); | ||
node.error(error.message, msg); | ||
node.send(error); | ||
} | ||
} | ||
}); | ||
|
||
|
||
|
||
}); | ||
} | ||
|
||
RED.nodes.registerType('mip', HttpNode); | ||
RED.nodes.registerType('mip', httpNode); | ||
}; |
Oops, something went wrong.