はじめに
functionノードの外部npmモジュールを使用する場合、enebularのNode-REDフローエディタは正常に動作しますが、クラウド実行環境ではエラーが発生します。
enebularでクラウド実行環境を利用する場合、外部npmモジュールの使用に注意!
今後の機能拡張に期待します。
2024年2月3日 追記
外部npmモジュールを使用せず、functionノードにコード(npmモジュールの関数)を書くことでエラーを回避しました。
function getBoundary(header){
if (typeof header === 'undefined' || header === null) {
return "";
}
var items = header.split(';');
if(items)
for(let i=0;i<items.length;i++){
var item = (new String(items[i])).trim();
if(item.indexOf('boundary') >= 0){
var k = item.split('=');
return (new String(k[1])).trim();
}
}
return "";
}
function obj(str){
if (typeof str === 'undefined' || str === null) {
return {};
}
var k = str.split('=');
if (k.length < 2) { // '='で分割した結果が2つの要素を持たない場合
return {}; // または適切なエラーハンドリング
}
var a = k[0].trim();
var b = JSON.parse(k[1].trim());
var o = {};
Object.defineProperty( o , a ,
{ value: b, writable: true, enumerable: true, configurable: true })
return o;
}
function process1(part){
if (typeof part.header === 'undefined' || part.header === null) {
return {};
}
var header = part.header.split(';');
var file = obj(header.length > 2 ? header[2] : null); // header[2]が存在しない場合はnullを渡す
if (typeof part.info === 'undefined' || part.info === null || !part.info.includes(':')) {
return file; // part.infoが不正な形式の場合はfileをそのまま返す
}
var contentTypeParts = part.info.split(':');
if (contentTypeParts.length < 2) {
return file; // ':'で分割した結果が2つの要素を持たない場合
}
var file = obj(header[2]);
var contentType = part.info.split(':')[1].trim();
Object.defineProperty( file , 'type' ,
{ value: contentType, writable: true, enumerable: true, configurable: true })
Object.defineProperty( file , 'data' ,
{ value: new Buffer(part.part), writable: true, enumerable: true, configurable: true })
return file;
}
function Parse(multipartBodyBuffer,boundary){
var prev = null;
var lastline='';
var header = '';
var info = ''; var state=0; var buffer=[];
var allParts = [];
for(let i=0;i<multipartBodyBuffer.length;i++){
var oneByte = multipartBodyBuffer[i];
var prevByte = i > 0 ? multipartBodyBuffer[i-1] : null;
var newLineDetected = ((oneByte == 0x0a) && (prevByte == 0x0d)) ? true : false;
var newLineChar = ((oneByte == 0x0a) || (oneByte == 0x0d)) ? true : false;
if(!newLineChar)
lastline += String.fromCharCode(oneByte);
if((0 == state) && newLineDetected){
if(("--"+boundary) == lastline){
state=1;
}
lastline='';
}else
if((1 == state) && newLineDetected){
header = lastline;
state=2;
lastline='';
}else
if((2 == state) && newLineDetected){
info = lastline;
state=3;
lastline='';
}else
if((3 == state) && newLineDetected){
state=4;
buffer=[];
lastline='';
}else
if(4 == state){
if(lastline.length > (boundary.length+4)) lastline=''; // mem save
if(((("--"+boundary) == lastline))){
var j = buffer.length - lastline.length;
var part = buffer.slice(0,j-1);
var p = { header : header , info : info , part : part };
allParts.push(process1(p));
buffer = []; lastline=''; state=5; header=''; info='';
}else{
buffer.push(oneByte);
}
if(newLineDetected) lastline='';
}else
if(5==state){
if(newLineDetected)
state=1;
}
}
return allParts;
};
const body = msg.payload;
const lines = body.toString().split('\r\n');
const boundary = lines[0].slice(2);
const parts = Parse(body, boundary);
//msg.payload = parts;
msg.payload = parts[0].data;
return msg;
カスタムノード
ついでにNode-REDのカスタムノードとenebularのプライベートノードを作成しました。
- enebularのプライベートノード
- Node-REDのカスタムノード
(参考)
問い合わせ内容
回答結果
Node-REDフロー
-
s3-test-01プロジェクト
- lcdp-image-upload-test-01フロー
フローエディタ
データストア
multipart/form-dataデータを入力し、構造化データを出力するfunctionノード
クラウド実行環境のログ
Welcome to Node-RED
===================
[Jan 28th 2024, 23:04:55]: 2024-01-28T14:04:55.018Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO 28 Jan 14:04:55 - [info] Node-RED version: v3.0.2-c.2
[Jan 28th 2024, 23:04:55]: 2024-01-28T14:04:55.018Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO 28 Jan 14:04:55 - [info] Node.js version: v18.18.2
[Jan 28th 2024, 23:04:55]: 2024-01-28T14:04:55.018Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO 28 Jan 14:04:55 - [info] Linux 5.10.201-213.748.amzn2.x86_64 x64 LE
[Jan 28th 2024, 23:04:58]: 2024-01-28T14:04:58.618Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO 28 Jan 14:04:58 - [info] Loading palette nodes
[Jan 28th 2024, 23:05:06]: 2024-01-28T14:05:06.319Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO 28 Jan 14:05:06 - [info] Context store : 'default' [module=memory]
[Jan 28th 2024, 23:05:06]: 2024-01-28T14:05:06.336Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO Node-RED server started.
[Jan 28th 2024, 23:05:06]: 2024-01-28T14:05:06.397Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO 28 Jan 14:05:06 - [warn] Using unencrypted credentials
[Jan 28th 2024, 23:05:06]: 2024-01-28T14:05:06.437Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO 28 Jan 14:05:06 - [info] Installing module: parse-multipart-data, version: latest
[Jan 28th 2024, 23:05:07]: 2024-01-28T14:05:07.337Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO passing event to aws-lambda-io event emitter
[Jan 28th 2024, 23:05:15]: 2024-01-28T14:05:15.039Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO 28 Jan 14:05:15 - [error] Installation of module parse-multipart-data failed:
[Jan 28th 2024, 23:05:15]: 2024-01-28T14:05:15.039Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO 28 Jan 14:05:15 - [error] ------------------------------------------
[Jan 28th 2024, 23:05:15]: 2024-01-28T14:05:15.039Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO 28 Jan 14:05:15 - [error] npm WARN config production Use `--omit=dev` instead.
npm ERR! code ENOENT
npm ERR! syscall mkdir
npm ERR! path /home/sbx_user1051
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, mkdir '/home/sbx_user1051'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent
npm ERR! Log files were not written due to an error writing to the directory: /home/sbx_user1051/.npm/_logs
npm ERR! You can rerun the command with `--loglevel=verbose` to see the logs in your terminal
[Jan 28th 2024, 23:05:15]: 2024-01-28T14:05:15.056Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO 28 Jan 14:05:15 - [error] ------------------------------------------
[Jan 28th 2024, 23:05:15]: 2024-01-28T14:05:15.076Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO 28 Jan 14:05:15 - [info] Failed to load external modules required by this flow:
[Jan 28th 2024, 23:05:15]: 2024-01-28T14:05:15.076Z 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 INFO 28 Jan 14:05:15 - [info] - parse-multipart-data [unexpected_error]
[Jan 28th 2024, 23:05:15]: END RequestId: 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0
[Jan 28th 2024, 23:05:15]: REPORT RequestId: 9f7d3cb9-ffc6-4f2e-9195-e8cf8030afa0 Duration: 20230.99 ms Billed Duration: 20231 ms Memory Size: 256 MB Max Memory Used: 209 MB Init Duration: 725.75 ms