VMware {code} Community
AS2E
Contributor
Contributor
Jump to solution

Custom Web View and PHP

Hello everyone,

I'd like to run PHP code on my custom web view but I don't know how to install it. The problem is than I don't even know which web server Orchestrator is using. I thought it was Apache but I can't find corresponding files. Could anyone help me to implement this functionality?

Thanks.

Reply
0 Kudos
1 Solution

Accepted Solutions
tschoergez
Leadership
Leadership
Jump to solution

Hi!

seems to be an issue within the Tapestry-Parser.

It should work if you use an external file for the javascript-stuff:

<html>
<head>
</head>
<body>
<script type="text/javascript" src="vodoo.js">
</script>

</body>
</html>

And all the javascript-code in voodo.js in the same directory.

Regards,

Joerg

View solution in original post

Reply
0 Kudos
25 Replies
Jinnie
VMware Employee
VMware Employee
Jump to solution

It runs on JBoss at the moment.

Quick googling shows some topics on JBoss modules for PHP. But I have not tried it.

And I am not really sure what is the chanse of successful mix between php and the usual tapesty/dojo environment of the webviews.

Reply
0 Kudos
tschoergez
Leadership
Leadership
Jump to solution

Servus!

PHP directly in Orchestrator? Forget it (sorry)!

Even if you manage it to run PHP on JBoss, there will be no direct integration into the Orchestrator-objects, as Jinnie mentioned.

The only way I see is to use a SOAP-client-library for PHP on an external webserver. Maybe the python-client for the Orchestrator-Webservice will help to get an idea: http://labs.vmware.com/flings/pyvco

(If you are new to the standard vco-webviews: It's hard to get started with them, and their future is VERY uncertain, so maybe focussing on another technology based on the Webservice-API is the better way)

Regards,

Joerg

Reply
0 Kudos
AS2E
Contributor
Contributor
Jump to solution

Well, seems to be pretty complicated. There might be another solution I hope. After running a workflow I'd like to check if it was successfull. I'm talking about very short workflows like restarting or resetting virtual machines. In case these workflows fail, this mostly means than the user don't has the nessecary rights and I'd like to display adequate error message.

I managed it to select the necessary information out of the Orchestrator database. Now I though about using PHP for reading out these data. Are there other possibilities for doing this?

Reply
0 Kudos
tschoergez
Leadership
Leadership
Jump to solution

Reading the information from the database will work surely. And if you really read-only, I see no danger for corruptin anything. BUT: The official statement of VMware will be: The database schema is not part of the API, so it is subject to change even in minor updates.

So have to QA your database reader after every vCO-patch, because the database layout may have changed.

For the use case you mentioned the way via webservice-API is not too complicated, I guess (calling workflows with multiple input is much more complicated). Here you only find the workflow and its past token, so only a few POST-values for the API call.

There might be another way: Can you create an action inside vCO which returns exactly the information you need?

Then is should be possible to call this action via a direct webview-link without any webservice-stuff. (You can find an example on page 307 in the developer guide).

I might find some time to create an concrete example on weekend...

Regards,

Joerg

AS2E
Contributor
Contributor
Jump to solution

I tried to create an action which should return the needed infomation. But now I have trouble calling the action in my webview.  I tried something like the following but of course this doesn't work because there is no system folder in my web view root folder. I'm a little confused about this. Do I have to create these folders manually? What do I have to put into the action.html file?

<script type="text/javascript" language="JavaScript">
<!---
var sysstat = .system/execute/action/action.html?action=GetTokenState&actionParameters=attribute:ResetVM&actionParameters=ResetVM;
document.write(sysstat);
//-->
</script>

Reply
0 Kudos
tschoergez
Leadership
Leadership
Jump to solution

Hi,

the system/execute/action.... is not a old-fashioned static html-file, it is a mapped method of the Tapestry-component in background. Comparable to a RESTful Web-Service. So there is no need to create the folder or copy any files.

Just make sure that the webview is published and has an Attribute "GetTokenState" (Type: Action) in your case. Then the full link to call the action should be http://your-vco-server:8282/vmo/yourwebviewname/system/execute/action/action.html?action=GetTokenSta.........

Regards,

Joerg

AS2E
Contributor
Contributor
Jump to solution

Hi,

How can I catch the the value the action I created returns? Don't I have to use a variable the value is going to be saved in?

Thanks.

Reply
0 Kudos
tschoergez
Leadership
Leadership
Jump to solution

Did it work with the link-example in my last post?

(I get a strange "String index out of range: -1" error when I try)

But if your read further in the dev guide, on page 308 second half there is another "Run an Action from a URL" chapter (seems to be a copy&past error in the docs).

With the link-structure like

http://vcoserver:8280/vmo/myWebviewName/system/vmo/pages/action.html?action=myWebViewAttributeAction...

it worked for me.

The result is direct the return of the called Action. If this return is a complex data type, the result will be in JSON-syntax.

You could now process this in your web applicaiton. A short google found an example:

http://www.admin-wissen.de/eigene-tutorials/webentwicklung/ajax-tutorial/json-statt-xml/

(its in German, but I don't think thats a problem for you 🙂 )

If you want, I can put together a complete example-package in vCO for you....

regards,

Joerg

Reply
0 Kudos
AS2E
Contributor
Contributor
Jump to solution

The first example you posted didn't work for me too. The second one at least doesn't return an error. I'm using the following link:

http://lab-srv002:8280/vmo/service_portal/system/vmo/pages/action.html?action=GetTokenState&actionPa... 

I created web view attributes for the GetTokenState action and the RestartVM workflow. This link displays nothing else than a "null" in the top left edge of the browser. I think there should be the value the action returns instead.

The action itself definitely works. For testing I created a workflow which calls the action and I added a System.log which puts out the returned value. This works fine. The action only returns the tokens state so I don't think that's a complex data type. It's just a string.

Here's my action in case you need it.

var retList = new Array();

if (runningWF != null) {

var tokens = runningWF.executions;
if(tokens != null){
  for(var jj=0; jj<tokens.length; jj++){
  
    retList.push( tokens[jj] );
  }
}
}


function compare( token1, token2 )  {
var time1 = token1.startDate;
var time2 = token2.startDate;
if ( time1 < time2 )  {
  return -1;
}
if ( time1 > time2 )  {
  return 1;
}
return 0;
}

retList.sort( compare ).reverse();
var state = retList[0].state;
System.log("Current State: "+state);

return state;

Reply
0 Kudos
tschoergez
Leadership
Leadership
Jump to solution

Hi!

Your Action worked for me:

08-03-2011 09-17-45.png

Don't forget to set the return-Type of your Action to String:

08-03-2011 09-19-07.png

BTW: I like the line "retList.sort( compare ).reverse();"... very smart usage of JavaScript-Power Smiley Wink... I just don't want to maintain it two years later :smileysilly:.

Regards,

Joerg

Reply
0 Kudos
AS2E
Contributor
Contributor
Jump to solution

I probably didn't set the return type correctly. Could you fix the pictures attached so I can how it worked for you? Something with the linking went wrong, I think.

btw. I copied the "retList.sort( compare ).reverse();" from another action. If something changes in a new version and it won't work anymore, I'll still be able to copy the changes. :smileygrin:

Reply
0 Kudos
AS2E
Contributor
Contributor
Jump to solution

I figured out where to set the return type. Now it works. For writing my the result into a variable, would you agree than the easiest way is to write it into a file first and read out that file afterwards? I can't find any hints it the documentation than there is a direct way too. Do you know where vCO saves that file? It doesn't seem to be possible to enter a path, at least I didn't figure out a way it works.

Here's the link I'm using right know:

http://lab-srv002:8280/vmo/service_portal/system/execute/action/GetTokenState/status.txt?actionParam..."

Reply
0 Kudos
tschoergez
Leadership
Leadership
Jump to solution

Hi,

first of all: Another try with the pictures...

09-17-45.png

09-19-07.png

aah, here we go: no space in the filename allowed.... "again what learned" :smileylaugh:

For the result: it comes back directly via http to the one who executed the link, so no need to save it to a file!?

If you want to save some information to a file, this is done locally on the vCO-server, with the FileWriter-objects in javascript. (See an example in the XML-related workflows of the included library). If you want to access local files on the vCO-server, also don't forget to set the js-io-rights.conf (=> vCO-Admin guide)...

do you call the action link from another PHP-based website?

Regards,

Joerg

Reply
0 Kudos
AS2E
Contributor
Contributor
Jump to solution

Yes, that's how it looks in my environment too now. The problem I actually have is than the result comes back directly via http. Depending on the actions result I want to forward the user either to website A or website B. But for realizing that, I need the actions result in a variable (for the if-statement). I didn't found any hints in the developer's guide than it's possible to save the result directly into a variable, but on page 308 is a chapter "Writing Action Results to a File". That's why I thougt the easiest way to save the result in a variable is by writing it to a file first, and read out the file after. My problem now is, than there's nowhere stated where vCO saves that file. I can enter a filename and it work's whitout any errors, but when I search for this file on the server afterwards, I can't find it.

You mean when I want to write something to file I have to do that inside the action? I don't had that idea yet but I'll try on Monday. That may work. Thanks.

Reply
0 Kudos
tschoergez
Leadership
Leadership
Jump to solution

hm, I don't really understand your architecture: If you get the pop-up to save the result as a file, the file is saved somewhere on the client computer!

If if you want to redirect this way, you have to implement something on the client side (JavaScript...). If the link is called by another homepage, you might to implement some Web2.0-AJAX-stuff, so that the frontend-webpage has the redirection-logic.

If you want to save some information in the filesystem on the server, use the FileWriter-object as mentioned...

Regards,

Joerg

Reply
0 Kudos
AS2E
Contributor
Contributor
Jump to solution

Should I get a pop-up? I'm using the following link:

http://lab-srv002:8280/vmo/service_portal/system/execute/action/GetTokenState/status.txt?actionParam..."

Shouldn't that link save a text file somewhere on my client computer? I neither can find a file called status.txt on my server nor on my client. I don't really want to save the text file on the server, that makes everything much more complicated.

Regards

Reply
0 Kudos
AS2E
Contributor
Contributor
Jump to solution

I found a partially working solution using Ajax. I'm now able to save the return value of the action into a variable. But it only works when I run the code in windows explorer. When I call the code using my web view I get the following parsing error.

org.apache.hivemind.ApplicationRuntimeException
Could not parse template 'startstop.html' of the webview folder 'service_portal'. -- (DEV mode: ch.dunes.vso.webview.engine.webviews-folder-path=C:\SYSMGR\Webviews)
org.apache.tapestry.parse.TemplateParseException
Tag <> on line 28 contains more than one 'this.callback' attribute.

I don't think there's a mistake in the code. Otherwise it wouldn't work in windows explorer. Isn't JBoss able to handle Ajax code or what else could be the problem here?

Reply
0 Kudos
tschoergez
Leadership
Leadership
Jump to solution

Hi!

Can you post the code of your Webview-Page and the Ajax stuff?

Otherwise it's impossible to reproduce the issue in the labs 🙂

Regards,

Joerg

Reply
0 Kudos
AS2E
Contributor
Contributor
Jump to solution

Yes of course. There it is. I marked line 28 where the error according to JBoss occurs.

<html>
<head>
</head>
<body>
<script type="text/javascript">
var req = new AjaxRequest('http://lab-srv002:8280/vmo/service_portal/system/vmo/pages/action.html?action=GetTokenState&actionPa...', function(response){
        var status = response;

    }
);
req.send();

if (status == "completed")
{
window.location="submitted2.html";
}
else
{
window.location="norights.html";
}

function AjaxRequest(sURL, fCallback, sContent)
{
this.url = sURL;
if(AjaxRequest.arguments.length < 1)
  this.url = "";
this.callback = fCallback;
if(AjaxRequest.arguments.length < 2)
this.callback = null;
this.content = sContent;
if(AjaxRequest.arguments.length < 3)
  this.content = "";
this.httpReq = null;
this.send = function()
{
  if(this.url.length <= 0)
   return false;
  if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject))
  {
   this.httpReq = new XMLHttpRequest();
  }
  else
  {
   try
   {
    this.httpReq = new ActiveXObject("Microsoft.XMLHTTP");
   }
   catch(e)
   {
    this.httpReq = null;  
   }
  }
  if (this.httpReq != null)
  {
   var method = (this.content.length > 0) ? "POST" : "GET";
   this.httpReq.open(method, this.url, true);
   if(this.content.length > 0)
    this.httpReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
   var tmp = this;
   this.httpReq.onreadystatechange = function(){tmp.onRequestStateChange();};
   this.httpReq.send(this.content);
   return true;
  }
  else
   return false;
}
this.onRequestStateChange = function()
{
  if(this.httpReq.readyState == 4)
  {
   if(this.callback != null)
    this.callback(this.httpReq.responseText);
  }
}
}

</script>
</body>
</html>

Reply
0 Kudos