[Freeipa-devel] Web UI refactoring effort ready for review

Petr Vobornik pvoborni at redhat.com
Mon Apr 22 16:54:54 UTC 2013


Hello,

Web UI refactoring is ready for review.

Code is available at usual location: 
git://fedorapeople.org/~pvoborni/freeipa.git branch menu

I would like to ask Endi and Ana to comment the design of 
Builder/Registry/Global registry/Providers.

I will work with Ana and Varun on testing the stuff to avoid regressions.

There are some remaining minor parts to be implemented (described 
below). They shouldn't block the review.

The whole effort has 124 commits. They reflect the way how it was 
developed. Many of them could be squashed (mainly the ones with 
'Builder:' prefix. Some, mostly fixes of issues found later, might be 
quite hard to squash. We should decide on some reasonable compromise to 
avoid spending a lot of time on squashing.

Later this week I'll create design page for #3235 and update the one for 
#3236. The doc on http://pvoborni.fedorapeople.org/doc/ should also be 
updated to reflect new builder capabilities.

Following text describes the work which was done since the last review 
(starting with 1440996d9466921178598289579f5dad031e4e54 Metadata and 
text providers commit)

Main refactoring themes
-----------------------
1. Menu + application controller refactoring
Was described in previous mails. #3235

2. Plugins support
Also discussed.  #3236

3. Make definitions of specification objects (specs) of entities, 
facets, widgets modifiable by plugins. No ticket, but supports both 
#3535 and #3236.

a) Main complication is specification of objects not yet retrieved - 
mostly metadata and messages.

Data providers were created to solve the issue. Providers expect string 
as an input and return related data. Provider logic is implemented in 
./_base/Provider. Providers can be nestable so one provider can serve as 
access point for multiple provider.

One should use ./_base/metadata_provider for obtaining metadata and 
./text for strings. ./text also searches in metadata by using 
metadata_provider.

All instances of IPA.metadata and IPA.messages were replaced by provider 
definitions.

b) Second big issue was build of objects. Entities and facets have 
complex build logic. It can be simplified into three steps:
     1) modifications of spec
     2) creation of object and class inheritance
     3) init logic

Most of the ideas were implemented in previous part but the builder 
alone got new features to meet all requirements. The main features are 
post_ops and pre_ops.

Pre_ops are operations, defined as functions, objects or diff objects 
which are executed/applied before creation of instance (calling 
ctor/factory). Their purpose is to modify spec object. They are similar 
to pre callbacks in ipa framework.

Post_ops are operations executed after executing factory/constructor. 
Their purpose is to contain object's initialization logic.

New Builder features:
* distinguishes between framework(built) object and spec. Returns input 
if its not a spec. Allows to specify spec or built object in spec.
* mass build when supplied array of specs
* specify global pre/post_ops
* factory, ctor defaults
* support of two modes when spec is a simple string: 'type', 'property'. 
Default is 'type'. 'type' means that spec is a name of object type and 
builder should search construct registry. 'property' serves for 
simplifying spec eg: '{ name: 'uid' } -> 'uid'. This means that it 
heavily rely on builders defaults to supply correct factory/ctor.
* overrides: allow to override builder defaults (factory, ctor, 
post_ops, pre_ops)
* context - object supplied by caller which is passed to pre_ops and 
post_ops. Allows to define containers.


New Construct registry features:
* post_ops and pre_ops for types

c) Web UI has several object types: entities, facets, widgets, fields, 
actions, validators, entity policies, facet policies. Each object type 
requires its builder, construct registry and some also singleton 
registry. Two umbrella pseudo-registries were created to avoid creating 
twice as many modules and also to allow redefinition of the registries: 
./reg and ./builder.

./reg is a registry of construct registries or singleton registries. 
Difference between normal registry is that one can access its registries 
directly.

./builder is a registry of builders. Each object type may have its own 
builder with different defaults, pre_ops, post_ops and construct 
registry. Construct registry is usually the one registered in ./reg.
Builder also serves as general build interface so one don't have to 
obtain the builder first:
       builder.build(object_type, spec, context, overrides)
Builder can also be used for building objects without registered builders:
	builder.build('', spec, context, overrides)

All modules should register their objects at registration phase. It 
defines a structure so one can expect when objects are registered and 
also one can do some changes to the spec in module before it is registered.

Plugins containing and entity should have the spec prepared in a module 
property. So modules don't have to specify the object statically but 
they have to make sure that it will be static when the module is 
requested by other module (plugin).

d) Modification of spec by diff object. Implemented in ./_base/Spec_mod 
module. Applied by builder. Was not thoroughly tested. One variant of 
pre_op. I would like to improve the concept in a future.


Know problems & remaining work
------------------------------
1. Change generation of plugin index to dynamical instead of rpm-post

2. Incorrect behavior (enabled buttons) of rule table when 'rule 
applies to anyone' selected.

3. delete ./facets module
Use ./reg an ./builder instead. Incorporate it into router to support 
standalone facets.

Design Questions
----------------
1. Move ./_base/metadata_provider to ./metadata?
Might simplify stuff.

2. Move actions/buttons spec from factories to pre_ops associated with 
the factories.

Example of stuff to be moved (search.js):
      spec.actions = spec.actions || [];
      spec.actions.unshift(
          'refresh',
          'batch_remove',
          'add');

It may simplify/allow removal of those items in spec or pre_ops of child 
factories. Currently there is no way how to intercept them.

---

I hope that I didn't forget anything important.

Thank you,
-- 
Petr Vobornik




More information about the Freeipa-devel mailing list