Loopback soap connector not populating the model with the service methods - web-services

I am having trouble consuming soap web service using loopback-connector-soap. I followed the instructions from github and here.
I am able to consume the web service provided in the example but when I replace it with my wsdl it doesn't work. There are no errors after connecting but after creating the model, calling any method exposed by the web service fails with the error message
Object function ModelConstructor(data, options) { if (!(this instanceof ModelConstructor)) { return new ModelConstructor(data, options); } if (ModelClass.settings.unresolved) { throw new Error('Model ' + ModelClass.modelName + ' is not defined.'); } ModelBaseClass.apply(this, arguments); } has no method 'GetAgentBalance'
My code snippet is as shown below
var api = {};
var ds = loopback.createDataSource('soap', {
connector: 'loopback-connector-soap',
remotingEnabled: true,
wsdl: 'https://jambopay.com/agencyservices?WSDL',// The url to WSDL
wsdl_options: {
rejectUnauthorized: false,
strictSSL: false,
requestCert: true,
}
});
// Unfortunately, the methods from the connector are mixed in asynchronously
// This is a hack to wait for the methods to be injected
ds.once('connected', function () {
// Create the model
var service = ds.createModel('AgencyService', {});
api.getBalance = function (callback) {
//Displays the parsed WSDL
console.log(ds.connector);
var timestamp = moment().format('YYYY-MM-DD HH:mm:ss');
var pass = crypto.createHash('sha1').update(apiUsername + timestamp + apiKey).digest("hex");
//GetAgentBalance is a method in the web service.
service.GetAgentBalance({ username: apiUsername, timestamp: timestamp, pass: pass }, function (err, response) {
var result = (!err && response.Balance) ? response.Balance : null;
callback(err, result);
});
}
});
module.exports = api;
The console.log(ds.connector) displays the wsdl content plus a flag parsed:true meaning it was parsed successfully.
Kindly help me figure out why the model is not being populated with the methods from the web service which is preventing the consumption of the web service. Please note that this web service works fine in ASP.NET,Java as well as PHP and I guess several other languages and frameworks. I'm stuck at this point and your assistance is highly appreciated.

Related

Include Stripe in angular project

I am working on a website which uses angular for client and django for backend and I want to include stripe for payments. To configure stripe on the backend I have a microservice which runs on docker and accepts the following requests:
one for creating a stripe customer
another one for creating a payment
I configured stripe on the client using the provided form as follows:
export class PaymentComponent implements OnInit {
paymentHandler:any = null;
constructor(private checkoutService: CheckoutService) { }
ngOnInit() {
this.invokeStripe();
}
initializePayment(amount: number) {
const paymentHandler = (<any>window).StripeCheckout.configure({
key: 'pk_test_51MKU1wDo0NxQ0glB5HRAxUsR9MsY24POw3YHwIXnoMyFRyJ3cAV6FaErUeuEiWkGuWgAOoB3ILWXTgHA1CE9LTFr00WOT5U5vJ',
locale: 'auto',
token: function (stripeToken: any) {
console.log(stripeToken);
alert('Stripe token generated!');
paymentStripe(stripeToken);
}
});
const paymentStripe = (stripeTocken: any) => {
this.checkoutService.makePayment(stripeTocken).subscribe((data:any) => {
console.log(data)
})
}
paymentHandler.open({
name: 'Card Details',
description: 'Introduce the information from your card',
amount: amount * 100
});
}
invokeStripe() {
if(!window.document.getElementById('stripe-script')) {
const script = window.document.createElement("script");
script.id = "stripe-script";
script.type = "text/javascript";
script.src = "https://checkout.stripe.com/checkout.js";
script.onload = () => {
this.paymentHandler = (<any>window).StripeCheckout.configure({
key: 'pk_test_51MKU1wDo0NxQ0glB5HRAxUsR9MsY24POw3YHwIXnoMyFRyJ3cAV6FaErUeuEiWkGuWgAOoB3ILWXTgHA1CE9LTFr00WOT5U5vJ',
locale: 'auto',
token: function (stripeToken: any) {
console.log(stripeToken)
alert('Payment has been successfull!');
}
});
}
window.document.body.appendChild(script);
}
}
}
The makePayment method makes a request to the django server sending the stripe tocken.
From the server I need the above requests to the microservice.
My question is why do I need the configurations from the server as long as all I have to do to perform a payment is to make a request to the microservice? And where should I use the tocken.
I have also read about webhooks, but I don't really understand the concept and how to use this in my situation.
Also, do I need to test everything with angular cli? And why?
Thank you in advance!

How to use WCF service hosted on IIS in an AWS lambda function?

I have this scenario in which a service hosted on IIS must be used by my AWS lambda function. When I try adding it as a service reference, I'm getting "An error occurred while attempting to discover services in the solution: No services found in the solution.. " error. I don't find any issue with the service, and it is working fine.
Is there any link that I'm missing to make my service available to be used by AWS?
If you are using node.js for Lambda then please do like below,
var soap = require('soap');
var url = 'YouServiceURL.svc?wsdl';
var soapOptions = {
forceSoap12Headers: true
};
var soapHeader = {
'wsa:Action': 'http://tempuri.org/MyBinding/MyOperation',
'wsa:To': 'YouServiceURL.svc'
};
exports.handler = function(event, context, callback) {
var params = {
param1: event.param1,
param2: event.param2
};
soap.createClient(url, soapOptions, function(err, client) {
if (err) callback(err);
client.addSoapHeader(soapHeader, '', 'wsa', 'http://www.w3.org/2005/08/addressing');
client.MyOperation(params, function(err, data) {
if (err) callback(err);
callback(null, data);
});
});
}
Please find sample code here

Django equivalent for Node.js's Bluebird Promises [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I have a complex use case of promises in an Express (Node) server application, and now I'm being asked to migrate this server to Django. Basically my server (let's call it "A") is an OAuth2 client for another server (let's call it "B") and so A can request resources from B through B's API. Likewise, server A offers its own API which is intended to be consumed through ajax from javascript code in the browser. Let me show you the following picture to make things clearer:
My server A is working like a middleware between the browser and server B. So when the browser makes a call to one of A's API functions, A in turn makes several calls to B's API and based on those results A returns its own stuff to the browser.
So, in terms of code, I was doing something like this in Node.js (the code is just a simplification):
var express = require('express');
var router = express.Router();
var request = require('request-promise');
var Promise = require('bluebird');
...
//the following are helper functions
function getStuff1(req,res,params) {
request.get({
uri: "http://externalserver.com/api/whatever...",
headers: {
'Authorization':'Bearer' + req.user.accessToken //<-- notice that I'm using the user's access token (OAuth2)
}
}).then(function(input) {
//use params and input and compute stuff
return stuff;
}).catch(function(error) {
if(error.statusCode == 401) { // the accessToken has expired, we need to refresh it
return refreshOAuthToken(req,res)
.then(function(){
return getStuff1(req,res,params); // after refreshing the accessToken, we recursively call getStuff1 again
})
.catch(function(err) {
throw(err);
});
} else {
throw(error);
}
});
}
function getStuff2(req,res,params) { ... }
function getStuff3(req,res,params) { ... }
function getStuff4(req,res,params) { ... }
...
function refreshOAuthToken(req,res) {
return request.post({
uri: "http://otherserver/oauth/token",
form: {
'client_id': oauthClientId,
'client_secret': oauthClientSecret,
'grant_type': 'refresh_token',
'refreshToken': req.user.refreshToken // we're using the user's refresh token
})
.then( function(body) {
jsonResponse = JSON.parse(body);
req.user.accessToken = jsonResponse.access_token;
req.user.refreshToken = jsonResponse.refresh_token;
})
.catch( function(error) {
throw(error);
});
};
}
// the following is an actual API function
function apiFunction1(req,res) {
//first we compute params1 somehow
var params1 = req.whatever;
getStuff1(req,res, params1)
.then(function(stuff1) {
// do something with stuff1 and compute params2
return getStuff2(req,res,params2);
})
.then(function(stuff2) {
// do something with stuff2 and compute params3
return getStuff3(req,res,params3);
})
.then(function(stuff3) {
// now make 2 asynchronous calls at the same time
var promise4 = getStuff4(req,res,params4);
var promise5 = getStuff5(req,res,params5);
return Promise.all([promise4,promise5]); //we combine 2 promises into 1 with Promise.all
})
.then(function(results) {
var stuff4 = results[0];
var stuff5 = results[1];
//do something with stuff4 and stuff5, and compute the final answer
var answer = doSomethingWith(stuff4,stuff5);
res.send(answer); //finally we send the answer to the client
})
.catch(function(error) {
res.status(401).send({error: error}); // in case of any error, we send it back to the client
});
}
router.get('/api-function-1', apiFunction1);
module.exports = router;
This router is imported later like so:
var api = require('./routes/api');
app.use('/api', api);
So as you can see I'm doing a lot of requests to B which include refreshing OAuth2 tokens and making calls to B's API. Now the browser's javascript can call A's API function like so:
$.ajax('/api/api-function-1' + extra_params, {
dataType: 'json',
type: 'GET'
})
.done(doSomething)
.fail(handleError);
So what is the best way to achieve something like this in Django? I'm new to Django and python in general so I'm very open to any suggestion. Does Django have some equivalent for Node's bluebird library for promises? Any help regarding the OAuth2 part is also very welcomed.
Django conforms to, and is usually served, use the WSGI standard. WSGI and the default django deployment have a completely different execution model compared to node.
Node employs an event loop. Requests come in and are put on a single event loop. Bluebird (promises) allow you to put an event on the event loop and register an action to perform when that even completes. Django doesn't have a concept of an event loop, and doesn't have an equivalent to promises/futures (by default). In django a request comes in and is executed synchronously. There are a pool of workers, and when request comes in a single worker will handle executing the code until it is finished. There are no events registered onto an event loop.
Django code will look like:
# make an authenticated request using oauth user token
# if request fails make another request to refresh token
# remake request

Ember - Issue with HTTP POST request

I have written a (very) simple RESTFul Web service to retrieve data from MongoDB using Node, Express and Mongoose.
On the server side, I have this code:
router.route('/products').post(function(req,res){
var product = new Product(req.body);
product.save(function(err){
if(err)
res.send(err);
res.send({message:'Product Added'});
});
When I submit a request from my Ember client, the req.body contains something like the following:
{ attributes:
{ category: 1,
name: 'y',
price: 1,
active: false,
notes: null } }
The attribute names are exactly the same as my mongoose schema. I get no error but the document created in MongoDB is empty (just get the _id and __v fields).
What am I doing wrong. Should I convert the req.body further into ???
A couple things that will help debug:
1) From a quick glance (I haven't used mongoose before) it looks like call back function passed to save takes two arguments.
2) I don't know if your code got cut off, but the sample above was missing a matching });
3) I made the function short circuit itself on error, so you will not see 'Product added' unless that is truly the case.
Try these fixes.
router.route('/products').post(function(req,res){
var product = new Product(req.body);
product.save(function(err, product){
if(err){
return res.send(err);
}
return res.send({message:'Product Added'});
});
});
The issue was related to my lack of familiarity with Ember and Node+Express. The data received in the server is slightly different from what I had first indicated: (first line was missing)
{ product:
{ attributes:
{ category: ... } } }
On the server side I can access my data using req.body.product.attributes (instead of req.body):
router.route('/products').post(function(req,res){
var product = new Product(req.body.product.attributes);
product.save(function(err){
if(err)
res.send(err);
res.send({message:'Product Added'});
});

Backbone.js Problems with fetch() in IE

I'm building a web app with Django on back-end and Backbone.js on front-end
I have problems with IE when I'm trying to fetch data from the server. When I run my HTML page in IE, the collection fetch always invoke the error func.
My code:
$(function(){
var Chapter = Backbone.Model.extend({});
var Chapters = Backbone.Collection.extend({
model: Chapter,
url: 'http://ip.olya.ivanovss.info/chapters'
});
var chapters = new Chapters();
var Router = new (Backbone.Router.extend({
routes: {
"": "choose_activity",
"/": "choose_activity"
},
choose_activity: function () {
chapters.fetch({
success: function () {
AppView.render();
},
error: function() {
alert('error');
}
});
}
}))();
var AppView = new (Backbone.View.extend({
el: '.popup',
templates: {
choose_activity: Handlebars.compile($('#tpl-activities').html())
},
render: function () {
this.$el.html(this.templates["choose_activity"]({ chapters: chapters.toJSON()}));
}
}))();
Backbone.history.start();
});
Django's View:
def chapters(request):
chapters = list(Chapter.objects.order_by('id'))
response = HttpResponse(json.dumps(chapters, default=encode_myway), mimetype='text/plain')
if request.META.get('HTTP_ORIGIN', None) in ('http://localhost', 'http://html.olya.ivanovss.info', 'http://10.0.2.2'):
response['Access-Control-Allow-Origin'] = request.META['HTTP_ORIGIN']
return response
Thank you in advance
IE7 doesn't support CORS.
There are 2 ways around this. The EASY way is Proxy over your API. My Python is rusty (I'm a Node/PHP dev), but I'm sure that there are a million and one resources on how do do this. The good thing about this is you don't have to touch the API. But it means your local server has to CURL and return every single request from your API server.
And second (and much less server intensive way) is JSONP! The idea of JSONP is that it appends a <script> to the document with the URL you specify. jQuery appends a ?callback=jQueryNNN where NNN is a random number. So effectively when the <script> loads, it calls jQueryNNN('The Response Text') and jQuery knows to parse the response from there. The bad thing about this is you have to wrap all of your responses on the API side (which is super easy if you're just starting, not so easy if you already have an infrastructure built out).
The annoying things about JSONP is that by it's nature you can't do a POST/PUT/DELETE. BUT you can emulate it if you have access to the API:
Backbone.emulateHTTP = true;
model.save(); // POST to "/collection/id", with "_method=PUT" + header.
To integrate JSONP with Backbone is pretty simple (little secret Backbone.sync uses jQuery's $.ajax() and the options parameters forwards over to jQuery ;)).
For each one of your models/collections which access a cross origin you can add a su
var jsonpSync = function (method, model, options) {
options.timeout = 10000; // for 404 responses
options.dataType = "jsonp";
return Backbone.sync(method, model, options);
};
In each collection and model what does cross-origin:
var MyCollection = Backbone.Collection.extend({
sync : jsonpSync
});
Or just overwrite the whole Backbone sync
Backbone.__sync = Backbone.sync;
var jsonpSync = function (method, model, options) {
options.timeout = 10000; // for 404 responses
options.dataType = "jsonp";
return Backbone.__sync(method, model, options);
};
Backbone.sync = jsonpSync;
On the server side you can do: this to return a JSONP response (copy pasted here):
def randomTest(request):
callback = request.GET.get('callback', '')
req = {}
req ['title'] = 'This is a constant result.'
response = json.dumps(req)
response = callback + '(' + response + ');'
return HttpResponse(response, mimetype="application/json")