Skip to content

Instantly share code, notes, and snippets.

@dex4er
Created May 24, 2013 15:31
Show Gist options
  • Save dex4er/5644354 to your computer and use it in GitHub Desktop.
Save dex4er/5644354 to your computer and use it in GitHub Desktop.
JSON to SOAP proxy server
#!/usr/bin/env perl
use strict;
use warnings;
use Log::Report 'json2xml', syntax => 'SHORT';
use XML::LibXML;
use XML::Compile::WSDL11;
use XML::Compile::SOAP11;
use XML::Compile::Transport::SOAPHTTP;
use File::Slurp qw(read_file);
use YAML::XS ();
use JSON::PP ();
use constant wsdl_file => 'calculator.wsdl';
sub call_soap {
my ($request, $endpoint) = @_;
my $wsdldata = read_file(wsdl_file);
my $operation = (keys %$request)[0];
$request = $request->{$operation};
my $wsdldom = XML::LibXML->load_xml(string => $wsdldata);
my $imports = eval { $wsdldom->find('/wsdl:definitions/wsdl:types/xsd:schema/xsd:import') };
my @schemas = eval { map { $_->getAttribute('schemaLocation') } $imports->get_nodelist };
my $wsdl = XML::Compile::WSDL11->new;
$wsdl->importDefinitions(\@schemas);
$wsdl->addWSDL($wsdldom);
$endpoint = $wsdl->endPoint unless defined $endpoint;
my $http = XML::Compile::Transport::SOAPHTTP->new(
address => $endpoint,
);
$http->userAgent->env_proxy;
my $action = eval { $wsdl->operation($operation)->soapAction() };
my $transport = $http->compileClient(
action => $action,
);
$wsdl->compileCalls(
sloppy_floats => 1,
sloppy_integers => 1,
transport => $transport,
);
my ($response, $trace) = $wsdl->call($operation, $request);
return $response;
};
use Plack::Request;
use Plack::Response;
use IO::String;
my $app = sub {
my ($env) = @_;
my $req_plack = Plack::Request->new($env);
my $json = JSON::PP->new->utf8->relaxed->allow_barekey;
my $req_data = $json->decode($req_plack->content);
my $res_data = call_soap($req_data, $req_plack->request_uri);
my $res_json = $json->encode($res_data);
my $res_plack = Plack::Response->new(200);
$res_plack->content_type('text/json');
$res_plack->body($res_json);
return $res_plack->finalize;
};
$app;
{
"add": {
"x": 2,
"y": 3
}
}
<?xml version="1.0" encoding="US-ASCII"?>
<!--generated by GLUE Standard 4.1.2 on Fri Nov 21 13:50:48 PST 2003-->
<wsdl:definitions name="Calculator"
targetNamespace="http://www.parasoft.com/wsdl/calculator/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tme="http://www.themindelectric.com/"
xmlns:tns="http://www.parasoft.com/wsdl/calculator/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xsd:schema
elementFormDefault="qualified"
targetNamespace="http://www.parasoft.com/wsdl/calculator/">
<xsd:element
name="add">
<xsd:complexType>
<xsd:sequence>
<xsd:element
name="x" type="xsd:float"/>
<xsd:element name="y"
type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element
name="addResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element
name="Result"
type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element
name="divide">
<xsd:complexType>
<xsd:sequence>
<xsd:element
name="numerator" type="xsd:float"/>
<xsd:element
name="denominator"
type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element
name="divideResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element
name="Result"
type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element
name="multiply">
<xsd:complexType>
<xsd:sequence>
<xsd:element
name="x" type="xsd:float"/>
<xsd:element name="y"
type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element
name="multiplyResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element
name="Result"
type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element
name="subtract">
<xsd:complexType>
<xsd:sequence>
<xsd:element
name="x" type="xsd:float"/>
<xsd:element name="y"
type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element
name="subtractResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element
name="Result"
type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:message
name="add0In">
<wsdl:part element="tns:add"
name="parameters"/>
</wsdl:message>
<wsdl:message
name="add0Out">
<wsdl:part element="tns:addResponse"
name="parameters"/>
</wsdl:message>
<wsdl:message
name="divide1In">
<wsdl:part element="tns:divide"
name="parameters"/>
</wsdl:message>
<wsdl:message
name="divide1Out">
<wsdl:part element="tns:divideResponse"
name="parameters"/>
</wsdl:message>
<wsdl:message
name="multiply2In">
<wsdl:part element="tns:multiply"
name="parameters"/>
</wsdl:message>
<wsdl:message
name="multiply2Out">
<wsdl:part element="tns:multiplyResponse"
name="parameters"/>
</wsdl:message>
<wsdl:message
name="subtract3In">
<wsdl:part element="tns:subtract"
name="parameters"/>
</wsdl:message>
<wsdl:message
name="subtract3Out">
<wsdl:part element="tns:subtractResponse"
name="parameters"/>
</wsdl:message>
<wsdl:portType
name="ICalculator">
<wsdl:operation name="add"
parameterOrder="x y">
<wsdl:input message="tns:add0In"
name="add0In"/>
<wsdl:output message="tns:add0Out"
name="add0Out"/>
</wsdl:operation>
<wsdl:operation name="divide"
parameterOrder="numerator denominator">
<wsdl:input
message="tns:divide1In" name="divide1In"/>
<wsdl:output
message="tns:divide1Out"
name="divide1Out"/>
</wsdl:operation>
<wsdl:operation
name="multiply" parameterOrder="x y">
<wsdl:input
message="tns:multiply2In" name="multiply2In"/>
<wsdl:output
message="tns:multiply2Out"
name="multiply2Out"/>
</wsdl:operation>
<wsdl:operation
name="subtract" parameterOrder="x y">
<wsdl:input
message="tns:subtract3In" name="subtract3In"/>
<wsdl:output
message="tns:subtract3Out"
name="subtract3Out"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding
name="ICalculator" type="tns:ICalculator">
<soap:binding
style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation
name="add">
<soap:operation soapAction="add"
style="document"/>
<wsdl:input name="add0In">
<soap:body
use="literal"/>
</wsdl:input>
<wsdl:output
name="add0Out">
<soap:body
use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation
name="divide">
<soap:operation soapAction="divide"
style="document"/>
<wsdl:input name="divide1In">
<soap:body
use="literal"/>
</wsdl:input>
<wsdl:output
name="divide1Out">
<soap:body
use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation
name="multiply">
<soap:operation soapAction="multiply"
style="document"/>
<wsdl:input name="multiply2In">
<soap:body
use="literal"/>
</wsdl:input>
<wsdl:output
name="multiply2Out">
<soap:body
use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation
name="subtract">
<soap:operation soapAction="subtract"
style="document"/>
<wsdl:input name="subtract3In">
<soap:body
use="literal"/>
</wsdl:input>
<wsdl:output
name="subtract3Out">
<soap:body
use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service
name="Calculator">
<wsdl:documentation>instance of class webtool.soap.examples.calculator.Calculator</wsdl:documentation>
<wsdl:port
binding="tns:ICalculator" name="ICalculator">
<soap:address
location="http://ws1.parasoft.com/glue/calculator"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment