Here's my code in nodeJS.. When I deployed it to my local it is always run ok, but when i deployed it on the production I always got an error "ArrayBuffer not defined". Can someone tell me what it caused? I'll tried to add ArrayBuffer but I got the same error. Thanks
var svr = http.createServer(function(req, resp) {
var response = [];
var calls = [];
var windowLiveId;
var huaweiReturnCode;
var serviceId = apigeeAccess.getVariable(req,'subscription.serviceid');
var ericssonRequestBody = {"offerId":serviceId,"generateBillingRecord":true };
calls.push(function(callback) {
http.get('http://butcha-test.apigee.net/v1/accounts/', function (resource) {
resource.setEncoding('binary');
resource.on('data', function (data) {
windowLiveId = JSON.parse(data).AccountId;
request.post({
url:'http://butcha-test.apigee.net/v1/erickson/'+windowLiveId,
method: 'POST',
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify(ericssonRequestBody)
}, function(error,res,body){
apigeeAccess.setVariable(req,"ericsonStatus",(/2[0-9][0-9]/.test(res.statusCode)) ? "success":"fail");
apigeeAccess.setVariable(req,"ericsonStatusCode",res.statusCode);
callback();
});
});
});
});
calls.push(function(callback){
request.post({
url:'http://morning-sea-3467.getsandbox.com/mockOverseaBossServiceSoapBinding',
method: 'POST',
headers: {'content-type' : 'application/xml'},
body: huaweiSoapRequest
}, function(error,res,body){
response.push(body);
var tag = "<bean:returnCode>";
var x = body.indexOf(tag) + tag.length;
huaweiReturnCode = body.substring(x, (x+1));
apigeeAccess.setVariable(req,"huaweiReturnCode",huaweiReturnCode);
apigeeAccess.setVariable(req,"huaweiStatusResult",(huaweiReturnCode =="0")? "success":"fail");
callback();
});
});
async.parallel(calls, function(){
resp.end(str2ab(response.toString));
});
});
Maybe because of the version of your Apigee? Because older version of Apigee is not supported nodeJs
Related
I am trying to call Databricks api to run a notebook or job by its ID by the API endpoint api/2.0/jobs/run-now but I am getting an error like getaddrinfo ENOTFOUND https://adb-<workspace-id>.<random-number>.azuredatabricks.net/api/2.0/jobs/run-now. But I am giving the right url (NOTE: I copied the url from the browser address bar till .net as per the example mentioned in : Example Job API
Below is my Node.JS code :
router.get('/triggerJob', (req, res) => {
var job_payload = {
"job_id": <Job_ID>
}
var options = {
host: 'https://adb-<workspaceid>.<number>.azuredatabricks.net/api/2.0/jobs/run-now',
body: JSON.stringify(job_payload),
method: 'Post',
headers: { 'Authorization': 'token' }
}
var data = '';
console.log('till here')
var request = https.request(options, function (result) {
var body = "";
result.on('data', function (data) {
console.log('data came');
body += data;
});
result.on('end', function () {
console.log('ended too');
data = JSON.parse(body);
res.json(data);
});
});
request.on('error', function (e) {
console.log('Problem with request: ' + e.message);
});
request.end();
})
As I got Solution for my question I want share it with all for the future refernce.
According to microsoft docs: enter link description here
They ask us to hit the url with https://adb-<workspaceid>.<number>.azuredatabricks.net/api/2.0/jobs/run-now but I got is we need to hit the url:
https://<{locationname}>.azuredatabricks.net then api/2.0/jobs/run-now. So below is the code for the same:
const request=require("request");
const rp=require("request-promise");
const triggerJob=((res,req)=>{
var job_payload = {
"job_id": <Job_ID>
}
var options = {
host: 'https://<locationname>.azuredatabricks.net/api/2.0/jobs/run-now',
body: JSON.stringify(job_payload),
method: 'Post',
headers: { 'Content-Type':'application/jsoon','Authorization': 'Bearer token' }
}
var response=await rp(url,options);
if(response!=null){
return res.json(response)
}
});
module.exports= triggerJob;
I minimize the line of code for clarity.
I have middleware (API calls, not part of a route) which I want to use in a callback response.
// MIDDLEWARE EXAMPLE
var postInvoice = function(req, res){
function request(callback) {
var path='/xxx?';
var data = querystring.stringify( {
'action' : 'xxx',
'appkey' : 'xxx'',
'fromapi' : 'xxx',
'fromapiuser' : 'xxx',
'username' : 'xxx',
'shipmethod' : 'TEST',
'shipping' : '0',
'taxes' : '0'
});
var options = {
port: 443,
host: xxx,
path: path,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': data.length
}
};
var postRequest = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('Invoice Response: ' + chunk);
});
});
postRequest.write(data);
}
request(function(responseData) {
console.log(responseData);
});
}
I need to access the response in another route (which itself includes callback via API)
app.get('/result', function(req, res){
var resourcePath = req.param('resourcePath');
function request(callback) {
var path = resourcePath
var options = {
port: 443,
host: xxx,
path: path,
method: 'GET'
};
var postRequest = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
jsonRes = JSON.parse(chunk);
return callback(jsonRes);
});
});
postRequest.end();
}
request(function(responseData) {
console.log(responseData);
// this is where I invoke the middleware,
if(some response condition is met) {
postinvoice();
}
res.render('result', {
check: check,
response: checkout_msg
});
});
});
I'm able to view the 'Invoice Response' in console, but I cannot manipulate it in the /result route. I'd like to be able to invoke the middleware, create locals and make the locals available in /result route.
thank you,
try this
var postRequest = http.request(options, function (response) {
var body = '';
response.setEncoding('utf8');
response.on('data', function (chunk) {
body += chunk;
});
response.on('end', function () {
body = JSON.parse(body); //if response is json
return callback(body);
});
});
I'm trying to execute the following code inside AWS Lambda which only makes a POST http request to an ElasticSearch.
The problem I'm facing is that it seems the nodejs request has a read timeout and the response is almost always cut and an error is thrown. I've checked that the problem is not related with AWS Lambda timeout which is set to 10 seconds and the code throws an error in less than a second.
As you can see, I've tried to put a timeout to 5secs but I think that's a connection timeout and not a read timeout.
What am I doing wrong?
var http = require('http');
exports.handler = (event, context, callback) => {
var options = {
hostname: '172.31.40.10',
port: 9200,
path: '/articles/es/_search?_source=reference',
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (body) {
var parsed = JSON.parse(body);
var b = [];
for (var i = 0; i < parsed.hits.hits.length; i++) {
b.push(parsed.hits.hits[i]._source.reference);
}
var response = {
statusCode: '200',
body: JSON.stringify(b),
headers: {
'Content-Type': 'application/json',
}
};
callback(null, response);
});
});
req.on('error', function(e) {
callback(new Error('fallo'));
});
req.setTimeout(5000, function() {req.abort;})
req.on('socket', function (socket) {
socket.setTimeout(5000);
socket.on('timeout', function() {
req.abort();
});
});
req.write(MY_QUERY_HERE);
req.end();
};
I think you should let the stream of incoming data finish before performing any data manipulation.
Example :
var http = require('http');
//var _ = require('underscore');
function MyPostRequest(callback) {
var options = {
hostname:'172.31.40.10',
port:9200,
path:'/articles/es/_search?_source=reference',
method:'POST',
headers:{'Content-Type':'application/json'}
};
http.request(options, function(res) {
var tmpstore = ''; //temp. data storage
//:Store the continuous incoming data stream
res.on('data', function(d){tmpstore += d;});
//:Data reception is done, use it now...
res.on('end', function() {
var parsed = JSON.parse(tmpstore); var b = [];
for (var i = 0; i < parsed.hits.hits.length; i++) {
b.push(parsed.hits.hits[i]._source.reference);
}
/* //I suggest using underscore module :
_.each(parsed.hits.hits,function(element, index, list){
b.push(element._source.reference);
});
*/
var response = {
statusCode:'200',
body:JSON.stringify(b),
headers:{'Content-Type':'application/json'}
};
callback(null, response);
});
//:Response contained an error
res.on('error', function(e){/*error handling*/callback(e,null);});
});
}
Using the Instagram API i am calling the endpoint.
https://api.instagram.com/v1/tags/MYTAG/media/recent?access_token=MYACCESSTOKEN
I am getting different results returned when calling from my app vs calling from apigee.com. The difference being the access_token.
When i use https://apigee.com/console/instagram and make the instagram api call i get back 8 images. (after logging in with my instagram creditials), which is what i would expect.
if i log in with the same creditials using my nodejs app , i get a different auth token(which you would assume), but i get an empty data set back.
{ pagination: { next_min_id: 'STUFF', min_tag_id: 'STUFF' },
meta: { code: 200 },
data: []
}
I must be missing something simple.
Can anyone see what i may be doing wrong in my nodejs code
Thanks for any help
This is the nodejs code:::
var https = require('https');
var http = require('http');
var express = require('express');
var app = express();
var fs = require("fs");
var client_id = "CLIENT_ID";
var client_secret = "CLIENT_SECRET";
var redirect_uri = 'https://MYDOMAIN/handleauth';
var authorize_link = 'https://api.instagram.com/oauth/authorize/?client_id=' + client_id + '&redirect_uri=' + redirect_uri + '&response_type=code';
app.get('/authorize_user', function (req, res) {
res.redirect(authorize_link);
});
app.get('/handleauth', function (req, res) {
res.send("ok");
if (req.query['code']) {
var request = require('request');
var post_data = {
'client_id': client_id,
'client_secret': client_secret,
'grant_type': 'authorization_code',
'redirect_uri': redirect_uri,
'code': req.query['code']
};
var headers = {
'User-Agent': 'Super Agent/0.0.1',
'Content-Type': 'application/x-www-form-urlencoded'
}
var post_options = {
url: 'https://api.instagram.com/oauth/access_token',
method: 'POST',
headers: headers,
form: post_data
};
request(post_options, function (error, response, body) {
if (error || response.statusCode != 200) {
console.error(error);
} else {
var pbody = JSON.parse(body);
console.log('Response: ' + pbody);
console.log('pbody.access_token: ' + pbody.access_token);
var options = {
url: 'https://api.instagram.com/v1/tags/MYTAG/media/recent?access_token='+pbody.access_token,
method: 'GET'
};
request(options, function (error, response, body) {
if (error && response.statusCode != 200) {
console.error(error);
}else{
var jsonobjArr = JSON.parse(body);
console.log(jsonobjArr);
}
});
}
});
}
});
var options = {
key: fs.readFileSync("/ssl_certs/me.key"),
cert: fs.readFileSync("/ssl_certs/me_bundle.crt")
};
https.createServer(options, app).listen(4000, function () {
console.log("HTTPS Express Instagram server listening on port " + 4000);
});
You're in Sandbox Mode.
Data is restricted to the 10 users and the 20 most recent media from each of those users.
I realized this because I could only receive data from the tags I've posted.
Your question helped me figure out how to generate the access token. I couldn't get node-rest-client to work. Thanks!
My suggestion is to build the best application you can to mitigate the approval process.
I am new to NodeJS and inside of AWS Lambda I am trying to make a POST request that calls an external API with a JSON object, creates a document with the response and then reads the contents of the file.
Coming from a Ruby background, I'm thinking the problem stems from my unfamiliarity with asynchronous programming, but I've tried using callbacks and readfileSync just to debug with no luck.
Any help would be appreciated.
var querystring = require('querystring');
var https = require('https');
var fs = require('fs');
exports.handler = function(event, context) {
console.log('Received event:', JSON.stringify(event, null, 2));
var operation = event.operation;
delete event.operation;
var accessKey = event.accessKey;
delete event.accessKey;
var templateName = event.templateName;
delete event.templateName;
var outputName = event.outputName;
delete event.outputName;
var req = {
"accessKey": accessKey,
"templateName": templateName,
"outputName": outputName,
"data": event.data
};
function doPost(data, callback) {
// Build the post string from an object
var post_data = JSON.stringify(data);
// An object of options to indicate where to post to
var post_options = {
host: 'hostname.com',
port: '443',
path: '/path/to/api',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': post_data.length
}
};
// Set up the request
var file = fs.createWriteStream(outputName);
var post_req = https.request(post_options, function(res) {
res.setEncoding('utf8');
res.pipe(file);
res.on('response', function(response) {
console.log(response);
});
res.on('error', function(e) {
context.fail('error:' + e.message);
})
res.on('end', function() {
context.succeed('success, end request listener');
});
});
// post the data
post_req.write(post_data);
post_req.end();
callback();
}
function printFileContents() {
fs.readFileSync(outputName, 'utf8', function (err, data) {
console.log('file contents:' + data);
});
}
switch (operation) {
case 'create':
// Make sure there's data before we post it
if(req) {
doPost(req, printFileContents);
printFileContents();
}
break;
...
}
};
In general, I'd recommend starting like this:
var querystring = require('querystring');
var https = require('https');
var fs = require('fs');
exports.handler = function(event, context) {
console.info('Received event', event);
var data = {
"accessKey": accessKey,
"templateName": templateName,
"outputName": outputName,
"data": event.data
};
// Build the post string from an object
var post_data = JSON.stringify(data);
// An object of options to indicate where to post to
var post_options = {
host: 'hostname.com',
port: '443',
path: '/path/to/api',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': post_data.length
}
};
var post_request = https.request(post_options, function(res) {
var body = '';
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
context.done(body);
});
res.on('error', function(e) {
context.fail('error:' + e.message);
});
});
// post the data
post_request.write(post_data);
post_request.end();
};
You can see I simplified your code quite a bit. I'd recommend avoiding the file system since that would slow down your program. I'm also not sure about what is the real goal of your function so I just return the HTTP response.