VMware {code} Community
mcssschaefer
Enthusiast
Enthusiast

VMware Orchestrator WebService and Perl

Hi guys,

a little bit offtopic, but unfortunately I only found little help in the orchestrator forum (http://communities.vmware.com/message/1796606#1796606). Hopefully someone in here can help.

I use SOAP::WSDL to call VMware Orchestrator workflows, but since Iam new to perl and webservices in I got stuck when trying to call workflows which needs complex types (i.e. Array of String or even more complexer types). Iam also not sure if SOAP::WSDL is the prefered library to use, since the VCO WebService WSDL is generated with Axis 1.2.1 and I can't say if the stubs which were created by SOAP::WSDL using wsdl2perl.pl are 100% correct.

So i think it is better to use SOAP::Lite.

As far as I undertsood this uses WSDL:

my $soap = SOAP::Lite->new();
my $service = $soap->service('http://xxxxxx/vmware-vmo-webcontrol/webservice?WSDL');
print Dumper($service->getAllWorkflows('xxx', 'xxxxxxx));

And, without WSDL:

my $soap = SOAP::Lite->new( proxy => 'http://xxxx/vmware-vmo-webcontrol');
$soap->uri("webservice");
my $som = $soap->call('getAllWorkflows','xxxxx','xxxxx');
die $som->fault->{ faultstring } if ($som->fault);
print $som->result, "\n";

I also tried this one, to construct own data types:

my $soap = SOAP::Lite->new( proxy => 'http://1xxxxxx/vmware-vmo-webcontrol');
$soap->uri("webservice");
my $som = $soap->call('getAllWorkflows',
        SOAP::Data->name('username')->value('xxxxx')->type('xxxxx'),
        SOAP::Data->name('password')->value('xxxx')->type('xxxxx'));

die $som->fault->{ faultstring } if ($som->fault);
print Dumper($som->result);

When using SOAP::WSDL I could call a worklfow i.e. with this call:

$response = $interface->executeWorkflow( {
       workflowId =>  $workflowid, # string
        password =>  $password, # string
        username =>  $username, # string
        workflowInputs => [{
                                name =>  "vm", # string
                                type =>  "VC:VirtualMachine", # string
                                value =>  $virtualMachine->get_dunesUri(), # string
                            },{
                                name =>  "name", # string
                                type =>  "string", # string
                                value =>  "perl snapshot", # string
                            },{
                                name =>  "description", # string
                                type =>  "string", # string
                                value =>  "perl snapshot", # string
                            },{
                                name =>  "memory", # string
                                type =>  "boolean", # string
                                value =>  1, # string
                            },{
                                name =>  "quiesce", # string
                                type =>  "boolean", # string
                                value =>  1, # string
                            }]
                            });
    die $response if not $response;

But I don't know how to construct complex types, let's assume I have a workflow which has an inputParamaeters dnsResolver which is an array os Strings. How can I pass something like that with SOAP::Lite or SOAP::WSDL?

@dnsResolver = ( "10.0.0.1", "10.0.0.2");

Interesting WSDL part:

<element name="executeWorkflow">

     <complexType>

          <sequence>

               <element name="workflowId" type="xsd:string"/>

               <element name="username" type="xsd:string"/>

               <element name="password" type="xsd:string"/>

               <element maxOccurs="unbounded" minOccurs="0" name="workflowInputs" type="impl:WorkflowTokenAttribute"/>

          </sequence>

     </complexType>

</element>

<complexType name="WorkflowTokenAttribute">

     <sequence>

          <element name="name" nillable="true" type="xsd:string"/>

          <element name="type" nillable="true" type="xsd:string"/>

          <element name="value" nillable="true" type="xsd:string"/>

     </sequence>

</complexType>

Thanks in advance,

Stephan

http://blog.mightycare.de http://www.mightycare.de
Reply
0 Kudos
7 Replies
mcssschaefer
Enthusiast
Enthusiast

Okay, I found a hint in the VCO developer guide. The array is a special formated string, see below:

The value property represents either
the input or output parameter value for
this particular workflow token, in the
form of a string.
If the type is an array of objects, the
value is a string of the following
format:
"#{#<type1>#<value1>#;#<type2>#
<value2>#...}#"
http://blog.mightycare.de http://www.mightycare.de
Reply
0 Kudos
mcssschaefer
Enthusiast
Enthusiast

I tired to use this information and it seems Iam getting closer:

[...]

},{
                                name    =>      "dnsServerList",
                                type    =>      "Array/string",
                                value   =>      "#{#<string>#<10.0.0.1>#;#<string>#<10.0.0.2>#}#",
                        },{

[...]

Orchestrator log:

-10-11 20:48:20.203+0200 INFO  [Execution] Executing workflow 'XXXXX'
2011-10-11 20:48:20.375+0200 ERROR [STDERR] ch.dunes.model.type.UnsupportedTypeException: Unknown type : <string>
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.type.TypeConverter.toObject(TypeConverter.java:351)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.type.ArrayConvertor$ArrayReader.getObjectFromString(ArrayConvertor.java:277)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.type.ArrayConvertor$ArrayReader.readElements(ArrayConvertor.java:196)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.type.ArrayConvertor$ArrayReader.readString(ArrayConvertor.java:228)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.type.ArrayConvertor$ArrayReader.read(ArrayConvertor.java:143)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.type.ArrayConvertor.toObject(ArrayConvertor.java:38)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.type.TypeConverter.toObject(TypeConverter.java:349)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.Attribute.fetchValue(Attribute.java:386)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.type.OgnlInvoker.getValue(OgnlInvoker.java:72)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.type.OgnlInvoker.getValue(OgnlInvoker.java:40)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.type.TypeQualifierValue.getValue(TypeQualifierValue.java:323)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.workflow.WorkflowParameterValidator.validateInputParameters(WorkflowParameterValidator.java:57)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.workflow.WorkflowParameterValidator.validateInputParameters(WorkflowParameterValidator.java:86)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.workflow.WorkflowParameterValidator.validateInputParameters(WorkflowParameterValidator.java:86)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.workflow.WorkflowParameterValidator.validateInputParameters(WorkflowParameterValidator.java:35)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.model.workflow.WorkflowParameterValidator.validateWorkflowInputs(WorkflowParameterValidator.java:116)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.workflow.engine.mbean.runner.WorkflowRunner.validateWorkflowParameters(WorkflowRunner.java:367)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.workflow.engine.mbean.runner.WorkflowRunner.execute(WorkflowRunner.java:62)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.workflow.engine.mbean.runner.WorkflowTokenRunner.execute(WorkflowTokenRunner.java:65)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.workflow.engine.mbean.helper.WorkflowHandler.execute(WorkflowHandler.java:187)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at ch.dunes.workflow.engine.mbean.helper.WorkflowHandler.run(WorkflowHandler.java:155)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
2011-10-11 20:48:20.375+0200 ERROR [STDERR]     at java.lang.Thread.run(Thread.java:619)

This shows, that Iam on the right way, Orchestrator sees that Iam trying to call with an array as parameter, the ArrayConvert is triggerd.

I think I could write some Java code using the examples to figure out what they expect. But maybe someone have already done this?

http://blog.mightycare.de http://www.mightycare.de
Reply
0 Kudos
stumpr
Virtuoso
Virtuoso

So I'm a huge Perl fan, but there are some Python bindings for VCO: http://labs.vmware.com/flings/pyvco  It may be an alternative worth considering since it's already baked.

Reuben Stump | http://www.virtuin.com | @ReubenStump
Reply
0 Kudos
mcssschaefer
Enthusiast
Enthusiast

Okay, I got it. The solution is to serialize the array to VMware-Format like described in VCO developer guide.

i.e.


     },{
   name    =>      "dnsServerList",
      type    =>      "Array/string",
    value   =>      "#{#string#10.0.0.1#;#string#10.0.0.2#}#", #"@dnsServerList",
     },{
http://blog.mightycare.de http://www.mightycare.de
Reply
0 Kudos
Carmageddon
Contributor
Contributor

Thank you so much mcssschaefer!

Your hints and samples helped me, I think I am too on the right way (using PHP).

Here is the method I created for arrays (similar to normal items):

/**
* Method to deal with adding arrays of elements like strings, numbers etc - only deals with homogenous array!
* @param array $objects Array of the values to add.
* @param String $name Name of the attribute, default value is 'name'.
* @param string $type Should be either string or "number".
*/
public function AddArrayInput(array $objects, $name="name", $type="string") {
if (empty($objects))
throw new Exception("Array of objects should not be empty!", 1);
$finalString = '#{';
foreach ($objects as $value)
$finalString = $finalString."#<$type>#<$value>#;";
$finalString = trim($finalString, ";");
$finalString = $finalString."}#";
$attr = new stdClass();
$attr->name = $name;
$attr->type = "Array/$type";
$attr->value = $finalString;
$this->workflowInputs[] = $attr;
}

When I call the workflow, I get no exceptions thrown, however, vCO still fails to validate the array parameters Smiley Sad

In the execution Events log (in GUI), I see this:

Workflow has failed: Invalid parameter(s)

Validation error for parameter 'alertEmailTo': OGNL error : null

And in the variables list, the Array type parameters remain "Not set"

I must be very very close! what am I doing wrong?

Here is a sample piece of the print_r of getWorkflowTokenStatus output which indicates how the parameter was constructed and passed to vCO:

    stdClass::__set_state(array(        'name' => 'OrgAlertEmailTo',        'type' => 'Array/string',        'value' => '#{#<string>#<maxim@domain.com>#}#',     )),

Please, any help?

EDIT: Additional information:

It seems that the validation error comes from the workflows INSIDE the workflow I am executing - for some reason either the array is not properly parsed, or not passed to the workflows inside. for example, the OrgAlertEmailTo is an input parameter for a local parameter called alertEmailTo (in Add an Organization workflow).

I am not sure what this clue means...

Message was edited by: Carmageddon

Reply
0 Kudos
Carmageddon
Contributor
Contributor

I solved it! your information is misleading (as well as the documentation).

The string should look as follows:

#{#string#xxx.xxx.37.202-xxx.xxx.37.206#}#

Reply
0 Kudos
mcssschaefer
Enthusiast
Enthusiast

Hi Carmagedon.

I don't see a problem. As you already figured out you have to remove '<' and '>'.

Best regards,

Stephan

P.S. Sorry for my late anwser, but we had a long weekend.

http://blog.mightycare.de http://www.mightycare.de
Reply
0 Kudos