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
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>#...}#"
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?
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.
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",
},{
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 ![]()
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
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#}#
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.
