--_000_D290AD8432118048947689BA3AE8A9B3E47B82SACEXCMBX04PRDhqn_
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
Hi Vojtech,
The patch is great and has cleared up some questions I had about the implem=
entation. I've been able to get the sample plugins working and waded throug=
h the code changes, so feel like I have a good understanding of what was de=
livered. Thanks a lot for putting this all together. I do have a few questi=
ons and suggestions for you, though.
Will there eventually be a way to add one or more buttons to the context se=
nsitive buttons and menus throughout the interface? For example, we'd like =
to allow a button to provision a datastore when a data center, cluster, or =
host is selected. When the button is clicked, it would open a dialog with a=
n iframe in which we would load our interface to perform the associated act=
ion. Some contexts would have several buttons, such as a storage domain (pr=
ovision, resize, dedupe management, destroy) so it would probably make sens=
e for a drop down menu to be available as well so that the number of button=
s above the table doesn't get too cluttered. We'd also like to add these sa=
me actions to the menus that popup when a contextual object is right clicke=
d.
If needed we can help work on an implementation for the dialog popup plugin=
framework as we'd like to get it in relatively quickly so we can move forw=
ard on the content side of our plugin.
For the reverse proxy, would it be easier from a customer standpoint to jus=
t include a reverse proxy servlet such as this one?
http://sourceforge.net=
/projects/j2ep/
I'm just thinking that setting up and managing a plugin for the HTTP server=
may be more complex than including one internally that would be transparen=
t to a customer.
Thanks,
Chris
From: Vojtech Szocs <vszocs@redhat.com<mailto:vszocs@redhat.com>
Date: September 21, 2012 4:37:31 PM EDT
To: engine-devel <engine-devel@ovirt.org<mailto:engine-devel@ovirt.org>
Subject: [Engine-devel] UI Plugins: PoC patch revision 5 is
here
Hi guys,
it's been a while but here comes the latest revision of UI Plugins proof-of=
-concept patch (please find it attached).
This revision was originally meant to focus solely on server-side component=
s of the plugin infrastructure. However, I ended up implementing all the ma=
jor concepts and ideas as discussed on engine-devel mailing list, impacting=
both client-side and server-side parts of the plugin infrastructure. As a =
result, UI plugin infrastructure should be pretty much complete now, so we =
can focus on specific plugin API features in upcoming PoC revisions.
There's a whole bunch of changes and improvements in this revision, so I'll=
try to cover all the relevant parts step by step. If you have any comments=
, questions or ideas, please let me know!
So here we go... (or if you just want to get the patch, find the link at th=
e end of this message)
________________________________
0. Added new Engine configuration values
UI plugin data path is represented by ConfigValues.UIPluginDataPath enum op=
tion ("UIPluginDataPath" in vdc_options table), and resolved relative to Co=
nfigValues.DataDir if possible. Following (default) values:
* UIPluginDataPath =3D ui-plugins
* DataDir =3D /usr/share/ovirt-engine
result in UI plugin data path: /usr/share/ovirt-engine/ui-plugins
UI plugin config path is represented by ConfigValues.UIPluginConfigPath enu=
m option ("UIPluginConfigPath" in vdc_options table), and resolved relative=
to ConfigValues.ConfigDir if possible. Following (default) values:
* UIPluginConfigPath =3D ui-plugins
* ConfigDir =3D /etc/ovirt-engine
result in UI plugin config path: /etc/ovirt-engine/ui-plugins
1. Processing UI plugin data on the server
PluginDataManager is the class responsible for reading, validating and cach=
ing UI plugin descriptor/configuration data on the server (Engine). It has =
two main responsibilities:
* return a snapshot of currently valid plugin data (getCurrentData meth=
od)
* reload plugin data from local file system if necessary (reloadData me=
thod)
The reloadData method doesn't modify "live" plugin data directly. Instead,
=
it creates a local working copy of current plugin data, updates this copy a=
s it reads/validates plugin descriptor and configuration files, and attempt=
s to update "live" plugin data through conditional reference re-assignment =
(using java.util.concurrent.atomic.AtomicReference.compareAndSet method).
In other words, reloadData method makes no attempts with regard to Java loc=
k-based synchronization, in favor of dealing with "live" data through Atomi=
cReference (reference that involves atomic volatile reads and writes):
* In the best case, a thread will succeed in updating "live" data (Atom=
icReference.compareAndSet =3D=3D true), which means that "live" data remain=
ed unchanged since this thread acquired a reference of current plugin data.
* In the worst case, a thread will NOT succeed in updating "live" data =
(AtomicReference.compareAndSet =3D=3D false), which means that "live" data =
was already changed by another thread since this thread acquired a referenc=
e of current plugin data.
In my opinion, when dealing with external resources like the local file sys=
tem, this is a good compromise between performance and up-to-date data. Whi=
le we might not get "completely-up-to-date" data at the given point in time=
(reloadData + getCurrentData), we are guaranteed to get "recently-up-to-da=
te" and consistent data. In other words, the requirement of "completely-up-=
to-date" data would involve synchronized statements that would hurt perform=
ance. In my (very humble) opinion, the benefit of having "completely-up-to-=
date" data, at the cost of reduced performance, is not really worth it, esp=
ecially in our case when the user can just hit refresh (F5) to reload WebAd=
min and its plugin data.
Plugin descriptor files are expected to be placed in UI plugin data path, f=
or example: /usr/share/ovirt-engine/ui-plugins/foo.json
Following descriptor file attributes are implemented and recognized by the =
plugin infrastructure:
* name: A name that uniquely identifies the plugin (required attribute)=
.
* url: URL of plugin host page that invokes the plugin code (required a=
ttribute).
* config: Default configuration object associated with the plugin (opti=
onal attribute).
* resourcePath: Path to plugin static resources, relative to UI plugin =
data path (optional attribute). This is used when serving plugin files thro=
ugh Engine PluginResourceServlet (more on this below).
Plugin configuration files are expected to be placed in UI plugin config pa=
th, for example: /etc/engine/ui-plugins/foo-config.json
Note that plugin configuration files follow the "<descriptorFileName>-confi=
g.json" convention.
Following configuration file attributes are implemented and recognized by t=
he plugin infrastructure:
* config: Custom configuration object associated with the plugin (optio=
nal attribute). This overrides the default plugin descriptor configuration,=
if any.
* enabled: Indicates whether the plugin should be loaded on WebAdmin st=
artup (optional attribute). Default value is 'true'.
* order: Defines the relative order in which the plugin will be loaded =
on WebAdmin startup (optional attribute). Default value is Integer.MAX_VALU=
E (lowest order).
The concept of merging custom configuration (config attribute in foo-config=
.json), if any, on top of default configuration (config attribute in foo.js=
on), if any, remains unchanged. This makes the plugin configuration quite f=
lexible - in my opinion, the added complexity of handling/merging such conf=
iguration is definitely worth the effort.
The enabled attribute is straight-forward, allowing users to turn the given=
plugin off, if necessary. In future, users should still be able to load su=
ch plugins through WebAdmin GUI.
The order attribute controls the order in which plugins are loaded on WebAd=
min startup. Since plugin resources are fetched asynchronously by the brows=
er, this is basically a way of imposing some degree of determinism in the "=
generally-non-deterministic" plugin environment, which is helpful when trou=
bleshooting problems with multiple plugins. This attribute is also helpful =
due to file listing methods in java.io.File giving no guarantees that files=
would be listed in any particular order (otherwise we could just go for th=
e "NN-<descriptorFileName>.json" convention, with NN being the order
number=
).
2. Modified behavior of WebadminDynamicHostingServlet
WebadminDynamicHostingServlet is the servlet used to serve WebAdmin applica=
tion host page (HTML page that bootstraps WebAdmin JavaScript code).
In addition to its former behavior, as part of handling the given request, =
WebadminDynamicHostingServlet:
* reloads descriptor/configuration data from local file system if neces=
sary, and obtains a snapshot of currently valid plugin data (PluginDataMana=
ger.reloadAndGetCurrentData)
* embeds all plugin meta-data, suitable for use in client-side plugin i=
nfrastructure, into WebAdmin host page as "pluginDefinitions" JavaScript ar=
ray (PluginDefinitions)
As a result, reloading UI plugin descriptor/configuration data is as simple=
as refreshing (F5) WebAdmin application in the browser (no need to restart=
Engine).
3. Added servlet for serving plugin static resources
PluginResourceServlet is the servlet used to serve UI plugin static files (=
plugin host page, 3rd party JavaScript, etc.) from the local file system.
For example, requesting URL:
* http://<EngineManagerHost>:8700/webadmin/webadmin/plugin/foo/content/=
start.html<http://%3cEngineManagerHost%3e:8700/webadmin/webadmin/plugin/foo=
/content/start.html
will send the content of:
* /usr/share/ovirt-engine/ui-plugins/<resourcePath>/content/start.html
to the client.
As shown in the above example:
* /webadmin/webadmin/plugin/ is the servlet root path for PluginResourc=
eServlet
* in the extra path beyond the servlet root path (/foo/content/start.ht=
ml):
* /foo represents the name of the plugin
* /content/start.html represents the path to requested resource, rel=
ative to "UIPluginDataPath / <resourcePath>"
Note that each plugin using PluginResourceServlet to serve its static files=
must declare non-empty resourcePath attribute in within the plugin descrip=
tor.
Also note that PluginResourceServlet, unlike WebadminDynamicHostingServlet,=
does NOT reload descriptor/configuration data from local file system as pa=
rt of handling the given request. In other words, it's assumed that plugin =
data has already been (re)loaded when serving WebAdmin application host pag=
e, with subsequent requests to PluginResourceServlet reading the current pl=
ugin information.
Until we solve the cross-origin issue in a clean way, PluginResourceServlet=
should be used to serve all plugin resources from local file system.
4. Plugin lifecycle improved to deal with misbehaving plugins
PluginState enum has been modified to deal with plugins that allow uncaught=
exceptions to escape from plugin event handler functions (e.g. "UiInit"):
* removed state INITIALIZED
* added state INITIALIZING: The plugin is (currently) being initialized=
by calling UiInit event handler function.
* added state IN_USE: Plugin's UiInit event handler function has comple=
ted successfully, we can now call other event handler functions as necessar=
y. The plugin is in use now.
* added state FAILED: An uncaught exception escaped while calling an ev=
ent handler function, which indicates internal error within the plugin code=
. The plugin is removed from service.
I've attached a simple state diagram that illustrates different states and =
transitions between them (green color is initial state, red color is end st=
ate).
Uncaught exceptions in plugin event handler functions will be caught and ha=
ndled by the plugin infrastructure. This prevents a misbehaving plugin from=
breaking WebAdmin application, since WebAdmin is the caller (initiator) of=
the function call. In such case, the plugin will be removed from service.
Update on cross-origin issue (consequence of same-origin policy)
In order for the plugin to access WebAdmin plugin API, plugin host page (e.=
g. start.html) must be served from URL on same origin as Engine origin. Oth=
erwise, plugin code running in the context of an iframe'd host page will fa=
il to evaluate "parent.pluginApi" expression, with "parent" being
top-level=
(WebAdmin) window, and "pluginApi" being the global plugin API object expo=
sed by WebAdmin.
This is why PluginResourceServlet, available on Engine origin, should be us=
ed to serve all plugin resources from local file system.
There's only one issue that remains to be solved: cross-origin "plugin vs. =
remote service" communication, with "remote service" being anything other
t=
han Engine (REST API). In future, we'll address this with Apache reverse pr=
oxy configuration, so that users can configure Apache server (placed in fro=
nt of Engine JBoss AS) to put arbitrary (local or remote non-Engine) servic=
es on same origin. However, this requires a change in current Apache config=
uration. Until then, users can manually edit the Engine Apache configuratio=
n file (/etc/httpd/conf.d/ovirt-engine.conf).
________________________________
I've attached some sample plugin files for you to experiment with. Instead =
of attaching actual patch file (92 kB) to this email, I've submitted the pa=
tch to oVirt Gerrit:
http://gerrit.ovirt.org/8120
Let me know what you think!
Cheers,
Vojtech
<ui-plugin-sample-files.tar.gz
<ui-plugin-lifecycle.png
_______________________________________________
Engine-devel mailing list
Engine-devel@ovirt.org<mailto:Engine-devel@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-devel
--_000_D290AD8432118048947689BA3AE8A9B3E47B82SACEXCMBX04PRDhqn_
Content-Type: text/html; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
<html xmlns:v=3D"urn:schemas-microsoft-com:vml"
xmlns:o=3D"urn:schemas-micr=
osoft-com:office:office" xmlns:w=3D"urn:schemas-microsoft-com:office:word"
=
xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml"
xmlns=3D"http:=
//www.w3.org/TR/REC-html40"
<head
<meta http-equiv=3D"Content-Type"
content=3D"text/html; charset=3Dus-ascii"=
<meta name=3D"Generator" content=3D"Microsoft
Word 14 (filtered medium)"
<!--[if
!mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
p
{mso-style-priority:99;
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
font-size:12.0pt;
font-family:"Times New Roman","serif";}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
{mso-style-priority:99;
mso-style-link:"Balloon Text Char";
margin:0in;
margin-bottom:.0001pt;
font-size:8.0pt;
font-family:"Tahoma","sans-serif";}
span.BalloonTextChar
{mso-style-name:"Balloon Text Char";
mso-style-priority:99;
mso-style-link:"Balloon Text";
font-family:"Tahoma","sans-serif";}
span.EmailStyle20
{mso-style-type:personal;
font-family:"Calibri","sans-serif";
color:#1F497D;}
span.EmailStyle23
{mso-style-type:personal-reply;
font-family:"Calibri","sans-serif";
color:#1F497D;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
@list l0
{mso-list-id:180434570;
mso-list-template-ids:-282402880;}
@list l0:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:"Courier New";
mso-bidi-font-family:"Times New Roman";}
@list l0:level3
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l0:level4
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l0:level5
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l0:level6
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l0:level7
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l0:level8
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l0:level9
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l1
{mso-list-id:259874230;
mso-list-template-ids:-1105409970;}
@list l1:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l1:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:"Courier New";
mso-bidi-font-family:"Times New Roman";}
@list l1:level3
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l1:level4
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l1:level5
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l1:level6
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l1:level7
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l1:level8
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l1:level9
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l2
{mso-list-id:580258439;
mso-list-template-ids:-6366690;}
@list l2:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l2:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:"Courier New";
mso-bidi-font-family:"Times New Roman";}
@list l2:level3
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l2:level4
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l2:level5
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l2:level6
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l2:level7
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l2:level8
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l2:level9
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l3
{mso-list-id:713581435;
mso-list-template-ids:2069783976;}
@list l3:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l3:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:"Courier New";
mso-bidi-font-family:"Times New Roman";}
@list l3:level3
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l3:level4
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l3:level5
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l3:level6
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l3:level7
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l3:level8
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l3:level9
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l4
{mso-list-id:765921994;
mso-list-template-ids:400719310;}
@list l4:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l4:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:"Courier New";
mso-bidi-font-family:"Times New Roman";}
@list l4:level3
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l4:level4
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l4:level5
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l4:level6
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l4:level7
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l4:level8
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l4:level9
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l5
{mso-list-id:843908114;
mso-list-template-ids:-1243547606;}
@list l5:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l5:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:"Courier New";
mso-bidi-font-family:"Times New Roman";}
@list l5:level3
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l5:level4
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l5:level5
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l5:level6
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l5:level7
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l5:level8
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l5:level9
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l6
{mso-list-id:964771435;
mso-list-template-ids:-2000783132;}
@list l6:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l6:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:"Courier New";
mso-bidi-font-family:"Times New Roman";}
@list l6:level3
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l6:level4
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l6:level5
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l6:level6
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l6:level7
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l6:level8
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l6:level9
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l7
{mso-list-id:1176848642;
mso-list-template-ids:1223565722;}
@list l7:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l7:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:"Courier New";
mso-bidi-font-family:"Times New Roman";}
@list l7:level3
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l7:level4
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l7:level5
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l7:level6
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l7:level7
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l7:level8
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l7:level9
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l8
{mso-list-id:1311206220;
mso-list-template-ids:314224160;}
@list l8:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l8:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:"Courier New";
mso-bidi-font-family:"Times New Roman";}
@list l8:level3
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l8:level4
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l8:level5
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l8:level6
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l8:level7
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l8:level8
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l8:level9
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l9
{mso-list-id:1434012829;
mso-list-template-ids:-690447050;}
@list l9:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l9:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:"Courier New";
mso-bidi-font-family:"Times New Roman";}
@list l9:level3
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l9:level4
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l9:level5
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l9:level6
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l9:level7
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l9:level8
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l9:level9
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l10
{mso-list-id:2135564416;
mso-list-template-ids:728504136;}
@list l10:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l10:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:"Courier New";
mso-bidi-font-family:"Times New Roman";}
@list l10:level3
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l10:level4
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l10:level5
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l10:level6
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l10:level7
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l10:level8
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
@list l10:level9
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Wingdings;}
ol
{margin-bottom:0in;}
ul
{margin-bottom:0in;}
--></style><!--[if gte mso 9]><xml
<o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" /
</xml><![endif]--><!--[if gte mso
9]><xml
<o:shapelayout
v:ext=3D"edit"
<o:idmap v:ext=3D"edit"
data=3D"1" /
</o:shapelayout></xml><![endif]--
</head
<body bgcolor=3D"white"
lang=3D"EN-US" link=3D"blue" vlink=3D"purple"
<div class=3D"WordSection1"
<p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:"Ca=
libri","sans-serif";color:#1F497D">Hi
Vojtech,<o:p></o:p></s=
pan></p
<p
class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:"Ca=
libri","sans-serif";color:#1F497D"><o:p> </o:p></span><=
/p
<p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:"Ca=
libri","sans-serif";color:#1F497D">The patch is great
and ha=
s cleared up some questions I had about the implementation. I’ve been=
able to get the sample plugins working and waded through the
code changes, so feel like I have a good understanding of what was deliver=
ed. Thanks a lot for putting this all together. I do have a few questions a=
nd suggestions for you, though.<o:p></o:p></span></p
<p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:"Ca=
libri","sans-serif";color:#1F497D"><o:p> </o:p></span><=
/p
<p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:"Ca=
libri","sans-serif";color:#1F497D">Will there
eventually be =
a way to add one or more buttons to the context sensitive buttons and menus=
throughout the interface? For example, we’d like to allow
a button to provision a datastore when a data center, cluster, or host is =
selected. When the button is clicked, it would open a dialog with an iframe=
in which we would load our interface to perform the associated action. Som=
e contexts would have several buttons,
such as a storage domain (provision, resize, dedupe management, destroy) s=
o it would probably make sense for a drop down menu to be available as well=
so that the number of buttons above the table doesn’t get too clutte=
red. We’d also like to add these same
actions to the menus that popup when a contextual object is right clicked.=
<o:p></o:p></span></p
<p
class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:"Ca=
libri","sans-serif";color:#1F497D"><o:p> </o:p></span><=
/p
<p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:"Ca=
libri","sans-serif";color:#1F497D">If needed we can
help wor=
k on an implementation for the dialog popup plugin framework as we’d =
like to get it in relatively quickly so we can move forward on
the content side of our plugin.<o:p></o:p></span></p
<p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:"Ca=
libri","sans-serif";color:#1F497D"><o:p> </o:p></span><=
/p
<p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:"Ca=
libri","sans-serif";color:#1F497D">For the reverse
proxy, wo=
uld it be easier from a customer standpoint to just include a reverse proxy=
servlet such as this one? </span><a
href=3D"http://sourceforge.net/p=
rojects/j2ep/">http://sourceforge.net/projects/j2ep/</a
<o:p></o:p></p
<p
class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:"Ca=
libri","sans-serif";color:#1F497D">I’m just
thinking t=
hat setting up and managing a plugin for the HTTP server may be more comple=
x than including one internally that would be transparent to a
customer.<o:p></o:p></span></p
<p
class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:"Ca=
libri","sans-serif";color:#1F497D"><o:p> </o:p></span><=
/p
<p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:"Ca=
libri","sans-serif";color:#1F497D">Thanks,<o:p></o:p></span>=
</p
<p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:"Ca=
libri","sans-serif";color:#1F497D">Chris<o:p></o:p></span></=
p
<blockquote
style=3D"margin-top:5.0pt;margin-bottom:5.0pt"
<div
<p class=3D"MsoNormal"
style=3D"margin-bottom:12.0pt"><b>From:</b> Vojtech =
Szocs <<a
href=3D"mailto:vszocs@redhat.com">vszocs@redhat.com</a>><br=
<b>Date:</b> September 21, 2012 4:37:31 PM
EDT<br
<b>To:</b> engine-devel
<<a href=3D"mailto:engine-devel@ovirt.org">engin=
e-devel(a)ovirt.org</a>&gt;<br
<b>Subject:</b> <b>[Engine-devel] UI Plugins: PoC patch revision 5
is here<=
/b><o:p></o:p></p
</div
</blockquote
<blockquote
style=3D"margin-top:5.0pt;margin-bottom:5.0pt"
<div
<div
<p
class=3D"MsoNormal" style=3D"margin-bottom:12.0pt"><span
style=3D"color:=
black">Hi guys,<br
<br
it's
been a while but here comes the latest revision of UI Plugins proof-of=
-concept patch (please find it attached).<br
<br
This revision was originally meant
to focus solely on server-side component=
s of the plugin infrastructure. However, I ended up implementing all the ma=
jor concepts and ideas as discussed on engine-devel mailing list, impacting=
both client-side and server-side
parts of the plugin infrastructure. As a result, UI plugin infrastructure =
should be pretty much complete now, so we can focus on specific plugin API =
features in upcoming PoC revisions.<br
<br
There's a whole bunch of changes
and improvements in this revision, so I'll=
try to cover all the relevant parts step by step. If you have any comments=
, questions or ideas, please let me know!<br
<br
So here we go... (or if you just
want to get the patch, find the link at th=
e end of this message)<o:p></o:p></span></p
<div class=3D"MsoNormal"
align=3D"center" style=3D"text-align:center"><span=
style=3D"color:black"
<hr size=3D"2"
width=3D"100%" align=3D"center"
</span></div
<p
class=3D"MsoNormal"><span style=3D"color:black"><br
<strong>0. Added new Engine configuration
values</strong><b><br
</b><br
<u>UI plugin data
path</u> is represented by <em>ConfigValues.UIPluginDataP=
ath</em> enum option ("UIPluginDataPath" in
<i>vdc_options</i> table), and resolved relative to
<i>ConfigValues.DataDir=
</i> if possible. Following (default)
values:<o:p></o:p></span></p
<ul
type=3D"disc"
<li class=3D"MsoNormal"
style=3D"color:black;mso-margin-top-alt:auto;mso-ma=
rgin-bottom-alt:auto;mso-list:l0 level1 lfo1"
<i>UIPluginDataPath =3D
ui-plugins</i><o:p></o:p></li><li class=3D"MsoNorma=
l" style=3D"color:black;mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;=
mso-list:l0 level1 lfo1"
<i>DataDir =3D
/usr/share/ovirt-engine</i><o:p></o:p></li></ul
<p class=3D"MsoNormal"><span
style=3D"color:black">result in UI plugin data=
path: <i
/usr/share/ovirt-engine/ui-plugins</i><br
<br
<u>UI plugin config
path</u> is represented by <i>ConfigValues.UIPluginConf=
igPath</i> enum option ("UIPluginConfigPath" in
<i>vdc_options</i> table), and resolved relative to
<i>ConfigValues.ConfigD=
ir</i> if possible. Following (default)
values:<o:p></o:p></span></p
<ul
type=3D"disc"
<li class=3D"MsoNormal"
style=3D"color:black;mso-margin-top-alt:auto;mso-ma=
rgin-bottom-alt:auto;mso-list:l3 level1 lfo2"
<i>UIPluginConfigPath =3D
ui-plugins</i><o:p></o:p></li><li class=3D"MsoNor=
mal" style=3D"color:black;mso-margin-top-alt:auto;mso-margin-bottom-alt:aut=
o;mso-list:l3 level1 lfo2"
<i>ConfigDir =3D
/etc/ovirt-engine</i><o:p></o:p></li></ul
<p><span style=3D"color:black">result in
UI plugin config path: <i>/etc/ovi=
rt-engine/ui-plugins</i><o:p></o:p></span></p
<p class=3D"MsoNormal"><span
style=3D"color:black"><br
<b>1. Processing UI plugin data on the server<br
</b><br
<i>PluginDataManager</i> is the class responsible for reading,
validating a=
nd caching UI plugin descriptor/configuration data on the server (Engine). =
It has two main responsibilities:<o:p></o:p></span></p
<ul type=3D"disc"
<li
class=3D"MsoNormal" style=3D"color:black;mso-margin-top-alt:auto;mso-ma=
rgin-bottom-alt:auto;mso-list:l2 level1 lfo3"
return a
snapshot of currently valid plugin data (<i>getCurrentData</i> met=
hod)<o:p></o:p></li><li class=3D"MsoNormal"
style=3D"color:black;mso-margin=
-top-alt:auto;mso-margin-bottom-alt:auto;mso-list:l2 level1 lfo3"
reload plugin data from local file system if necessary
(<i>reloadData</i> m=
ethod)<o:p></o:p></li></ul
<p><span style=3D"color:black">The
<i>reloadData</i> method doesn't modify =
"live" plugin data directly. Instead, it creates a local working =
copy of current plugin data, updates this copy as it reads/validates plugin=
descriptor and configuration files, and attempts
to update "live" plugin data through conditional reference re-as=
signment (using <i
java.util.concurrent.atomic.AtomicReference.compareAndSet</i>
method).<o:p>=
</o:p></span></p
<p><span
style=3D"color:black"><o:p> </o:p></span></p
<p><span style=3D"color:black">In other
words, <i>reloadData</i> method mak=
es no attempts with regard to Java lock-based synchronization, in favor of =
dealing with "live" data through
<i>AtomicReference</i> (reference that involves atomic
<i>volatile</i> read=
s and writes):<o:p></o:p></span></p
<ul
type=3D"disc"
<li class=3D"MsoNormal"
style=3D"color:black;mso-margin-top-alt:auto;mso-ma=
rgin-bottom-alt:auto;mso-list:l4 level1 lfo4"
In the
best case, a thread will succeed in updating "live" data (=
<i>AtomicReference.compareAndSet</i> =3D=3D true), which means that
"l=
ive" data remained unchanged since this thread acquired a reference of=
current plugin data.<o:p></o:p></li><li
class=3D"MsoNormal" style=3D"color=
:black;mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;mso-list:l4 level=
1 lfo4"
In the worst case, a thread will NOT
succeed in updating "live" d=
ata (<i>AtomicReference.compareAndSet</i> =3D=3D false), which means that
&=
quot;live" data was already changed by another thread since this threa=
d acquired a reference of current plugin
data.<o:p></o:p></li></ul
<p><span style=3D"color:black">In my opinion, when dealing
with external re=
sources like the local file system, this is a good compromise between perfo=
rmance and up-to-date data. While we might not get "completely-up-to-d=
ate" data at the given point in time (<i>reloadData
+ getCurrentData</i>), we are guaranteed to get
"recently-up-to-d=
ate" and consistent data. In other words, the requirement of "com=
pletely-up-to-date" data would involve
<i>synchronized</i> statements that would hurt performance. In my (very hum=
ble) opinion, the benefit of having "completely-up-to-date" data,=
at the cost of reduced performance, is not really worth it, especially in =
our case when the user can just hit refresh
(F5) to reload WebAdmin and its plugin
data.<o:p></o:p></span></p
<p><span
style=3D"color:black"><o:p> </o:p></span></p
<p><u><span
style=3D"color:black">Plugin descriptor files</span></u><span
s=
tyle=3D"color:black"> are expected to be placed in UI plugin data path, for=
example:
<i>/usr/share/ovirt-engine/ui-plugins/foo.json</i><o:p></o:p></span></p
<p><span
style=3D"color:black"><o:p> </o:p></span></p
<p><span style=3D"color:black">Following
descriptor file attributes are imp=
lemented and recognized by the plugin
infrastructure:<o:p></o:p></span></p
<ul
type=3D"disc"
<li class=3D"MsoNormal"
style=3D"color:black;mso-margin-top-alt:auto;mso-ma=
rgin-bottom-alt:auto;mso-list:l9 level1 lfo5"
<i>name</i>: A name that uniquely identifies the plugin (required
attribute=
).<o:p></o:p></li><li class=3D"MsoNormal"
style=3D"color:black;mso-margin-t=
op-alt:auto;mso-margin-bottom-alt:auto;mso-list:l9 level1 lfo5"
<i>url</i>: URL of plugin host page that invokes
the plugin code (required =
attribute).<o:p></o:p></li><li class=3D"MsoNormal"
style=3D"color:black;mso=
-margin-top-alt:auto;mso-margin-bottom-alt:auto;mso-list:l9 level1 lfo5"
<i>config</i>: Default configuration object
associated with the plugin (opt=
ional attribute).<o:p></o:p></li><li class=3D"MsoNormal"
style=3D"color:bla=
ck;mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;mso-list:l9 level1 lf=
o5"
<i>resourcePath</i>:
Path to plugin static resources, relative to UI plugin=
data path (optional attribute). This is used when serving plugin files thr=
ough Engine
<i>PluginResourceServlet</i> (more on this
below).<o:p></o:p></li></ul
<p><u><span style=3D"color:black">Plugin configuration
files</span></u><spa=
n style=3D"color:black"> are expected to be placed in UI plugin config path=
, for example:
<i>/etc/engine/ui-plugins/foo-config.json</i><o:p></o:p></span></p
<p><span
style=3D"color:black"><o:p> </o:p></span></p
<p><span style=3D"color:black">Note that
plugin configuration files follow =
the "<descriptorFileName>-config.json"
convention.<o:p></o:=
p></span></p
<p><span
style=3D"color:black"><o:p> </o:p></span></p
<p><span style=3D"color:black">Following
configuration file attributes are =
implemented and recognized by the plugin
infrastructure:<o:p></o:p></span><=
/p
<ul type=3D"disc"
<li
class=3D"MsoNormal" style=3D"color:black;mso-margin-top-alt:auto;mso-ma=
rgin-bottom-alt:auto;mso-list:l8 level1 lfo6"
<i>config</i>: Custom configuration object associated with the plugin
(opti=
onal attribute). This overrides the default plugin descriptor configuration=
, if any.<o:p></o:p></li><li class=3D"MsoNormal"
style=3D"color:black;mso-m=
argin-top-alt:auto;mso-margin-bottom-alt:auto;mso-list:l8 level1 lfo6"
<i>enabled</i>: Indicates whether the plugin should
be loaded on WebAdmin s=
tartup (optional attribute). Default value is
'true'.<o:p></o:p></li><li cl=
ass=3D"MsoNormal"
style=3D"color:black;mso-margin-top-alt:auto;mso-margin-b=
ottom-alt:auto;mso-list:l8 level1 lfo6"
<i>order</i>: Defines the relative order in which the plugin will be
loaded=
on WebAdmin startup (optional attribute). Default value is
<i>Integer.MAX_VALUE</i> (lowest
order).<o:p></o:p></li></ul
<p><span style=3D"color:black">The concept of merging custom
configuration =
(<i>config</i> attribute in
<i>foo-config.json</i>), if any, on top of default configuration
(<i>config=
</i> attribute in
<i>foo.json</i>), if any, remains unchanged. This makes the plugin configur=
ation quite flexible - in my opinion, the added complexity of handling/merg=
ing such configuration is definitely worth the
effort.<o:p></o:p></span></p=
<p><span
style=3D"color:black"><o:p> </o:p></span></p
<p><span style=3D"color:black">The
<i>enabled</i> attribute is straight-for=
ward, allowing users to turn the given plugin off, if necessary. In future,=
users should still be able to load such plugins through WebAdmin GUI.<o:p>=
</o:p></span></p
<p><span
style=3D"color:black"><o:p> </o:p></span></p
<p><span style=3D"color:black">The
<i>order</i> attribute controls the orde=
r in which plugins are loaded on WebAdmin startup. Since plugin resources a=
re fetched asynchronously by the browser, this is basically a way of imposi=
ng some degree of determinism in the
"generally-non-deterministic" plugin environment, which is helpf=
ul when troubleshooting problems with multiple plugins. This attribute is a=
lso helpful due to file listing methods in
<i>java.io.File</i> giving no guarantees that files would be listed in any =
particular order (otherwise we could just go for the "NN-<descripto=
rFileName>.json" convention, with NN being the order
number).<o:p><=
/o:p></span></p
<p
class=3D"MsoNormal"><span style=3D"color:black"><br
<b>2. Modified behavior of
WebadminDynamicHostingServlet<br
</b><br
<i>WebadminDynamicHostingServlet</i> is the servlet used to serve
WebAdmin =
application host page (HTML page that bootstraps WebAdmin JavaScript code).=
<br
<br
In addition to its former behavior,
as part of handling the given request, =
<i>WebadminDynamicHostingServlet</i>:<o:p></o:p></span></p
<ul type=3D"disc"
<li
class=3D"MsoNormal" style=3D"color:black;mso-margin-top-alt:auto;mso-ma=
rgin-bottom-alt:auto;mso-list:l7 level1 lfo7"
reloads
descriptor/configuration data from local file system if necessary, =
and obtains a snapshot of currently valid plugin data (<i>PluginDataManager=
.reloadAndGetCurrentData</i>)<o:p></o:p></li><li
class=3D"MsoNormal" style=
=3D"color:black;mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;mso-list=
:l7 level1 lfo7"
embeds all plugin meta-data,
suitable for use in client-side plugin infrast=
ructure, into WebAdmin host page as "pluginDefinitions" JavaScrip=
t array
(<i>PluginDefinitions</i>)<o:p></o:p></li></ul
<p class=3D"MsoNormal"><span
style=3D"color:black">As a result, reloading U=
I plugin descriptor/configuration data is as simple as refreshing (F5) WebA=
dmin application in the browser (no need to restart Engine).<br
<br
<b>3. Added servlet for
serving plugin static resources<br
</b><br
<i>PluginResourceServlet</i> is the servlet used to serve UI plugin
static =
files (plugin host page, 3rd party JavaScript, etc.) from the local file sy=
stem.<br
<br
For
example, requesting URL:<o:p></o:p></span></p
<ul type=3D"disc"
<li
class=3D"MsoNormal" style=3D"color:black;mso-margin-top-alt:auto;mso-ma=
rgin-bottom-alt:auto;mso-list:l5 level1 lfo8"
<i><a
href=3D"http://%3cEngineManagerHost%3e:8700/webadmin/webadmin/plugin/=
foo/content/start.html">http://<EngineManagerHost>:8700/webadmin/weba=
dmin/plugin/foo/content/start.html</a></i><o:p></o:p></li></ul
<p><span style=3D"color:black">will send
the content of:<o:p></o:p></span><=
/p
<ul type=3D"disc"
<li
class=3D"MsoNormal" style=3D"color:black;mso-margin-top-alt:auto;mso-ma=
rgin-bottom-alt:auto;mso-list:l1 level1 lfo9"
<i>/usr/share/ovirt-engine/ui-plugins/<resourcePath>/content/start.ht=
ml</i><o:p></o:p></li></ul
<p><span style=3D"color:black">to the
client.<o:p></o:p></span></p
<p><span
style=3D"color:black"><o:p> </o:p></span></p
<p><span style=3D"color:black">As shown
in the above example:<o:p></o:p></s=
pan></p
<ul type=3D"disc"
<li class=3D"MsoNormal"
style=3D"color:black;mso-margin-top-alt:auto;mso-ma=
rgin-bottom-alt:auto;mso-list:l10 level1 lfo10"
<i>/webadmin/webadmin/plugin/</i> is the servlet root path for
<i>PluginRes=
ourceServlet</i><o:p></o:p></li><li
class=3D"MsoNormal" style=3D"color:blac=
k;mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;mso-list:l10 level1 lf=
o10"
in the extra path beyond the servlet
root path (<i>/foo/content/start.html<=
/i>):<o:p></o:p></li></ul
<ul
type=3D"disc"
<ul type=3D"circle"
<li class=3D"MsoNormal"
style=3D"color:black;mso-margin-top-alt:auto;mso-ma=
rgin-bottom-alt:auto;mso-list:l10 level2 lfo10"
<i>/foo</i> represents the name of the
plugin<o:p></o:p></li><li class=3D"M=
soNormal" style=3D"color:black;mso-margin-top-alt:auto;mso-margin-bottom-al=
t:auto;mso-list:l10 level2 lfo10"
<i>/content/start.html</i> represents the path to requested resource,
relat=
ive to "UIPluginDataPath /
<resourcePath>"<o:p></o:p></li><=
/ul
</ul
<p
class=3D"MsoNormal"><span style=3D"color:black">Note that
each plugin us=
ing <i>PluginResourceServlet</i> to serve its static files must declare non=
-empty
<i>resourcePath</i> attribute in within the plugin descriptor.<br
<br
Also note that
<i>PluginResourceServlet</i>, unlike <i>WebadminDynamicHosti=
ngServlet</i>, does NOT reload descriptor/configuration data from local fil=
e system as part of handling the given request. In other words, it's assume=
d that plugin data has already been
(re)loaded when serving WebAdmin application host page, with subsequent re=
quests to
<i>PluginResourceServlet</i> reading the current plugin information.<br
<br
Until we solve the cross-origin
issue in a clean way, <i>PluginResourceServ=
let</i> should be used to serve all plugin resources from local file system=
.<br
<br
<b>4. Plugin lifecycle
improved to deal with misbehaving plugins</b><br
<br
<i>PluginState</i> enum
has been modified to deal with plugins that allow u=
ncaught exceptions to escape from plugin event handler functions (e.g. &quo=
t;UiInit"):<o:p></o:p></span></p
<ul type=3D"disc"
<li
class=3D"MsoNormal" style=3D"color:black;mso-margin-top-alt:auto;mso-ma=
rgin-bottom-alt:auto;mso-list:l6 level1 lfo11"
removed
state <i>INITIALIZED</i><o:p></o:p></li><li
class=3D"MsoNormal" sty=
le=3D"color:black;mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;mso-li=
st:l6 level1 lfo11"
added state
<i>INITIALIZING</i>: The plugin is (currently) being initialize=
d by calling UiInit event handler function.<o:p></o:p></li><li
class=3D"Mso=
Normal" style=3D"color:black;mso-margin-top-alt:auto;mso-margin-bottom-alt:=
auto;mso-list:l6 level1 lfo11"
added
state <i>IN_USE</i>: Plugin's UiInit event handler function has compl=
eted successfully, we can now call other event handler functions as necessa=
ry. The plugin is in use now.<o:p></o:p></li><li
class=3D"MsoNormal" style=
=3D"color:black;mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;mso-list=
:l6 level1 lfo11"
added state
<i>FAILED</i>: An uncaught exception escaped while calling an e=
vent handler function, which indicates internal error within the plugin cod=
e. The plugin is removed from service.<o:p></o:p></li></ul
<p class=3D"MsoNormal"
style=3D"margin-bottom:12.0pt"><span style=3D"color:=
black">I've attached a simple state diagram that illustrates different stat=
es and transitions between them (green color is initial state, red color is=
end state).<br
<br
Uncaught
exceptions in plugin event handler functions will be caught and ha=
ndled by the plugin infrastructure. This prevents a misbehaving plugin from=
breaking WebAdmin application, since WebAdmin is the caller (initiator) of=
the function call. In such case,
the plugin will be removed from service.<br
<br
<b>Update on cross-origin
issue (consequence of same-origin policy)</b><br
<br
In order for the plugin to access
WebAdmin plugin API, plugin host page (e.=
g. <i
start.html</i>) must be served
from URL on same origin as Engine origin. Ot=
herwise, plugin code running in the context of an iframe'd host page will f=
ail to evaluate "parent.pluginApi" expression, with
"parent&=
quot; being top-level (WebAdmin) window, and "pluginApi"
being the global plugin API object exposed by WebAdmin.<br
<br
This is why
<i>PluginResourceServlet</i>, available on Engine origin, shoul=
d be used to serve all plugin resources from local file system.<br
<br
There's only one issue that
remains to be solved: cross-origin "plugin=
vs. remote service" communication, with "remote service" be=
ing anything other than Engine (REST API). In future, we'll address this wi=
th Apache reverse proxy configuration, so that users
can configure Apache server (placed in front of Engine JBoss AS) to put ar=
bitrary (local or remote non-Engine) services on same origin. However, this=
requires a change in current Apache configuration. Until then, users can m=
anually edit the Engine Apache configuration
file
(<i>/etc/httpd/conf.d/ovirt-engine.conf</i>).<o:p></o:p></span></p
<div class=3D"MsoNormal"
align=3D"center" style=3D"text-align:center"><span=
style=3D"color:black"
<hr size=3D"2"
width=3D"100%" align=3D"center"
</span></div
<p class=3D"MsoNormal"
style=3D"margin-bottom:12.0pt"><span style=3D"color:=
black"><br
I've attached some sample plugin
files for you to experiment with. Instead =
of attaching actual patch file (92 kB) to this email, I've submitted the pa=
tch to oVirt Gerrit:
<a
href=3D"http://gerrit.ovirt.org/8120">http://gerrit.ovirt.or...
r
<br
Let me know what you
think!<br
<br
Cheers,<br
Vojtech<o:p></o:p></span></p
</div
</div
</blockquote
<blockquote style=3D"margin-top:5.0pt;margin-bottom:5.0pt"
<div
<p
class=3D"MsoNormal"><ui-plugin-sample-files.tar.gz><o:p></o:p></p
</div
</blockquote
<blockquote
style=3D"margin-top:5.0pt;margin-bottom:5.0pt"
<div
<p
class=3D"MsoNormal"><ui-plugin-lifecycle.png><o:p></o:p></p
</div
</blockquote
<blockquote
style=3D"margin-top:5.0pt;margin-bottom:5.0pt"
<div
<p
class=3D"MsoNormal">_______________________________________________<br
Engine-devel mailing list<br
<a
href=3D"mailto:Engine-devel@ovirt.org">Engine-devel@ovirt.org</a><br
<a
href=3D"http://lists.ovirt.org/mailman/listinfo/engine-devel"&g...
ts.ovirt.org/mailman/listinfo/engine-devel</a><o:p></o:p&g...
</div
</blockquote
</div
</body
</html
--_000_D290AD8432118048947689BA3AE8A9B3E47B82SACEXCMBX04PRDhqn_--