WSDL create incident via Perl SOAP::Lite (14165 Views)
Reply
Trusted Contributor
hansmaulwurf
Posts: 209
Registered: ‎07-12-2011
Message 1 of 6 (14,165 Views)
Accepted Solution

WSDL create incident via Perl SOAP::Lite

Hello,

 

i have a problem creating incidents via SOAP (Web Services) from a Linux machine to the HPSM 9.31 Server.

It is used for the integration of our monitoring system to HPSM.

 

Using soapUI is working perfectly. Creating incidents via Perl script is also successful... as long as there are no special character in the 'Description' field of the incident. So the problem is in the script i use. May be some one has a script for me that is working or experienced similar challenges.

 

The text i want to transfer to the Description field is :

Scheduled action Hostname - Software- notification.vbs(1.8)(cmd /c cscript "c:\ovo\Hostname - Software- notification.vbs") for user $AGENT_USER failed.

 As stated this works via soapUI! The Perl script is going to encode this string to base64:

U2NoZWR1bGVkIGFjdGlvbiBIb3N0bmFtZSAtIFNvZnR3YXJlLSBub3RpZmljYXRpb24udmJzKDEu
OCkoY21kIC9jIGNzY3JpcHQgImM6XG92b1xIb3N0bmFtZSAtIFNvZnR3YXJlLSBub3RpZmljYXRp
b24udmJzIikgZm9yIHVzZXIgJEFHRU5UX1VTRVIgZmFpbGVkLg==

 Which is not really useful. Forcing the script to do not encode this string let the request fail:

 

SOAP::Transport::HTTP::Client::send_receive: HTTP/1.1 500 Internal Server Error
Connection: close
Connection: close
Date: Mon, 22 Jul 2013 06:42:14 GMT
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=iso-8859-1
...
...
...
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server... to create envelope from given source: </faultstring><faultactor>Server</faultactor></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
Fault
        Code    SOAP-ENV:Server
        Actor   Server
        String  Unable to create envelope from given source:

 Does anybody know how to correctly send the request via Perl SOAP::Lite or has a script that is working?

 

Attached the script

 

 

 

Trusted Contributor
hansmaulwurf
Posts: 209
Registered: ‎07-12-2011
Message 2 of 6 (14,157 Views)

Re: WSDL create incident via Perl SOAP::Lite

[ Edited ]

and the source where it was taken from:

 

http://www.ifost.org.au/Software/

 

Spoiler
#!/usr/bin/perl

use strict;
use warnings;

BEGIN {
    if ($0 =~ m|^(.*)/[^/]+$|) {
        push(@INC, $1);
    }
}

use SOAP::Lite +trace => 'debug';
use MIME::Base64;
use HPSMSOAP;

my $site = 'http://bp4smdemo.hpsweducation.com:13080/SM/7';
my $user = 'falcon';
my $password = 'orange perfection';
my $auth = encode_base64("$user:$password", '');

my %argument = ();
foreach my $a (@ARGV) {
    if ($a =~ s/^([^=]+)=//) {
        $argument{$1} = $a;
    } else {
        die "invalid argument [$a]\n";
    }
}
my @required = qw(AffectedCI AssignmentGroup Contact Description Impact Title Urgency);
my @missing = ();
my $misscount = 0;
foreach my $r (@required) {
    if (! exists $argument{$r}) {
        $misscount += 1;
        push(@missing, $r);
    }
}
die "$misscount required args missing:\n\t" . join(' ', sort(@missing)) . "\n"
    if ($misscount);

my @xargs = ();
foreach my $k (keys %argument) {
    push(@xargs, SOAP::Data->name($k => $argument{$k}));
}
my $x = SOAP::Data->value(@xargs);

my $soap = SOAP::Lite->new(
    proxy => "$site/ws",
    service => "$site/IncidentManagement.wsdl",
    default_ns => $site);
$soap->transport->http_request->header('Authorization' => "Basic $auth");
$soap->on_action(sub { '"Create"'; } );

my $keys = SOAP::Data->name('keys' => '')->type('');
my $instance = SOAP::Data->name('instance' => \$x)->type('');
my $model = SOAP::Data->name('model' => \SOAP::Data->value($keys, $instance));
my $som = $soap->call('CreateIncident', $model);

soapfault($som);
soapstatus($som);
soapdata($som, '//CreateIncidentResponse/messages', 1);
soapdata($som, '//CreateIncidentResponse/model', 0);

 

Esteemed Contributor
Leon_Van_Dongen
Posts: 278
Registered: ‎09-30-2008
Message 3 of 6 (14,137 Views)

Re: WSDL create incident via Perl SOAP::Lite

Have you tried a URI encode or something similiar, just to see if it works?  You might need to escape some of the non standard characters.

 

http://www.perlhowto.com/encode_and_decode_url_strings

Trusted Contributor
hansmaulwurf
Posts: 209
Registered: ‎07-12-2011
Message 4 of 6 (14,078 Views)

Re: WSDL create incident via Perl SOAP::Lite

Hello again,

 

still did not get it working.

Escaping characters is not what i want. The string has to be transfered literally.

 

I had the idea to encode every description string before starting the SOAP request and to decode it on site of HPSM. I tried base64Decode but that does not seem to work on strings?! (Expected data type= binary)

 

var b64="U2VydmljZSBvdXRwdXQ6ClNjaGVkdWxlZCBhY3Rpb24gYTAwMDAwMDIgLSBDYXRhbGxhZSAtIG5vdGlmaWNhdGlvbi52YnMoMS44KShjbWQgL2MgY3NjcmlwdCAiYzpcb3ZvBzAwMDAwMDIgLSBDYXRhbGxhZSAtIG5vdGlmaWNhdGlvbi52YnMiKSBmb3IgdXNlciAkQUdFTlRfVVNFUiBmYWlsZWQuCkluc3RydWN0aW9uczpOT05F";
var decoded=base64Decode(b64);
print(decoded);

 

This should output the decoded string, but instead i get this back:

敓癲捩⁥畯灴瑵਺捓敨畤敬⁤捡楴湯愠〰〰〰′‭慃慴汬敡ⴠ渠瑯晩捩瑡潩⹮扶⡳⸱⤸挨摭⼠⁣獣牣灩⁴挢尺癯ݯ〰〰〰′‭慃慴汬敡ⴠ渠瑯晩捩瑡潩⹮扶≳
潦⁲獵牥␠䝁久彔单剅映楡敬⹤䤊獮牴捵楴湯㩳低䕎

 

Nobody ever had a problem using WSDL like me...?

Trusted Contributor
hansmaulwurf
Posts: 209
Registered: ‎07-12-2011
Message 5 of 6 (14,074 Views)

Re: WSDL create incident via Perl SOAP::Lite

[ Edited ]

Used a script to decode strings found here:

http://www.ldrive.com/js/base64Encoder.html

 

Spoiler
//
// base64.js
//
//
// simple base64 string encoding and decoding routines
// includes utf-8 "character byte" support
//
// copyright ©2008-2009 logicdriven, llc.  all rights reserved.
// permission is granted for unlimited restribution, as long
// as logicdriven is attributed
//
// some concepts, particularly the utf-8 support, are based on
// code from webtoolkit (http://www.webtoolkit.info)
//
//
// note that the code here is written for readability, not maximum
// efficiency or minimum code size.  in particular, we could have
// used the fall-through capabilities of the switch() statement to
// reduce the code size in the encodeQuanta() routine, but it would
// have been a lot harder to follow without much in the way of a
// performance gain
//
//
//



    var _encodingTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"


    //
    // base64 decoding routines
    //
    //
    function decodeBase64String(base64String) {
    // decodes the base64 string passed in, returns the
    // decoded string

        if (base64String == null) return "";
        if (base64String == "") return "";

        var decodedString = "";

        // strip non-base64 characters
        //
        // if your ECMAScript language doesn't support regular expressions
        // in its .replace method, you'll probably want to use a split/join
        // expression to pull out invalid characters.  an example of this
        // for selected whitespace elements is in the commented code lines below
        //
        base64String = base64String.replace(/[^A-Za-z0-9\+\/\=]/g, "");
        //base64String = base64String.split("\r").join("");
        //base64String = base64String.split("\n").join("");
        //base64String = base64String.split("\t").join("");
        //base64String = base64String.split(" ").join("");
        //base64String = base64String.split("+").join("");

        // ensure string length is a multiple of four
        switch (base64String.length % 4) {
            case 1:
                base64String += "===";
                break;
            case 2:
                base64String += "==";
                break;
            case 3:
                base64String += "=";
                break;
        }



        // iterate through the string, adding each decoded
        // chunk (quanta) to the result
        for (var i=0; i<(base64String.length-1); i=i+4) {
            decodedString += decodeBase64Quanta(base64String.substring(i,i+4));
        }
        return decodedString;

    }



    function decodeBase64Quanta(base64Quanta) {
    // decodes a four-character chunk of base64 data and
    // returns the three-character result
    //
    // each of the encoded characters passed can be considered as a group
    // of six bits (2^6 = 64; thus, base64).  If all four encoded characters
    // are smooshed together, we get 24 bits (6*4 = 24).  These 24 bits are
    // then split up into three chunks of eight bits each (8*3 = 24), which
    // are then (usually) returned as three bytes.
    //
    // as mentioned in the comments, we're only working with encoded strings,
    // so we save the byte->string conversion step and return a three-character
    // string
    //
    // the four six-bit characters make up the eight-bit results as follows:
    //    11111122 22223333 33444444
    //
    //

        // stick encoding values from string into bytes
        //
        var byte1 = _encodingTable.indexOf(base64Quanta.charAt(0));
        var byte2 = _encodingTable.indexOf(base64Quanta.charAt(1));
        var byte3 = _encodingTable.indexOf(base64Quanta.charAt(2));
        var byte4 = _encodingTable.indexOf(base64Quanta.charAt(3));

        // adjust for the padding character -- "=", which is not listed in our table
        //
        if (byte1 < 0) byte1 = 0;
        if (byte2 < 0) byte2 = 0;
        if (byte3 < 0) byte3 = 0;
        if (byte4 < 0) byte4 = 0;


        var output = "";

        // generate the output characters
        //
        // we do the bitwise ANDing here because, despite what the documentation
        // says, some ECMAScript languages (I'm looking at you, Flash) appear to
        // not always fill in the emptied bits with 0 when left shifting
        //
        output = output + String.fromCharCode(((byte1 << 2) & 0xFC) | (byte2 >>> 4));
        output = output + String.fromCharCode(((byte2 << 4) & 0xF0) | (byte3 >>> 2));
        output = output + String.fromCharCode(((byte3 << 6) & 0xC0) | byte4);

        // return the result
        return output;

    }




    //
    // base64 encoding routines
    //
    //
    function encodeBase64String(sourceString) {
    // encodes the passed string into base64 format

        if (sourceString == null) return "";
        if (sourceString == "") return "";

        sourceString = String(sourceString);

        var encodedString = "";

        // iterate through the string, adding each encoded
        // chunk (quanta) to the result
        for (var i=0; i<(sourceString.length); i=i+3) {
            encodedString += encodeBase64Quanta(sourceString.substring(i,i+3));
        }
        return encodedString;

    }


    function encodeBase64Quanta(sourceQuanta) {
    // encodes a one-, two-, or three-character chunk of data and returns
    // the four-character base64-encoded result
    //
    // essentially the inverse of the decodeQuanta function listed above, our
    // three characters make up the four six-bit results as follows:
    //    111111 112222 222233 333333
    //
    
        if (sourceQuanta.length = 0) return "";
    
        // create base64 "bytes" w/default values
        //
        var byte1 = -1;
        var byte2 = -1;
        var byte3 = -1;
        var byte4 = -1;
        
        
        // shift input bits into byte vars as appropriate
        //
        // we do extra bitwise ANDing here because, despite what the documentation
        // says, some ECMA script languages (I'm looking at you, Flash) appear to
        // not always fill in the emptied bits with 0 when left shifting
        //
        switch (sourceQuanta.length) {
            case 1:
                byte1 = (sourceQuanta.charCodeAt(0) >> 2) & 0x3F;
                byte2 = ((sourceQuanta.charCodeAt(0) & 0x03) << 4) & 0x30;
                break;
            case 2:
                byte1 = (sourceQuanta.charCodeAt(0) >> 2) & 0x3F;
                byte2 = (((sourceQuanta.charCodeAt(0) & 0x03) << 4) & 0x30) | (sourceQuanta.charCodeAt(1) >>> 4);
                byte3 = ((sourceQuanta.charCodeAt(1) & 0x0F) << 2) & 0x3C;
                break;
            case 3:
                byte1 = (sourceQuanta.charCodeAt(0) >> 2) & 0x3F;
                byte2 = (((sourceQuanta.charCodeAt(0) & 0x03) << 4) &0x30) | (sourceQuanta.charCodeAt(1) >>> 4);
                byte3 = (((sourceQuanta.charCodeAt(1) & 0x0F) << 2) & 0x3C) | (sourceQuanta.charCodeAt(2) >>> 6);
                byte4 = sourceQuanta.charCodeAt(2) & 0x3F;
                break;
        }
        
        
        // create output characters
        //
        var char1 = "=";
        var char2 = "=";
        var char3 = "=";
        var char4 = "=";
        
        if (byte1 >= 0) char1 = _encodingTable.charAt(byte1);
        if (byte2 >= 0) char2 = _encodingTable.charAt(byte2);
        if (byte3 >= 0) char3 = _encodingTable.charAt(byte3);
        if (byte4 >= 0) char4 = _encodingTable.charAt(byte4);
        
        // return the result
        return char1 + char2 + char3 + char4;

    }


    
    //
    // utf-8 encoding/decoding routines
    //
    // use these before calling the encodeString() routine or
    // after calling decodeString()
    //
    function encodeUTF8String(sourceString) {
    // function returns a version of the UTF-8 source string where high-order (non-ASCII)
    // characters have been converted into a sequence of "character bytes".  the resulting
    // string can be base64 encoded using the routines in this file, which normally only
    // accept ASCII encodings.
    //
    // note that this function does not work for unicode characters not in the Unicode
    // Basic Multilingual Plane.  for more information on UTF-8, check out the article
    // at Wikipedia (http://en.wikipedia.org/wiki/UTF-8)
    //
    // as you can see from the code, calling this method when the string contains nothing
    // but ASCII characters has no effect -- the returned string is identical to the
    // source parameter

        if (sourceString == null) return "";
        if (sourceString == "") return "";


        var utf8String = "";

        for (var i=0; i<sourceString.length; i++) {

            var code = sourceString.charCodeAt(i);

            // return 1,2, or 3 characters based on character type
            //
            if (code < 0x80) {
            // us-ascii characters.  returns the plain character (byte begins with 0)
                utf8String += String.fromCharCode(code);
            } else if (code < 0x800) {
            // latin, greek, cyrillic, etc.
            //
            // return two characters. first character byte begins with 110, the second
            // begins with 10
            //
                utf8String += String.fromCharCode(0xC0 | (code >> 6));
                utf8String += String.fromCharCode(0x80 | (code & 0x3F));
            } else {
            // all other basic multilingual plane chars
            //
            // return three characters. first character byte begins with 1110, both the
            // second and third character bytes begin with 10
            //
                utf8String += String.fromCharCode(0xE0 | (code >> 12));
                utf8String += String.fromCharCode(0x80 | ((code >> 6) & 0x3F));
                utf8String += String.fromCharCode(0x80 | (code & 0x3F));
            }
        }

        return utf8String;
    }



    function decodeUTF8String(utf8String) {
    // function takes a string previously encoded with the encodeUTF8 method
    // above and returns the original (pre-encoded) string
    
        if (utf8String == null) return "";
        if (utf8String == "") return "";

        var output = "";
        var i = 0;


        while (i < utf8String.length) {

            var code1 = utf8String.charCodeAt(i);
            var code2 = utf8String.charCodeAt(i+1);
            var code3 = utf8String.charCodeAt(i+2);
            var resultCode = 0;

            if (code1 < 0x80) {
            // plain character
                resultCode = code1;
                i++;
            } else if((code1  >= 0xC0) && (code1  < 0xE0)) {
            // two-character sequence.  merge and convert
                resultCode = ((code1 & 0x1F) << 6);
                resultCode = resultCode | (code2 & 0x3F);
                i += 2;
            } else {
            // three-character sequence.  merge and convert
                resultCode = ((code1 & 0x0F) << 12);
                resultCode = resultCode | ((code2 & 0x3F) << 6);
                resultCode = resultCode | (code3 & 0x3F);
                i += 3;
            }

            // append calculation result
            output += String.fromCharCode(resultCode);
        }

        return output;
    }




print(decodeBase64String("U2VydmljZSBvdXRwdXQ6ClNjaGVkdWxlZCBhY3Rpb24gYTAwMDAwMDIgLSBDYXRhbGxhZSAtIG5vdGlmaWNhdGlvbi52YnMoMS44KShjbWQgL2MgY3NjcmlwdCAiYzpcb3ZvBzAwMDAwMDIgLSBDYXRhbGxhZSAtIG5vdGlmaWNhdGlvbi52YnMiKSBmb3IgdXNlciAkQUdFTlRfVVNFUiBmYWlsZWQuCkluc3RydWN0aW9uczpOT05FCiEipyQlJi8oKT0/YLQnIyorfnw7LiIiJyctLV9fRW5kZQoxMjM0NTY3ODkxMjM0NTY3ODkxMjM0NTY3ODkxMjM0NTY3ODk="))

 

 

If this should be solvable by HPSM tools, i would like to know.

 

Elsewise i accept this as solution

 

p.s.:

How to assign Kudos to oneself?

Acclaimed Contributor
Dennis Handly
Posts: 25,294
Registered: ‎03-06-2006
Message 6 of 6 (14,056 Views)

Re: WSDL create incident via Perl SOAP::Lite

>How to assign Kudos to oneself?

 

Unfortunately you can't.  ;-)  Only others can do that.

You can only mark your post as a solution.

The opinions expressed above are the personal opinions of the authors, not of HP. By using this site, you accept the Terms of Use and Rules of Participation.