[Engine-devel] UI Plugins: PoC patch revision 6 now available

Vojtech Szocs vszocs at redhat.com
Wed Oct 24 18:24:16 UTC 2012


Hi Oved,

thanks for sharing details on REST API session support! With this feature implemented, we could extend WebAdmin UI login procedure with REST API login, retrieving session ID from the cookie and providing it to UI plugins through the plugin API. We could also perform REST API logout upon WebAdmin UI logout. I see that [http://wiki.ovirt.org/wiki/Features/RESTSessionManagement] is currently in design phase, is it close to being implemented or will it take some more time to be available?

Alternatively, (without REST API session support) we could also do REST API login/logout as part of each REST API call; but since UI plugins might want to delegate the responsibility to make the actual REST API call to other (e.g. server-side) components, we'd have to expose WebAdmin UI login credentials to each plugin (I'm not sure if this is a good idea).

Regards,
Vojtech


----- Original Message -----
From: "Oved Ourfalli" <ovedo at redhat.com>
To: "Itamar Heim" <iheim at redhat.com>
Cc: "engine-devel" <engine-devel at ovirt.org>, "Christopher Morrissey" <Christopher.Morrissey at netapp.com>
Sent: Wednesday, October 24, 2012 10:46:50 AM
Subject: Re: [Engine-devel] UI Plugins: PoC patch revision 6 now available



----- Original Message -----
> From: "Itamar Heim" <iheim at redhat.com>
> To: "Christopher Morrissey" <Christopher.Morrissey at netapp.com>
> Cc: "engine-devel" <engine-devel at ovirt.org>
> Sent: Tuesday, October 23, 2012 8:49:02 AM
> Subject: Re: [Engine-devel] UI Plugins: PoC patch revision 6 now available
> 
> On 10/22/2012 05:25 PM, Morrissey, Christopher wrote:
> > Hi Vojtech,
> >
> > Thanks again for the delivery of the patch. For revision 7, do you
> > have
> > a list of content? I had previously indicated I could work on
> > adding the
> > plugin API to launch a dialog, but hadn’t been able to get started
> > on it
> > until now. I wanted to see if you by chance were already working on
> > it
> > or if you were planning to deliver that yourself in the next
> > revision?
> >
> > A couple of other items we are looking for are the ability to add
> > tasks
> > for execution and get access to the session ID or some kind of
> > authentication token so that we can make calls from our server into
> > the
> > REST API. I’m not very familiar yet with the REST API so I’m not
> > sure
> > what authentication methods are available and which would be best.
> 
> Oved - I remember we discussed UI plugins should be able to use same
> logic as jasper reports for getting a session identifier for using
> the
> REST API.
> do you remember the details on this one?
> 

Yes.
What we planned to do is different than the jasper reports solution.
We planned to take the same session ID that the webadmin has, and pass it over to the REST API as session ID (as we added the REST session support - http://wiki.ovirt.org/wiki/Features/RESTSessionManagement).

The problem is that while previous versions of jboss allowed using the same session in two different webapps, it is no longer possible in jboss AS7,
so what we would need to do is to login once to the REST API with the credentials as used in webadmin, get the session ID from the cookie, and save it for further requests.

> Thanks,
>     Itamar
> 
> >
> > -Chris
> >
> > *From:*engine-devel-bounces at ovirt.org
> > [mailto:engine-devel-bounces at ovirt.org] *On Behalf Of *Vojtech
> > Szocs
> > *Sent:* Thursday, October 18, 2012 10:49 AM
> > *To:* engine-devel
> > *Subject:* [Engine-devel] UI Plugins: PoC patch revision 6 now
> > available
> >
> > Hi guys,
> >
> > the latest revision of UI Plugins proof-of-concept patch is now
> > available for you to experiment with. You can download the patch
> > from
> > oVirt Gerrit at http://gerrit.ovirt.org/#/c/8120/2 (patch set 2).
> >
> > Please read on to learn what's new in this revision. If you have
> > any
> > comments, questions or ideas, please let me know!
> >
> > ------------------------------------------------------------------------
> >
> >
> > *0. UI plugin path information resolved using local Engine
> > configuration**
> > *
> > Server-side UI plugin infrastructure now uses local
> > (machine-specific)
> > Engine configuration instead of global (/vdc_options/ database
> > table)
> > Engine configuration:
> >
> >   * Previously, path information was resolved through
> >     org.ovirt.engine.core.common.config.Config class - Engine
> >     configuration values were retrieved from /vdc_options/ database
> >     table.
> >   * Currently, path information is resolved through
> >     org.ovirt.engine.core.utils.LocalConfig class - Engine
> >     configuration
> >     values are retrieved from local file system.
> >
> > In case you're not working with oVirt Engine through RPM package
> > system,
> > e.g. you have a local development environment set up and you build
> > and
> > deploy oVirt Engine through Maven, please follow these steps:
> >
> > a. Copy default Engine configuration into
> > /usr/share/*ovirt-engine*/conf
> >
> > # mkdir -p /usr/share/ovirt-engine/conf
> > # cp <OVIRT_HOME>/backend/manager/conf/engine.conf.defaults
> > /usr/share/ovirt-engine/conf/engine.conf.defaults
> >
> >
> > b. If necessary, copy UI plugin data files from
> > /usr/share/engine/ui-plugins to
> > /usr/share/*ovirt-engine*/ui-plugins
> >
> > c. If necessary, copy UI plugin config files from
> > /etc/engine/ui-plugins
> > to /etc/*ovirt-engine*/ui-plugins
> >
> > d, In case you want to override the default Engine configuration,
> > put
> > your custom property file into /etc/sysconfig/ovirt-engine
> >
> > The reason behind this change is that path information for UI
> > plugin
> > data and configuration is typically machine-specific, and should be
> > customizable per machine through Engine local configuration.
> >
> > ------------------------------------------------------------------------
> >
> >
> > *1. New plugin API function: addMainTabActionButton
> > *
> > The "addMainTabActionButton" API adds custom context-sensitive
> > button to
> > the given main tab's data grid, along with corresponding data grid
> > context menu item.
> >
> > addMainTabActionButton(entityTypeName, label,
> > actionButtonInterface)
> >
> > /entityTypeName/ indicates which main tab's data grid the button
> > should
> > be added to, according to the entity type associated with the main
> > tab./entityTypeName/ values are strings reflecting
> > org.ovirt.engine.ui.webadmin.plugin.entityEntityType enum members.
> > Following /entityTypeName/ values are currently supported (values
> > are
> > case-sensitive): "DataCenter", "Cluster", "Host", "Storage",
> > "Disk",
> > "VirtualMachine", "Template".
> >
> > Note: "Pool" value is currently not supported, because of
> > org.ovirt.engine.core.common.businessentities.vm_pools entity not
> > implementing the BusinessEntity interface, not sure why though.
> > Maybe we
> > should switch from BusinessEntity to IVdcQueryable interface and
> > always
> > cast getQueryableId method result value to Guid?
> >
> > /label/ is the title displayed on the button/.
> > /
> > /actionButtonInterface/ represents an object that "implements the
> > button
> > interface" by declaring its functions: /onClick/, /isEnabled/,
> > /isAccessible/. All functions of /actionButtonInterface/ receive
> > currently selected item(s) as function arguments.
> >
> > Let's take a closer look at the concept behind
> > /actionButtonInterface/.
> > In traditional class-based object-oriented languages, such as Java,
> > interface is an abstract type that contains method declarations
> > without
> > an implementation. A class that implements the given interface must
> > implement all methods declared by that interface (unless it's an
> > abstract class, but this isn't relevant in our case).
> >
> > In contrast with traditional class-based object-oriented languages,
> > JavaScript supports OOP through prototype-based programming model
> > (https://developer.mozilla.org/en-US/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript).
> > At the same time, JavaScript language is dynamically-typed and
> > therefore
> > doesn't support traditional concept of interface in OOP, it uses
> > "duck
> > typing" technique instead
> > (http://en.wikipedia.org/wiki/Duck_typing).
> >
> > The simplest way to provide an object that "implements the given
> > interface" in JavaScript is to use "duck typing" technique:
> > providing an
> > object that contains well-known functions. In UI plugin
> > infrastructure,
> > I call this concept "interface object", represented by
> > org.ovirt.engine.ui.webadmin.plugin.jsni.JsInterfaceObject class.
> > Unlike
> > the traditional concept of interface abstract type in
> > object-oriented
> > languages, an "interface object" _does not necessarily have to
> > declare
> > all functions of the given interface_ in order to "implement" such
> > interface. In fact, an empty object can be used as a valid
> > "interface
> > object". Missing functions will be simply treated as empty (no-op)
> > functions. Furthermore, an "interface object" can "implement"
> > multiple
> > interfaces by declaring functions of those interfaces (interface
> > composition).
> >
> > Getting back to "addMainTabActionButton" API, here's a sample code
> > that
> > adds new button to "Host" main tab data grid, as part of UiInit
> > event
> > handler function:
> >
> > UiInit: *function*() {
> >      api.addMainTabActionButton('Host', 'Single-Host Action',
> >
> >          // Action button interface object
> >          // All functions receive currently selected item(s) as
> >          function
> > arguments
> >          {
> >
> >              // Called when the user clicks the button
> > onClick: *function*() {
> >                  // Calling 'arguments[0]' is safe, because
> >                  onClick()
> > can be called
> >                  // only when exactly one item is currently
> >                  selected in
> > the data grid
> >                  window.alert('Selected host entity ID = ' +
> > arguments[0].entityId);
> >              },
> >
> >              // Returning 'true' means the button is enabled
> >              (clickable)
> >              // Returning 'false' means the button is disabled
> > (non-clickable)
> >              // Default value = 'true'
> > isEnabled: *function*() {
> >                  // Enable button only when exactly one item is
> >                  selected
> > *return*arguments.length == 1;
> >              },
> >
> >              // Returning 'true' means the button is visible
> >              // Returning 'false' means the button is hidden
> >              // Default value = 'true'
> > isAccessible: *function*() {
> >                  // Always show the button in the corresponding
> >                  data grid
> > *return**true*;
> >              }
> >
> >          }
> >
> >      );
> > }
> >
> > As mentioned above, all functions of an interface object are
> > optional.
> > For functions expecting return value, default value is defined by
> > UI
> > plugin infrastructure. For example:
> >
> >   * onClick - no default value (no return value expected)
> >   * isEnabled / isAccessible - default value "true" (boolean return
> >     value expected)
> >
> > Note: UI plugin infrastructure checks the actual return value type,
> > and
> > uses default value in case the function returned something of wrong
> > (unexpected) type.
> >
> >
> > In the example above, "currently selected item(s)" maps to
> > JSON-like
> > representations of business entities currently selected in the
> > corresponding data grid. For now, the entity representation is
> > quite
> > simple and same for all entity types:
> >
> > { entityId: "[BusinessEntityGuidAsString]" }
> >
> > In future, we will create specific JSON-like representations for
> > specific business entities, in compliance with Engine REST API
> > entity
> > structure.
> >
> > For a more extensive example of using "addMainTabActionButton" API,
> > please see the attached "addMainTabActionButton.html.example" file.
> >
> > ------------------------------------------------------------------------
> >
> >
> > *2. Improved plugin API function: addMainTab
> > *
> > The "addMainTab" API was improved to address following issues:
> >
> >   * "addMainTab" can now be called at any moment during UI plugin
> >     runtime, given that the plugin is allowed invoke plugin API
> >     functions (plugin is either INITIALIZING or IN_USE).
> >     Previously, "addMainTab" worked reliably only when called from
> >     within UiInit event handler function.
> >     Currently, it's possible to call "addMainTab" at any moment,
> >     e.g.
> >     from within some other event handler function (after UiInit has
> >     completed).
> >
> >   * "addMainTab" now retains "active" tab (highlighted tab GUI).
> >     "addMainTab" works by adding new tab component (GWTP presenter
> >     proxy) and refreshing main tab panel GUI by removing all
> >     related
> >     tabs and re-adding them again.
> >     This logic is handled by
> >     org.ovirt.engine.ui.common.presenter.DynamicTabContainerPresenter
> >     class, which makes sure that "active" tab is retained even
> >     after
> >     main tab panel was refreshed.
> >
> > Furthermore, custom main tab implementation now displays the
> > content of
> > the given URL through HTML iframe element.
> >
> > ------------------------------------------------------------------------
> >
> >
> > *3. Improved native JavaScript function handling* (GWT JSNI)
> >
> > This patch introduces
> > org.ovirt.engine.ui.webadmin.plugin.jsni.JsFunction and
> > org.ovirt.engine.ui.webadmin.plugin.jsni.JsFunctionResultHelper
> > classes
> > providing Java abstraction for invoking native JavaScript
> > functions.
> > These classes follow the general contract of "interface object" as
> > mentioned above.
> >
> > JsFunctionResultHelper is particularly useful when dealing with
> > functions which are expected to return value of a certain type. Too
> > bad
> > standard GWT JSNI classes don't provide such abstraction for
> > working
> > with native functions out-of-the-box...
> >
> > ------------------------------------------------------------------------
> >
> >
> > *4. ActionPanel and ActionTable type hierarchy refactoring*
> > (related to
> > "addMainTabActionButton" API)*
> > *
> > Previously, AbstractActionPanel and AbstractActionTable classes
> > didn't
> > implement any reasonable interface that would allow other
> > components
> > (client-side UI plugin infrastructure) to depend on their
> > functionality
> > in a loosely-coupled manner. This would make code that implements
> > "addMainTabActionButton" API "ugly": main tab view interface would
> > have
> > to reference AbstractActionTable class directly. In MVP design
> > pattern,
> > view interface should avoid referencing specific GWT Widget classes
> > directly.
> >
> > This patch introduces new interfaces for ActionPanel and
> > ActionTable
> > components while eliminating code redundancy (duplicate or
> > unnecessary
> > code).
> >
> > ------------------------------------------------------------------------
> >
> >
> > *5. ActionPanel type hierarchy refactoring* (related to
> > "addMainTab" API)
> >
> > Since
> > org.ovirt.engine.ui.common.presenter.DynamicTabContainerPresenter
> > defines new DynamicTabPanel interface that extends standard GWTP
> > TabPanel interface, some refactoring had to be done in related
> > ActionPanel classes.
> >
> > This patch makes sure that both
> > org.ovirt.engine.ui.common.widget.tab.AbstractTabPanel (widget) and
> > org.ovirt.engine.ui.common.view.AbstractTabPanelView (view) support
> > DynamicTabPanel interface.
> >
> > Note that for now, only main tab panel
> > (org.ovirt.engine.ui.webadmin.section.main.presenter.MainTabPanelPresenter)
> > supports dynamic tabs within its view.
> >
> > ------------------------------------------------------------------------
> >
> >
> > *Where is addSubTab API function?*
> >
> > Implementing "addSubTab" API requires some more changes, and I
> > didn't
> > want to delay this PoC patch just because of it...
> >
> > Here's a sample code that illustrates proposed "addSubTab" API
> > usage:
> >
> > UiInit: *function*() {
> >      api.addSubTab('Host', // entityTypeName
> >          'Custom Host Sub Tab', // label
> >          'custom-host-sub-tab', // historyToken
> >          'http://www.ovirt.org/', // contentUrl
> >
> > // Sub tab interface object
> >          // All functions receive currently selected item(s)
> >          // within the main tab data grid as function arguments
> >          {
> >
> >              // Returning 'true' means the sub tab is visible
> >              // Returning 'false' means the sub tab is hidden
> >              // Default value = 'true'
> > isAccessible: *function*() {
> > *return*arguments.length == 1 && arguments[0].entityId ==
> > '<MyHostEntityId>';
> >              }
> >
> >          }
> >
> >      );
> > }
> >
> > As part of "addSubTab" API implementation, I'll refactor custom
> > main tab
> > components, in order to use one "tab type" for both main and sub
> > tabs.
> >
> > Currently, we have one (and only one) "tab type" - a tab that shows
> > content of the given URL through HTML iframe element.
> >
> > We could also create new "tab types", e.g. form-based tab that
> > shows
> > key/value pairs (IMHO this could be quite useful for custom sub
> > tabs).
> >
> > ------------------------------------------------------------------------
> >
> >
> > Let me know what you think!
> >
> > Cheers,
> > Vojtech
> >
> >
> >
> > _______________________________________________
> > Engine-devel mailing list
> > Engine-devel at ovirt.org
> > http://lists.ovirt.org/mailman/listinfo/engine-devel
> >
> 
> 
> _______________________________________________
> Engine-devel mailing list
> Engine-devel at ovirt.org
> http://lists.ovirt.org/mailman/listinfo/engine-devel
> 
_______________________________________________
Engine-devel mailing list
Engine-devel at ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-devel



More information about the Devel mailing list