Im working on an existing Windows Service project in VS 2013.
I've added a web API Controller class I cant remember now if its a (v2.1) or (v1) controller class....Anyway I've called it SyncPersonnelViaAwsApiController
Im trying to call it from a AWS lambda...so If I call the GET
public string Get(int id)
{
return "value";
}
with const req = https.request('https://actualUrlAddress/api/SyncPersonnelViaAwsApi/Get/4', (res) => {
I get returned body: undefined"value"
which is correct.
However if I try and call
const req = https.request('https://actualUrlAddress/api/SyncPersonnelViaAwsApi/SapCall', (res) => {
I get returned body: undefined{"Message":"The requested resource does not support http method 'GET'."}
//// POST api/<controller>
public string SapCall([FromBody]string xmlFile)
{
string responseMsg = "Failed Import User";
if (!IsNewestVersionOfXMLFile(xmlFile))
{
responseMsg = "Not latest version of file, update not performed";
}
else
{
Business.PersonnelReplicate personnelReplicate = BusinessLogic.SynchronisePersonnel.BuildFromDataContractXml<Business.PersonnelReplicate>(xmlFile);
bool result = Service.Personnel.SynchroniseCache(personnelReplicate);
if (result)
{
responseMsg = "Success Import Sap Cache User";
}
}
return "{\"response\" : \" " + responseMsg + " \" , \"isNewActiveDirectoryUser\" : \" false \"}";
}
Does anyone have any idea why it works for GET and not POST?
As we can hit the get im confident its not the lambda but I have included it just incase
const AWS = require('aws-sdk');
const https = require('https');
var s3 = new AWS.S3();
var un;
var pw;
var seralizedXmlFile;
let index = function index(event, context, callback) {
// For the purpose of testing I have populated the bucket and key params with objects that already exist in the S3 bucket
var params = {
Bucket: "testbucketthur7thdec",
Key: "personnelData_50312474_636403151354943757.xml"
};
// Get Object from S3 bucket and add to 'seralizedXmlFile'
s3.getObject(params, function (data, err) {
console.log("get object from S3 bucket");
if (err) {
// an error occurred
}
else
{
console.log("data " + data);
// populate seralizedXmlFile with data from S3 bucket
let seralizedXmlFile = err.Body.toString('utf-8'); // Use the encoding necessary
console.log("objectData " + seralizedXmlFile);
}
});
// set params
var ssm = new AWS.SSM({ region: 'Usa2' });
console.log('Instatiated SSM');
var paramsx = {
'Names': ['/Sap/ServiceUsername', '/Sap/ServicePassword'],
'WithDecryption': true
};
// password and username
ssm.getParameters(paramsx, function (err, data) {
console.log('Getting parameter');
if (err) console.log(err, err.stack); // an error occurred
else {
console.log('data: ' + JSON.stringify(data)); // successful response
console.log('password: ' + data.Parameters[0].Value);
console.log('username: ' + data.Parameters[1].Value);
pw = data.Parameters[0].Value;
un = data.Parameters[1].Value;
}
// request to external api application & remove dependency on ssl
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
//POST DOES NOT WORK
const req = https.request('https://actualUrlAddress/api/SyncPersonnelViaAwsApi/SapEaiCall', (res) => {
//GET WORKS
// const req = https.request('https://actualUrlAddress/api/SyncPersonnelViaAwsApi/Get/4', (res) => {
res.headers + 'Authorization: Basic ' + un + ':' + pw;
let body = seralizedXmlFile;
console.log('seralizedXmlFile: ' + seralizedXmlFile);
console.log('Status:', res.statusCode);
console.log('Headers:', JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', (chunk) => body += chunk);
res.on('end', () => {
console.log('Successfully processed HTTPS response');
callback(null, body);
console.log('returned body:', body);
});
});
req.end();
});
};
exports.handler = index;
UPDATE Thanks to @Thangadurai post with AWS Lambda - NodeJS POST request and asynch write/read file
I was able to include a post_options...please see updated lambda
// An object of options to indicate where to post to
var post_options = {
host: 'https://actualUrlAddress',
port: '80',
path: '/api/SyncPersonnelViaAwsApi/SapEaiCall',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': post_data.length
}
};
const req = https.request(post_options, (res) => {
res.headers + 'Authorization: Basic ' + un + ':' + pw;
let body = seralizedXmlFile;
console.log('seralizedXmlFile: ' + seralizedXmlFile);
console.log('Status:', res.statusCode);
console.log('Headers:', JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', (chunk) => body += chunk);
res.on('end', () => {
console.log('Successfully processed HTTPS response');
callback(null, body);
console.log('returned body:', body);
});
});
req.end();
It is now flagging as error:
Error: getaddrinfo ENOTFOUND http://actualUrlAddress http://actualUrlAddress.private:80
I had this getaggrinfo ENOTFOUND error before, it means it cant find the address....but arnt the hostname and api path correct?
I am trying to reach
const req = https.request('https://actualUrlAddress/api/SyncPersonnelViaAwsApi/SapCall
and yes the port is 80
any help would be appreciated Ta M
Skipping right to the update part (everything else is not relevant as I understand). Options should look like this:
Since as documentation states, host and protocol are in two separate properties, and SSL port is very unlikely to be 80, usually it is 443.
Given that Web API is being used the assumption is that the default routeing has also been configured.
I would suggest enabling attribute routing
Reference Attribute Routing in ASP.NET Web API 2
and updating the controller with the appropriate attributes and syntax
Take note of the expected paths in the comments above the actions.
The
[Http{Verb}]
attributes tell the routing framework what requests can be mapped to the action.now from the client the paths to call would be
As already mentioned in the comments, the port 80 is not used for HTTP calls. Even the linked example in the updated question uses port
443
for HTTPS calls. The header in options show JSON yet thebody
infers that XML is being sent.In order for the client to successfully communicate with the Web API the client will need to make sure it is making a valid request.