Business::cXML - Perl implementation of cXML messaging
Respond to an incoming request:
use Business::cXML; $cxml = new Business::cXML ( local => 'https://example.com/our/cxml', handlers => { PunchOutSetup => { __handler => sub { ... }, operationAllowed => 'create', }, }, ); # Calls $res->reply_to($req), so to/from/sender are probably OK. $output_xml_string = $cxml->process($input_xml_string); # Send output to requestor...
Send a request to a server:
use Business::cXML; $cxml = new Business::cXML ( remote => 'https://example.com/rest/cxml', secret => 'somesecrettoken', ); $req = $cxml->new_request('PunchOutSetup'); $req->from(id => '123456', domain => 'DUNS'); # Also sets Sender by default $req->to(id => '654321', domain => 'NetworkId'); # Populate request, see Business::cXML::Transmission documentation... $res = $cxml->send($req); # Do something with $res, the Business::cXML::Transmission response received...
Create a one-way message:
use Business::cXML; $cxml = new Business::cXML; $msg = $cxml->new_message('PunchOutOrder'); $msg->from(id => '123456', domain => 'DUNS'); # Also sets Sender by default $msg->to(id => '654321', domain => 'NetworkId'); # Populate message, see Business::cXML::Transmission documentation... print $cxml->stringify($msg, url => '...'); # Transmission in cXML-Base64 in an HTML FORM
Dispatch incoming HTTP/HTTPS requests and respond to them. Send outgoing requests and parse responses. Prepare and parse one-way messages.
As a convention, cXML refers to overall messages as "transmissions" to distinguish from Message type payloads. This library includes native Perl modules for the following transmission types:
Message
Business::cXML::Request::PunchOutSetup / Business::cXML::Response::PunchOutSetup
Business::cXML::Message::PunchOutOrder
Planned: Request::Order / Response::Order
Specifically NOT implemented are:
Attachments
Cryptographic signatures
Requesting the remote side's capabilities profile and restricting ourselves to it
While the above may implement a relatively small portion of the whole cXML specification, which is designed to describe every business-to-business transaction imaginable world-wide, it does fully satisfy our need (see "ACKNOWLEDGEMENTS") to act as a "punch-out" supplier to our Ariba/PeopleSoft/SAP/etc corporate clients.
The design is completely modular (see Business::cXML::Object) and uses XML::LibXML under the hood, to help simplify future efforts to cover more of the standard.
new( %options )
Returns a fresh cXML handler.
Options useful to send requests and receive responses:
remote
HTTP/HTTPS URL where to POST requests
Options useful to process requests and emit responses:
local
HTTP/HTTPS URL to publish where clients can reach this handler
secret
Secret keyword expected by remote server
sender_callback
Subroutine, passed to "sender_callback()".
One of: CXML_LOG_NOTHING (default), CXML_LOG_ERR, CXML_LOG_WARN, CXML_LOG_INFO. Alternates CXML_LOG_ERROR and CXML_LOG_WARNING are also available.
CXML_LOG_NOTHING
CXML_LOG_ERR
CXML_LOG_WARN
CXML_LOG_INFO
CXML_LOG_ERROR
CXML_LOG_WARNING
Subroutine, passed to "log_callback()".
Hash of handlers, dereferenced and passed to "on()".
sender_callback( $sub )
By default, a request's From/Sender credentials are only used to guess response credentials. If you specify a callback here, it will be invoked immediately after XML parsing, before passing to transaction handlers, giving you an opportunity to authenticate the caller.
Your subroutine will be passed 3 arguments:
If you return a false value, the request will be deemed unauthorized and no handler will be invoked.
If you return anything else, it will be stored and available in the request sender's _note property. (See Business::cXML::Credential for details.)
_note
Note that cXML From/Sender headers contain information about an entire company you're doing business with. The identity of the specific person triggering the request, if applicable, will be somewhere in contact or extrinsic data in the payload itself.
log_callback( $sub )
By default, basic details about log-worthy events are dumped to STDERR (filtered according to the current log level). By specifying your own handler, you can do anything else you'd like when informative events occur.
STDERR
Your subroutine will be passed 5 arguments:
Successful parsing of a new transmission triggers a level 3 log, whereas failure is a level 2. Failure to produce valid XML from our internal data (which should never occur) is a level 1.
NOTE: Logging is limited to this module. Thus, be sure to use process(), send() and stringify() to trap interesting events in the handling of Request, Response and Message transmissions.
Request
Response
on( %handlers )
Each key in %handlers is the bare name of a supported transaction type. For example, if you want to support PunchOutSetupRequest, the key is PunchOutSetup. Each key should point to a hashref specifying any options to declare in our Profile.
%handlers
PunchOutSetupRequest
PunchOutSetup
Profile
Special key __handler is mandatory and should point to a sub which will be called if its type of request is received, valid and optionally authenticated. Your handler will be passed 3 arguments:
__handler
Be sure to change the response's status, which is a 500 error by default.
The response's to/from/sender is initialized in reciprocity to the request's, so your handler might not need to change much in those.
Keys represent the case-sensitive name of the cXML request without the redundant suffix. For example, a PunchOutSetupRequest is our type PunchOutSetup. Possible keys include: Order, PunchOutSetup, StatusUpdate, GetPending, Confirmation, ShipNotice, ProviderSetup, PaymentRemittance.
Order
StatusUpdate
GetPending
Confirmation
ShipNotice
ProviderSetup
PaymentRemittance
Pings and Profile requests are built-in, although you can override the handling of the latter with your own handler if you'd like.
process( [$input] )
Decodes the $input XML string which is expected to be a complete cXML transmission. May invoke one of your handlers declared with on() if appropriate.
$input
Returns a string containing a valid cXML document at all times. This document includes any relevant status information determined during processing.
Note that an omitted or empty $input is actually valid and results in a "pong" response.
new_request( [$type] )
Returns a fresh Business::cXML::Transmission ready to be used as a request. Optional $type is a convenience shortcut to Business::cXML::Transmission::type(). The request's sender secret will be pre-filled.
$type
send( $request )
Freeze $request, a Business::cXML::Transmission, and attempt sending it to the configured remote server. Returns the received response Business::cXML::Transmission on success, undef on failure. Note that as per Business::cXML::Transmission::new(), it is also possible that an error arrayref be returned instead of a transmission if parsing failed.
$request
undef
In case of failure, you may want to wait a certain amount of time and try again. To give you more options to that effect, $request can be either a Business::cXML::Transmission or a string.
new_message( [$type] )
Returns a fresh Business::cXML::Transmission ready to be used as a stand-alone message. Optional $type is passed on to Business::cXML::Transmission::type().
stringify( $message, %args )
Convenience wrapper around Business::cXML::Transmission::toForm() which allows you to trap logging events.
Stéphane Lavergne https://github.com/vphantom
Graph X Design Inc. https://www.gxd.ca/ sponsored this project.
Copyright (c) 2017-2018 Stéphane Lavergne https://github.com/vphantom
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
To install Business::cXML, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Business::cXML
CPAN shell
perl -MCPAN -e shell install Business::cXML
For more information on module installation, please visit the detailed CPAN module installation guide.