loopbackio / loopback-connector-soap Goto Github PK
View Code? Open in Web Editor NEWLoopBack's SOAP based Web Services Connector
License: Other
LoopBack's SOAP based Web Services Connector
License: Other
Hello,
I'm looking at the pricing list and I'm not sure I understand exactly where this package fits in.
Is this free to use?
I'm mainly using the SOAP connector:
var loopback = require('loopback');
var ds = loopback.createDataSource('soap',
{
connector: require('./index'),
wsdl: 'http://www.webservicex.net/currencyconvertor.asmx?wsdl' // The url to WSDL
});
Thank you
Getting the following error trying to run this module behind Passenger Nginx after upgrading to the latest version:
/home/app/node_modules/loopback-connector-soap/node_modules/strongloop-license/lib/approot.js:22
throw new Error('Could not find package.json up from: ' + dir);
^
Error: Could not find package.json up from: /
at find (/home/app/node_modules/loopback-connector-soap/node_modules/strongloop-license/lib/approot.js:22:11)
at find (/home/app/node_modules/loopback-connector-soap/node_modules/strongloop-license/lib/approot.js:27:10)
at find (/home/app/node_modules/loopback-connector-soap/node_modules/strongloop-license/lib/approot.js:27:10)
at find (/home/app/node_modules/loopback-connector-soap/node_modules/strongloop-license/lib/approot.js:27:10)
at find (/home/app/node_modules/loopback-connector-soap/node_modules/strongloop-license/lib/approot.js:27:10)
at readRootPackage (/home/app/node_modules/loopback-connector-soap/node_modules/strongloop-license/lib/approot.js:31:13)
at Object. (/home/app/node_modules/loopback-connector-soap/node_modules/strongloop-license/index.js:14:18)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object. (/home/app/node_modules/loopback-connector-soap/index.js:1:63)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
My WCF xml is:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/ICustomerActionService/Register</Action>
</s:Header>
<s:Body>
<Register xmlns="http://tempuri.org/">
<registerInfo xmlns:d4p1="http://schemas.datacontract.org/2004/07/MYun.BPC.Contract.CustomerMgmt.Data" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<d4p1:BirthDay>2016-01-15T13:30:00</d4p1:BirthDay>
<d4p1:CellPhoneNo>123</d4p1:CellPhoneNo>
<d4p1:CustomerFrom i:nil="true" />
<d4p1:CustomerLevel>0</d4p1:CustomerLevel>
<d4p1:CustomerSource>0</d4p1:CustomerSource>
<d4p1:Gender>Male</d4p1:Gender>
<d4p1:HeadPicture i:nil="true" />
<d4p1:LoginPassword>123</d4p1:LoginPassword>
<d4p1:Name>123</d4p1:Name>
<d4p1:StoreName i:nil="true" />
<d4p1:WangwangNo i:nil="true" />
</registerInfo>
<invitationCode>123</invitationCode>
</Register>
</s:Body>
</s:Envelope>
CI failed due to missing .travis.yml
.
We should evaluate if there is a need to run Travis (if not, disable it), or to add the .travis.yml
file.
This is perfect to RESTify a soap service but can I use this to implement a REST front end using an abstract wsdl?
Change 4 tests and switch the code to use stockquote web service instead of weather service.
When a soap method has no parameters, the soap nodejs client fails and return an error:
invalid message definition for rpc style binding
I think i hit that problem:
I did a project to reproduce the problem:
GetMasterList is a method that takes no arguments and return only one.
https://github.com/mercuriete/loopback-example-connector/tree/soap
steps to reproduce:
Im using latest libraries as you can see in package.json
I need support in order to workaround this problem if is possible.
Thanks.
PS: Your work is awesome.
I am getting an error generating from the following WSDL: https://access.uat.oup.com/eacWebService/services/access-service-v2.0.wsdl
Creating model definition for soap_access-service-v2.0Soap11...
Creating model definition for ValidatePasswordCredentialsRequest...
Creating model definition for PasswordCredential...
Creating model definition for ValidatePasswordCredentialsResponse...
Creating model definition for GetFullUserEntitlementsRequest...
Creating model definition for wsUserId...
Creating model definition for Identifier...
Creating model definition for InternalIdentifier...
Creating model definition for ExternalIdentifier...
Creating model definition for GetFullUserEntitlementsResponse...
Creating model definition for ErrorStatus...
Updating model definition for User...
Creating model definition for Identifiers...
Creating model definition for FullProductEntitlementGroup...
Creating model definition for FullProductEntitlement...
Creating model definition for FullProductDetails...
Creating model definition for LicenceDetails...
Creating model definition for ExtendedLicenceDetails...
Creating model definition for RollingLicenceDetail...
Creating model definition for ConcurrencyLicenceDetails...
Creating model definition for UsageLicenceDetails...
Creating model definition for LicenceInfo...
Creating model definition for AuthenticateRequest...
Creating model definition for Credential...
Creating model definition for IPCredential...
Creating model definition for AuthenticateResponse...
Creating model definition for CreateUserAccountRequest...
Creating model definition for CreateUser...
Creating model definition for CreateUserAccountResponse...
Creating model definition for userStatusType...
Creating model definition for UpdateUserAccountRequest...
Creating model definition for UpdateUser...
Creating model definition for UpdateUserAccountResponse...
Validation error: invalid ModelDefinition
- name: is invalid
events.js:163
throw er; // Unhandled 'error' event
^
ValidationError: The `ModelDefinition` instance is not valid. Details: `name` is invalid (value: "soap_access-service-v2.0Soap11").
Any clues? Thanks
It seems the only way to define a SOAP datasource and model at the moment is to do it in a boot script, which is inconsistent with the way that the rest of our app is defined using Loopback's json definition files. This means that the definition of our datasources and models is now spread around the codebase rather than being consolidated in a single place (/datasources.json, /model-config.json and /common/models), which isn't ideal.
Can the soap connector be made to support the standard way of defining models and datasources too?
Hello guys,
I just cloned the repo and unit tests failed due to invalid WSDL URL.
Got 404 on this: http://www.webservicex.net/stockquote.asmx?wsdl
As a result several tests return an error.
git clone https://github.com/strongloop/loopback-connector-soap.git
cd loopback-connector-soap
npm i
npm test
Hi there,
Not sure if this is a limitation/bug, or my lack of understanding.
I am trying to configure a custom header in loopback-connector-soap.
Value should look as follows:
<com:AccessToken xmlns:com="http://thalesgroup.com/RTTI/2010-11-01/ldb/commontypes">
<com:TokenValue>nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn</com:TokenValue>
</com:AccessToken>
I can't figure out for the life of me how to format this in my loopback datasources configuration. I've got to the below but am completely stuck.
"soapHeaders": [
{
"",
"element": {"TokenValue": "nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn"},
"prefix": "com",
"namespace": "http://thalesgroup.com/RTTI/2010-11-01/ldb/commontypes"
}
Is it possible to create the header I am looking to create?
Hello,
Is it possible to add a xmlns attribute to a specific namespace with loopback soap connector ?
Issue : when converting a json to xml, loopback doesn't add the xmlns attribute to a tag which is an array.
Need this for CI of strong-soap. Back port #67 to 3.x from 4.x
Hello, I'm having the following problem:
...\node_modules\strong-soap\src\parser\wsdl\operation.js:74
headers.addElement(part.element.describe(definitions));
^
ReferenceError: definitions is not defined
at ...\node_modules\strong-soap\src\parser\wsdl\operation.js:74:50
What I'm trying:
var loopback = require('loopback');
var path = require('path');
var lcs = require('loopback-connector-soap');
var ds = loopback.createDataSource('soap', {
connector : lcs,
remotingEnabled : false,
wsdl : '.../saphws.asmx?WSDL' //It's valid, just ommited the address
});
ds.once('connected', function () {
var myservice = ds.createModel('SAPHWS', {});
myservice.LoadStuff({
dbUser : '...',
codServidor : 1
}, function (err, response) {
console.log("Retorno WS : %j", response);
var result = (!err && response.LoadStuffResult.Success) ?
response.LoadStuffResult : [];
cb(err, result);
});
});
The error occurs when I call myservice.LoadStuff(...)
.
A valid service body is:
<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/" xmlns:www="...">
<x:Header>
<www:WsAuth>
<www:usr>abc</www:usr>
<www:pas>pass</www:pas>
</www:WsAuth>
</x:Header>
<x:Body>
<www:LoadStuff>
<www:dbuser>...</www:dbuser>
<www:codServidor>1</www:codServidor>
</www:LoadStuff>
</x:Body>
</x:Envelope>
Do you have any ideas?
Thanks in advance!
is there a way to consume WCF using this SOAP connector?
i'm facing the below problem:
node_modules/soap/lib/client.js:233
result = obj.Body[output.$name];
TypeError: Cannot read property 'ConsultarPorEmailResponse' of undefined
Some clues?
Very thx!
Add eslint to project
Current test cases run server on port 3000, when needed, which crashes other test cases that try to use the same port on same instance causing CI failures.
Goal is to make test server apps port independent.
Parent issue: https://github.com/strongloop-internal/scrum-loopback/issues/932
README is there for a good reason. Mammoths like IBM and MS fell behind & now piggy backing on open source to pollute the waters.
Has anyone successfully ran examples?
Is it worth digging into it or just use node to write custom connector?
I have a existed web service. and I followed the tutorial Connecting to SOAP web services. And When I invoke a simple operation. It gave me the unexpected element exception. I looked up the documentation and could not find a option to disable generating these internal properties.
I use Wireshark to capture the related packets
POST /apiws/services/API HTTP/1.1
User-Agent: loopback-connector-soap/3.0.1
Accept: text/html,application/xhtml+xml,application/xml,text/xml;q=0.9,*/*;q=0.8
Accept-Encoding: none
Accept-Charset: utf-8
Connection: close
Host: mail.ynu.edu.cn:9900
Content-Length: 17821
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header/>
<soap:Body>
<ns1:authenticate xmlns:ns1="http://coremail.cn/apiws">
<__cachedRelations/>
<__data>
<user_at_domain>my_mail_address</user_at_domain>
<password>my_mail_password</password>
</__data>
<__dataSource/>
<__strict>false</__strict>
<__persisted>false</__persisted>
<user_at_domain>my_mail_address</user_at_domain>
<password>my_mail_password</password>
<_initProperties>function (data, options) {
var self = this;
var ctor = this.constructor;
if (typeof data !== 'undefined' && data.constructor &&
typeof (data.constructor) !== 'function') {
throw new Error(g.f('Property name "{{constructor}}" is not allowed in %s data', ctor.modelName));
}
if (data instanceof ctor) {
// Convert the data to be plain object to avoid pollutions
data = data.toObject(false);
}
var properties = _extend({}, ctor.definition.properties);
data = data || {};
if (typeof ctor.applyProperties === 'function') {
ctor.applyProperties(data);
}
options = options || {};
var applySetters = options.applySetters;
var applyDefaultValues = options.applyDefaultValues;
var strict = options.strict;
if (strict === undefined) {
strict = ctor.definition.settings.strict;
} else if (strict === 'throw') {
g.warn('Warning: Model %s, {{strict mode: `throw`}} has been removed, ' +
'please use {{`strict: true`}} instead, which returns' +
'{{`Validation Error`}} for unknown properties,', ctor.modelName);
}
var persistUndefinedAsNull = ctor.definition.settings.persistUndefinedAsNull;
if (ctor.hideInternalProperties) {
// Object.defineProperty() is expensive. We only try to make the internal
// properties hidden (non-enumerable) if the model class has the
// `hideInternalProperties` set to true
Object.defineProperties(this, {
__cachedRelations: {
writable: true,
enumerable: false,
configurable: true,
value: {},
},
__data: {
writable: true,
enumerable: false,
configurable: true,
value: {},
},
// Instance level data source
__dataSource: {
writable: true,
enumerable: false,
configurable: true,
value: options.dataSource,
},
// Instance level strict mode
__strict: {
writable: true,
enumerable: false,
configurable: true,
value: strict,
},
__persisted: {
writable: true,
enumerable: false,
configurable: true,
value: false,
},
});
if (strict) {
Object.defineProperty(this, '__unknownProperties', {
writable: true,
enumerable: false,
configrable: true,
value: [],
});
}
} else {
this.__cachedRelations = {};
this.__data = {};
this.__dataSource = options.dataSource;
this.__strict = strict;
this.__persisted = false;
if (strict) {
this.__unknownProperties = [];
}
}
if (options.persisted !== undefined) {
this.__persisted = options.persisted === true;
}
if (data.__cachedRelations) {
this.__cachedRelations = data.__cachedRelations;
}
var keys = Object.keys(data);
if (Array.isArray(options.fields)) {
keys = keys.filter(function(k) {
return (options.fields.indexOf(k) != -1);
});
}
var size = keys.length;
var p, propVal;
for (var k = 0; k < size; k++) {
p = keys[k];
propVal = data[p];
if (typeof propVal === 'function') {
continue;
}
if (propVal === undefined && persistUndefinedAsNull) {
propVal = null;
}
if (properties[p]) {
// Managed property
if (applySetters || properties[p].id) {
self[p] = propVal;
} else {
self.__data[p] = propVal;
}
} else if (ctor.relations[p]) {
var relationType = ctor.relations[p].type;
var modelTo;
if (!properties[p]) {
modelTo = ctor.relations[p].modelTo || ModelBaseClass;
var multiple = ctor.relations[p].multiple;
var typeName = multiple ? 'Array' : modelTo.modelName;
var propType = multiple ? [modelTo] : modelTo;
properties[p] = {name: typeName, type: propType};
/* Issue #1252
this.setStrict(false);
*/
}
// Relation
if (relationType === 'belongsTo' && propVal != null) {
// If the related model is populated
self.__data[ctor.relations[p].keyFrom] = propVal[ctor.relations[p].keyTo];
if (ctor.relations[p].options.embedsProperties) {
var fields = fieldsToArray(ctor.relations[p].properties,
modelTo.definition.properties, modelTo.settings.strict);
if (!~fields.indexOf(ctor.relations[p].keyTo)) {
fields.push(ctor.relations[p].keyTo);
}
self.__data[p] = new modelTo(propVal, {
fields: fields,
applySetters: false,
persisted: options.persisted,
});
}
}
self.__cachedRelations[p] = propVal;
} else {
// Un-managed property
if (strict === false || self.__cachedRelations[p]) {
self[p] = self.__data[p] =
(propVal !== undefined) ? propVal : self.__cachedRelations[p];
// Throw error for properties with unsupported names
if (/\./.test(p)) {
throw new Error(g.f(
'Property names containing dot(s) are not supported. ' +
'Model: %s, dynamic property: %s',
this.constructor.modelName, p
));
}
} else {
if (strict !== 'filter') {
this.__unknownProperties.push(p);
}
}
}
}
keys = Object.keys(properties);
if (Array.isArray(options.fields)) {
keys = keys.filter(function(k) {
return (options.fields.indexOf(k) != -1);
});
}
size = keys.length;
for (k = 0; k < size; k++) {
p = keys[k];
propVal = self.__data[p];
var type = properties[p].type;
// Set default values
if (applyDefaultValues && propVal === undefined) {
var def = properties[p]['default'];
if (def !== undefined) {
if (typeof def === 'function') {
if (def === Date) {
// FIXME: We should coerce the value in general
// This is a work around to {default: Date}
// Date() will return a string instead of Date
def = new Date();
} else {
def = def();
}
} else if (type.name === 'Date' && def === '$now') {
def = new Date();
}
// FIXME: We should coerce the value
// will implement it after we refactor the PropertyDefinition
self.__data[p] = propVal = def;
}
}
// Set default value using a named function
if (applyDefaultValues && propVal === undefined) {
var defn = properties[p].defaultFn;
switch (defn) {
case undefined:
break;
case 'guid':
case 'uuid':
// Generate a v1 (time-based) id
propVal = uuid.v1();
break;
case 'uuidv4':
// Generate a RFC4122 v4 UUID
propVal = uuid.v4();
break;
case 'now':
propVal = new Date();
break;
case 'shortid':
propVal = shortid.generate();
break;
default:
// TODO Support user-provided functions via a registry of functions
g.warn('Unknown default value provider %s', defn);
}
// FIXME: We should coerce the value
// will implement it after we refactor the PropertyDefinition
if (propVal !== undefined)
self.__data[p] = propVal;
}
if (propVal === undefined && persistUndefinedAsNull) {
self.__data[p] = propVal = null;
}
// Handle complex types (JSON/Object)
if (!BASE_TYPES[type.name]) {
if (typeof self.__data[p] !== 'object' && self.__data[p]) {
try {
self.__data[p] = JSON.parse(self.__data[p] + '');
} catch (e) {
self.__data[p] = String(self.__data[p]);
}
}
if (type.prototype instanceof ModelBaseClass) {
if (!(self.__data[p] instanceof type) &&
typeof self.__data[p] === 'object' &&
self.__data[p] !== null) {
self.__data[p] = new type(self.__data[p]);
}
} else if (type.name === 'Array' || Array.isArray(type)) {
if (!(self.__data[p] instanceof List) &&
self.__data[p] !== undefined &&
self.__data[p] !== null) {
self.__data[p] = List(self.__data[p], type, self);
}
}
}
}
this.trigger('initialize');
}</_initProperties>
<getPropertyType>function (propName) {
return this.constructor.getPropertyType(propName);
}</getPropertyType>
<toObject>function (onlySchema, removeHidden, removeProtected) {
if (onlySchema === undefined) {
onlySchema = true;
}
var data = {};
var self = this;
var Model = this.constructor;
// if it is already an Object
if (Model === Object) {
return self;
}
var strict = this.__strict;
var schemaLess = (strict === false) || !onlySchema;
var persistUndefinedAsNull = Model.definition.settings.persistUndefinedAsNull;
var props = Model.definition.properties;
var keys = Object.keys(props);
var propertyName, val;
for (var i = 0; i < keys.length; i++) {
propertyName = keys[i];
val = self[propertyName];
// Exclude functions
if (typeof val === 'function') {
continue;
}
// Exclude hidden properties
if (removeHidden && Model.isHiddenProperty(propertyName)) {
continue;
}
if (removeProtected && Model.isProtectedProperty(propertyName)) {
continue;
}
if (val instanceof List) {
data[propertyName] = val.toObject(!schemaLess, removeHidden, true);
} else {
if (val !== undefined && val !== null && val.toObject) {
data[propertyName] = val.toObject(!schemaLess, removeHidden, true);
} else {
if (val === undefined && persistUndefinedAsNull) {
val = null;
}
data[propertyName] = val;
}
}
}
if (schemaLess) {
// Find its own properties which can be set via myModel.myProperty = 'myValue'.
// If the property is not declared in the model definition, no setter will be
// triggered to add it to __data
keys = Object.keys(self);
var size = keys.length;
for (i = 0; i < size; i++) {
propertyName = keys[i];
if (props[propertyName]) {
continue;
}
if (propertyName.indexOf('__') === 0) {
continue;
}
if (removeHidden && Model.isHiddenProperty(propertyName)) {
continue;
}
if (removeProtected && Model.isProtectedProperty(propertyName)) {
continue;
}
if (data[propertyName] !== undefined) {
continue;
}
val = self[propertyName];
if (val !== undefined) {
if (typeof val === 'function') {
continue;
}
if (val !== null && val.toObject) {
data[propertyName] = val.toObject(!schemaLess, removeHidden, true);
} else {
data[propertyName] = val;
}
} else if (persistUndefinedAsNull) {
data[propertyName] = null;
}
}
// Now continue to check __data
keys = Object.keys(self.__data);
size = keys.length;
for (i = 0; i < size; i++) {
propertyName = keys[i];
if (propertyName.indexOf('__') === 0) {
continue;
}
if (data[propertyName] === undefined) {
if (removeHidden && Model.isHiddenProperty(propertyName)) {
continue;
}
if (removeProtected && Model.isProtectedProperty(propertyName)) {
continue;
}
var ownVal = self[propertyName];
// The ownVal can be a relation function
val = (ownVal !== undefined && (typeof ownVal !== 'function')) ? ownVal : self.__data[propertyName];
if (typeof val === 'function') {
continue;
}
if (val !== undefined && val !== null && val.toObject) {
data[propertyName] = val.toObject(!schemaLess, removeHidden, true);
} else if (val === undefined && persistUndefinedAsNull) {
data[propertyName] = null;
} else {
data[propertyName] = val;
}
}
}
}
return data;
}</toObject>
<toJSON>function () {
return this.toObject(false, true, false);
}</toJSON>
<fromObject>function (obj) {
for (var key in obj) {
this[key] = obj[key];
}
}</fromObject>
<reset>function () {
var obj = this;
for (var k in obj) {
if (k !== 'id' && !obj.constructor.dataSource.definitions[obj.constructor.modelName].properties[k]) {
delete obj[k];
}
}
}</reset>
<inspect>function (depth) {
if (INSPECT_SUPPORTS_OBJECT_RETVAL)
return this.__data;
// Workaround for older versions
// See also https://github.com/joyent/node/commit/66280de133
return util.inspect(this.__data, {
showHidden: false,
depth: depth,
colors: false,
});
}</inspect>
<getDataSource>function () {
return this.__dataSource || this.constructor.dataSource;
}</getDataSource>
<setStrict>function (strict) {
this.__strict = strict;
}</setStrict>
<trigger>function trigger(actionName, work, data, callback) {
var capitalizedName = capitalize(actionName);
var beforeHook = this.constructor['before' + capitalizedName] ||
this.constructor['pre' + capitalizedName];
var afterHook = this.constructor['after' + capitalizedName] ||
this.constructor['post' + capitalizedName];
if (actionName === 'validate') {
beforeHook = beforeHook || this.constructor.beforeValidation;
afterHook = afterHook || this.constructor.afterValidation;
}
var inst = this;
if (actionName !== 'initialize') {
if (beforeHook)
deprecateHook(inst.constructor, ['before', 'pre'], capitalizedName);
if (afterHook)
deprecateHook(inst.constructor, ['after', 'post'], capitalizedName);
}
// we only call "before" hook when we have actual action (work) to perform
if (work) {
if (beforeHook) {
// before hook should be called on instance with two parameters: next and data
beforeHook.call(inst, function() {
// Check arguments to next(err, result)
if (arguments.length) {
return callback && callback.apply(null, arguments);
}
// No err & result is present, proceed with the real work
// actual action also have one param: callback
work.call(inst, next);
}, data);
} else {
work.call(inst, next);
}
} else {
next();
}
function next(done) {
if (afterHook) {
afterHook.call(inst, done);
} else if (done) {
done.call(this);
}
}
}</trigger>
<isValid>function (callback, data, options) {
options = options || {};
var valid = true, inst = this, wait = 0, async = false;
var validations = this.constructor.validations;
var reportDiscardedProperties = this.__strict &&
this.__unknownProperties && this.__unknownProperties.length;
// exit with success when no errors
if (typeof validations !== 'object' && !reportDiscardedProperties) {
cleanErrors(this);
if (callback) {
this.trigger('validate', function(validationsDone) {
validationsDone.call(inst, function() {
callback(valid);
});
}, data, callback);
}
return valid;
}
Object.defineProperty(this, 'errors', {
enumerable: false,
configurable: true,
value: new Errors,
});
this.trigger('validate', function(validationsDone) {
var inst = this,
asyncFail = false;
var attrs = Object.keys(validations || {});
attrs.forEach(function(attr) {
var attrValidations = validations[attr] || [];
attrValidations.forEach(function(v) {
if (v.options && v.options.async) {
async = true;
wait += 1;
process.nextTick(function() {
validationFailed(inst, attr, v, options, done);
});
} else {
if (validationFailed(inst, attr, v)) {
valid = false;
}
}
});
});
if (reportDiscardedProperties) {
for (var ix in inst.__unknownProperties) {
var key = inst.__unknownProperties[ix];
var code = 'unknown-property';
var msg = defaultMessages[code];
inst.errors.add(key, msg, code);
valid = false;
}
}
if (!async) {
validationsDone.call(inst, function() {
if (valid) cleanErrors(inst);
if (callback) {
callback(valid);
}
});
}
function done(fail) {
asyncFail = asyncFail || fail;
if (--wait === 0) {
validationsDone.call(inst, function() {
if (valid && !asyncFail) cleanErrors(inst);
if (callback) {
callback(valid && !asyncFail);
}
});
}
}
}, data, callback);
if (async) {
// in case of async validation we should return undefined here,
// because not all validations are finished yet
return;
} else {
return valid;
}
}</isValid>
</ns1:authenticate>
</soap:Body>
</soap:Envelope>HTTP/1.1 500 Internal Server Error
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=UTF-8
Content-Length: 323
Date: Thu, 08 Jun 2017 02:40:26 GMT
Connection: close
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Client</faultcode><faultstring>Unmarshalling Error: 意外的元素 (uri:"", local:"__cachedRelations")。所需元素为<{}password>,<{}user_at_domain> </faultstring></soap:Fault></soap
Can I suggest you to update node-soap to v0.6.1 ?
I need the enhancement $xml that allow to give a plain XML.
Thanks
Hi,
The new release from node-soap is not working with loopback-connector-soap
Can you temporarily fixed the version to 0.9.3 ?
Thanks,
> require('loopback-connector-soap')
AssertionError: *** setRootDir: Intl dir not found under: /Users/rfeng/Demos/d1/node_modules/loopback-connector-soap
at Object.setRootDir (/Users/rfeng/Demos/d1/node_modules/strong-globalize/lib/helper.js:153:3)
at Function.SetRootDir (/Users/rfeng/Demos/d1/node_modules/strong-globalize/index.js:48:13)
at Object.<anonymous> (/Users/rfeng/Demos/d1/node_modules/loopback-connector-soap/index.js:7:4)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
I am getting a stack size error while using the CLI lb soap
command, while trying to access my OMS web services. My lb common models have already been created via the mssql connector, if that matters at all. The OMS can be viewed at https://smapromail.cgraphics.com/pmomsws/oms.asmx?WSDL.
throw er; // Unhandled 'error' event
^
RangeError: Maximum call stack size exceeded
at Array.indexOf (<anonymous>)
at checkAndConvertToNumber (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:438:25)
at buildElementProperties (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:321:13)
at buildElementProperties (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:327:7)
at buildElementProperties (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:327:7)
at buildElementProperties (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:327:7)
at buildElementProperties (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:327:7)
at buildElementProperties (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:327:7)
at buildElementProperties (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:327:7)
at buildElementProperties (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:327:7)
at buildElementProperties (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:327:7)
at buildElementProperties (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:327:7)
at buildElementProperties (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:327:7)
at buildElementProperties (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:327:7)
at buildElementProperties (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:327:7)
at buildElementProperties (/usr/local/lib/node_modules/loopback-cli/node_modules/loopback-soap/lib/codegen/generator-soap.js:327:7)
Emitted 'error' event at:
at Immediate.<anonymous> (/usr/local/lib/node_modules/loopback-cli/node_modules/yeoman-generator/lib/base.js:446:16)
at runCallback (timers.js:696:18)
at tryOnImmediate (timers.js:667:5)
at processImmediate (timers.js:649:5)
at process.topLevelDomainCallback (domain.js:121:23)
darwin x64 10.3.0
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
Does this connector support attachments? I have a soap endpoint that I am hitting, but the node-soap library that I'm using doesn't support attachments. Is there any way to do that here?
Cheers.
Work
Modify the test case to handle if the external WSDL location is unavailable http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL
Add new example stockquote service to strong-soap
Update strong-soap blog changing the code snippets and text to use stoquote web service instead of weather web service and send it to Dave Whitely.
I'm having incredible issues with node-soap
atm, since input param order is not guaranteed therefore tripping sequence encodings in wsdl.
Is input param order guaranteed with loopback-connector?
how can i set timeout?
It appears that the wsdl_options property is not being interpreted. When I try to connect to a soap service over HTTPS, I receive the following error with the strictSSL
and rejectUnauthorized
properties set to false :
{ "error": { "statusCode": 500, "name": "Error", "message": "unable to verify the first certificate", "code": "UNABLE_TO_VERIFY_LEAF_SIGNATURE", "stack": "Error: unable to verify the first certificate\n at Error (native)\n at TLSSocket.<anonymous> (_tls_wrap.js:1092:38)\n at emitNone (events.js:86:13)\n at TLSSocket.emit (events.js:185:7)\n at TLSSocket._finishInit (_tls_wrap.js:610:8)\n at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:440:38)" } }
However, if I add these as options to the ClientSSL security param then the certificate is bypassed, as expected. From looking at the implementation in soap-connector.js
is appears that the wsdl_options are possibly not being interpreted.
Steps to Reproduce
{ "strictSSL": false, "rejectUnauthorized": false }
Some of the automated tests rely on the availability of this URL:
http://www.webservicex.net/stockquote.asmx?wsdl
However, when webservicex.net becomes unavailable, CI would fail and affect other repos (e.g. loopback-datasource-juggler
) depending on it.
@rashmihunt suggested to have the wsdl locally for the tests.
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
Warning
These dependencies are deprecated:
Datasource | Name | Replacement PR? |
---|---|---|
npm | request |
These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.
.github/workflows/continuous-integration.yml
actions/checkout v3
actions/setup-node v4
actions/checkout v3
actions/setup-node v4
actions/checkout v3
github/codeql-action v3
github/codeql-action v3
package.json
debug ^4.0.1
request ^2.88.0
strong-globalize ^6.0.5
strong-soap ^4.0.0
@commitlint/cli ^19.0.0
@commitlint/config-conventional ^19.0.0
loopback-datasource-juggler ^5.0.0
mocha ^10.1.0
nyc ^17.0.0
should ^13.2.3
node >=18
.travis.yml
node 10
node 12
node 14
node 16
I would like to pass soap headers in this format:
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
soap:Header
< user >user</ user >
< password >password</ password >
</soap:Header>
soap:Body
</soap:Body>
</soap:Envelope>
this is how I am providing:
soapHeaders: [{
element: {inCredentials:{user: 'user', password: 'password'}},
namespace: 'http://sss'
}]
but for some reason it is not working and giving me invalid credentials in header when calling api, I test the API in postman and works fine. Am I doing something wrong in the soapheaders?
var soap = require('soap');
var url = 'http://api.daft.ie/v2/wsdl.xml';
soap.createClient(url, function(err, client) {
var args = {
'api_key': '...', // i can send this via email if needed
};
client['search_sale'](args, function(err, result) {
if (err) {
console.log(err);
return;
}
console.log(result);
});
});
$ node soap.js
{ results:
{ search_sentence: 'properties for sale anywhere in Ireland entered by',
pagination:
{ total_results: 35,
results_per_page: 10,
num_pages: 4,
current_page: 1,
first_on_page: 1,
last_on_page: 10 },
ads:
[ [Object],
[Object],
...
[Object],
[Object] ] } }
var loopback = require('loopback');
var path = require('path');
var ds = loopback.createDataSource('soap', {
connector: 'loopback-connector-soap',
// remotingEnabled: true,
url: 'http://api.daft.ie/v2/wsdl.xml',
// wsdl: 'http://api.daft.ie/v2/wsdl.xml',
operations: {
searchSale: {
service: 'DaftAPIService',
port: 'DaftAPIService',
operation: 'search_sale'
}
}
});
var args = {'api_key': '...'}; // i can send this via email if needed
// 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 DaftService = ds.createModel('DaftAPIService', {});
DaftService.searchSale(args, function (err, response) {
if (err) {
console.log('error: %j', err);
return;
}
console.log('response: %j', response);
});
});
$ node daft.ie.soap.js
Connection fails: [Error: Invalid WSDL URL: http://api.daft.ie/v2/wsdl.xml?wsdl
Code: 404
Response Body: <!DOCTYPE html
/to @raymondfeng
/cc @ShubhraKar @sumitha @cgole
When connecting to an external soap service, a loopback remote method created by the soap connector should respond as if it was a regular loopback method.
For example, calling a sharepoint service from a loopback REST api the response looks like this:
{
"d": {
"results": []
}
The connector should support an option that maps this to the conventional loopback response. Making the response body look like this:
[]
In general, loopback should add support for adding metadata in the body which is useful for clients that don't have access to read headers (where the metadata would otherwise exist).
Hi,
I need to use new features of node-soap module (v0.6). Can you update this module, please ?
Sincerely,
Valko
Hi i have a API with loopback versión 3.0 when execute NODE_ENV=local slc run
Connection failed: Error: Invalid WSDL URL: http://myurlservice.com/Service.asmx?wsdl
Code: 503
Response Body: "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\"http://www.w3.org/TR/html4/strict.dtd\">\r\n<HTML><HEAD><TITLE>Service Unavailable</TITLE>\r\n<META HTTP-EQUIV=\"Content-Type\" Content=\"text/html; charset=us-ascii\"></HEAD>\r\n<BODY><h2>Service Unavailable</h2>\r\n<hr><p>HTTP Error 503. The service is unavailable.</p>\r\n</BODY></HTML>\r\n"
It will be retried for the next request
events.js:183
throw er; // Unhandled 'error' event
I need the application to start even if the service is not available
Enhanced SOAP connector - Shelby enhanced the SOAP connector to handle WSDL 1.2/2.0, we want bake this back into the SL Connector.
Please reference: https://github.com/shelbys/loopback-connector-soap
ref: PLATAPI-1480
Here is the issue I posted on the forum, but haven't got any response. So simply try here. Your help will be really appreciated.
https://groups.google.com/forum/#!topic/loopbackjs/IX2yKCevDeI
I am only able to set the header values for the soap header when the loopback application boots. Is there any way to set the header on the fly when the call happens depending on some logic?
The latest version of this package currently on NPM is behind several commits and doesn’t work. The fix that it absolutely needs was done in cfab932. As it stands now, the _methodName
method is broken on NPM.
Hi ,
is it possible to return a promise when ds is ready to create model as against using the ds.once and wrapping supposed method calls that (could be exposed to other modules) inside ds.once() . for instance
var ds=loopback.createDataSource('soap',
{
connector: require('../index'),
remotingEnabled: true,
// wsdl: 'http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL' // The url to WSDL
wsdl: path.join(__dirname, './weather.wsdl')
}).then(function(){
return ds.createModel('WeatherService', {});
});
Description:
Whenever you send a json with bad characters for xml you get an error because the <,> are forbiden in xml. (usually you get the error on the response of the backend)
Solution:
Go recursive to all json and replace <, > and others chars to the equivalent in xml.
Reproducible always. version "loopback-connector-soap": "^2.5.0",
Thank you very much.
Your work is awesome!
There are many issues with https://github.com/vpulim/node-soap, especially in the area of XML namespace mapping/handling based on XML schemas.
The rewrite will:
Task list:
Hello,
I have a service that has a schema that requires the following XML for actionA:
<actionA xmlns="http://ws.example.com/">
<param1 xmlns="">ABC</uid>
<param2 xmlns="">123</vendor>
<param3 xmlns="">5</authentication>
</actionA>
The action element has a namespace, whereas the parameters are simply strings.
If I don't provide an empty namespace for them, they will take on the parent namespace (unless I'm misunderstanding XSD).
In any case, this is how my service expects the payload and this is how wizdler generates the skeletons, with an empty namespace.
However loopback generates the following which returns an exception:
<actionA xmlns="http://ws.example.com/">
<param1>ABC</uid>
<param2>123</vendor>
<param3>5</authentication>
</actionA>
I'm dead sure that this is the only issue. When I simply add xmlns="" on the params it works.
How can I get loopback do that?
Thank you
i am using this code, its working fine for me.
var service=ds.createModel('service',{});
service.GetBundleList({getBundleList : {CountryCode:'USA',BrandCode:'UVA',LanguageCode:'En',ICCID:'8901260842140591893',MSISDN:'14252833121'}},function(err,response){
console.log(response);
});
It printing the response but i want to print the request to actually determine the payload of SOAP request.
Hello guys,
Is it possible to update debug version to latest:
https://github.com/visionmedia/debug/releases
They added node 10 support and bump vulnerable packages.
From their changelog, no breaking change :)
I already have several methods working using createModel
var WeatherService = ds.createModel('WeatherService', {});
The problem is that these models are created programmatically and i cannot create a model.json
with the ACL access list maybe because these models are not created at the time that the ACL is parsed.
How can I get my soap models to work with authorization and authentication?
I am using this documentation but its only for models: http://loopback.io/doc/en/lb2/Controlling-data-access.html
Can you implement authZ for the whole datasource instead per models?
Thank you very much.
You are a great team and your product is awesome.
Security enables throws 'pfx' of null from soap-connector.js:100:20.
To enable security
'security': {
'scheme': 'ClientSSL'
}
/lib/soap-connector.js:100
if (sec.pfx) {
^
TypeError: Cannot read property 'pfx' of null
at /Volumes/Data/work/OpenBanking/git/aisp/ob-aisp-account-info-enterprise-direct-api/node_modules/loopback-connector-soap/lib/soap-connector.js:100:20
in soap-connector.js line no 79 var sec = null;
and line no 100 check for if (sec.pfx) {}
so its throws error.
line no 79 need to changes as var sec = {};
I fixed the issue, I will give the pull request
Hi,
Due to the upgrade of node-soap 0.8->0.9, maybe we should also bump the version of the connector ?
Hi guys, I have a problem getting the WSDL because the endpoint has to http basic auth. and i don't have idea where put the credentials for to generate the api. (in the model or datasource json file)
(sorry my english).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.