Assemblies


See the Glossary for definitions of terms used here.

Assembly Details

When you install an assembly containing applications into a home directory, the app automatically is accessible via the home name plus the application name within the assembly.  Mappings are searched first, then direct searching  is tried, if it is turned on.   If you do not map a URI to the app, the URI would be
    /{homedir-name}/{assembly-name}/apps/{appname}
unless you turn off direct searching of applications.  For a production server, you would want direct searching turned off, and only allow applications that were explicitly mapped in the web-apps file to be accessed.  Note that none of these scenarios result in files being directly accessible via the URL.  These just define search locations for the Application to find its base directory.  The Application still uses a ResourceManager to load all files.


(Map URI's to apps within assemblies)
web-apps.xml
/demo
/homes/acme/com-acme-apps-7/apps/demo
/catalog
/homes/acme/com-acme-apps-7/apps/catalog
/dynamide/ide
/homes/dynamide/com-dynamide-apps-60/apps/ide

The above mapping behaves differently in Self-Hosted Mode and Hosted Mode:
Without the mapping, the following default URL obtains:
Of course, in Self-Hosted Mode, you can name the accounts anything, such as /dev, /qa, and so on.
For example
The com-dynamide-apps assembly contains the following assembly.xml file:

assembly.xml
basename
com-dynamide-apps
interface
1
build
59
imports
com-dynamide-lib,1,59+

...
monitor
com.dynamide.AssemblyMonitor
To save some implementation time, and some figuring out of fancy parsing, just implement the version sequences as child elements:
    <imports>
<import>
<basename>com-dynamide-lib</basename>
<interface>
<version>1</version>
</interface>
<builds>
<version>1</version>
<version>3</version>
<version>*</version>
<version>5</version>
<version>7</version>
<version>*</version>
</builds>
</import>
<imports>
Implies builds versions 1, 3-5, 7+
The default for builds is *.
It is questionable whether to allow interface numbers to use open-ended ranges. And open ended build ranges may also be lax. If you allow them, make a utility that reports on all apps that are running with future versions of imports. It should also show you which apps need to be tested because new interfaces are available. It should then let you upgrade to the new interface.

Note that the assembly has a basename and a build number.  These two items determine the globally unique identifier for this assembly.  The interface number is for clients that wish to bind to this library as long as the interface doesn't change.  The interface is the sum of all Objects and API calls that the interface makes visible (public).  Typically, changing method signatures or removing Objects or API calls would mandate a new interface number.  Dynamide doesn't check the interface, the library author is responsible for determining if two versions have the same effective interface, since the interface to a Dynamide assembly includes widgets, pagetypes, editors, designers, properties, events, Javascript functions, Java objects, and Java methods,  mosts of which cannot be validated with a compiler.

An import can be based on a basename, an interface version string, and a build version string.  Version strings can be absolute numbers, ranges, or open-ended ranges.  "3" means just version 3, "1-2" means version 1 through 2, "1+" means all versions later than 1.

An Assembly can contain a web-apps.xml file.  This file can be merged into the master web-apps.xml file.  There is no implementation for this yet, but the rule would be to allow URI's if they don't cause conflicts.
I think that the web-apps should be an element inside an assembly.xml file
An Assembly can be zipped up into a zip file, in order to move it to another host.  The Assembly directory name should not be included in the path of the included files. That is, within the zip file, the root directory should be the assembly directory.  The name of the zip file will be used to extract it to a directory with that name.  
Here's an example:

Directory: Zip file:

com.acme-catalog-8.zip
Filename
Path
assembly.xml
/
application.xml
/apps/app1
page1.xml
/apps/app1
app1.css
/apps/app1/resources/css


However, the name that counts is the basename in the assembly.xml file, together with the interface and build version numbers. To avoid confusion with Java package names,  make the basename using dashes, using all  lower-case letters, and include library name plus the build number.  Use a new, single integer build number for each build or assembly release, not major-minor-build-bugfix.  Bugfixes back in the realease series would have to have a higher build number for Dynamide to be able to decide to use it preferentially.  If you change the functionality, consider using a new interface number.

For example, Dynamide distributes com-dynamide-apps-59, which is all the applications as of build 59.  The widgets and other shareable resources are assembled into com-dynamide-lib-59.  The interface version number is specified in the assembly.xml file, so is not used in the assembly zip file name.  When the assembly is registered, Dynamide will use the values in the assembly.xml file, not the assembly zip file or directory name.  Those names are just to avoid conflict with other assemblies installed on the same host.

Applications define imports of Assemblies.  Assemblies can thus import multiple versions of the same Assembly.  The search path is per-Application, not per-Assembly.

Widgets and Applications can require Java interfaces, and assembly interface numbers.  The Application decides which Java interface or assembly interface version to bind to.  The widget declares that it "requires" a certain interface level.  If this level is not available, the widget refuses to load, and logs an ERROR.  This can be captured with automated testing.  Test mode is turned on so that widgets don't  open DB connections, etc., and all pages and all widgets are loaded and rendered. Errors and Warnings can be inspected.  For a successful test, ERROR count must be zero, and WARNING count should be zero.

Imports are specified in the Dynamide objects.

An application specifies imports in application.xml:
Here's an example from an application that imports com-dynamide-lib, interface version 1, and any builds including build 59 or higher.  It also imports com-acme-apps interface version 1, all builds.

    <application>
<properties>
<property name='imports'>
<dataType>com.dynamide.datatypes.Enumeration</dataType>
<value>
<enumeration override="true">
<item dataType="com.dynamide.datatypes.Version">
<basename>com-dynamide-lib</basename>
<interface>1</interface>
<build>59+</build>
</item>
<item>
<basename>com-acme-apps</basename>
<interface>1</interface>
<build>1+</build>
</item>
</enumeration>
</value>
<helpTip>items: a list of Strings.</helpTip>
</property>
... <properties> ... </application>

Imports affect the search path for resources.  Each application has its own instance of the ResourceManager, which searches for resources.  The ResourceManager has a list of places to search, similar to a search path in a command shell.  The search order is:

  1. relative to the application directory
  2. relative to the assembly directory
  3. relative to the imported assembly directories, in the order that assemblies are imported
Assemblies may be imported from an account home directory, or from the shared assembly directory, called $RESOURCE_ROOT/assemblies/.

Finally, Dynamide discovers where the root of the assemblies is and how to handle virtual server host names by how Resin is configured with this file:

resin.conf
names virtual server mappings
names Dynamide Root directory


Use Cases


Directories in Dynamide application server environment

Here is the layout of Dynamide's resources, including your installed assemblies.

All searches and named resources are relative to "resources".  Since there are multiple "resources" directories, they are searched in order as defined  by the ResourceManager's resource path.  Normally, this is {assembly}/apps/{app}/resources/, {assembly}/resources, {imported-assembly}/resources, {imported-assembly}/resources, ... and so on through the list of imported-assemblies.  In this scheme, apps in imported assemblies cannot be searched for resources.  Instead, you must load up the app within your assembly or the imported assembly, and delegate to it.

Note: user "joe" cannot access files from assemblies in the home directory of user "acme", even though Joe works for acme.  In hosted mode, Joe must obtain copies of assemblies and place them in /joe/assemblies/ , or arrange to have them installed in /assemblies.  To protect access to assemblies, write a monitor class and name it in the assembly.xml file in the "monitor" field.  The monitor can accept, deny, and log access.  Without a monitor, in Hosted Mode, putting assemblies in /assemblies is less contained, since other organizations have access to the assemblies.

Other users can access applications installed in /homes/dynamide, but not via the filesystem, only through URLs, such as  /dynamide/ide.  The apps in dynamide can access files anywhere in the tree because the SecurityManager installed by the ResourceManager specifically allows it.


Mapping URI's to Applications (web-apps.xml)


A URI is the path portion of a URL. For example, given the URL
        http://myhost:80/foo/bar?param=value
the URI is
        /foo/bar

In the web-apps.xml file you describe the apps that are in this assembly, and what URI's should be associated with them.  If you are running in "Hosted Mode", the URI's will be prepended with the account name.  For example, account "acme" with an app named "demo",
        /demo
will become
        /~acme/demo
in hosted mode.

Also, if you are running in either Hosted Mode or Self-Hosted Mode, a user's sandbox will also be accessible by using this URI naming scheme.  For example, if user "joe" has the same application installed in an assembly in his home directory, then this application is available via:
        /~joe/demo

In Self-Hosted Mode, the administrator has permission to alter the global web-apps.xml file, and so can remap any URI's.

The context for URI mapping is chained.  The root web-apps.xml is read first, then all the web-apps.xml files from the account home dirs, then from each assembly.  Conflicts are dissallowed and reported.  ".." and  path.separator are not allowed.  All APPNAME values are taken to be relative to the directory with web-apps.xml.

Note: still to be worked out -- The WebAppEntry class in memory fills in the assembly name and home name, based on where it picked up the web-apps.xml file. This object is in the Dynamide context. But the contexts are searched in order, so a global web-apps.xml that specifies that a url maps to a certain assembly wins over the same url found in any assembly, since the global one specifies the assembly.
web-apps.xml files within assemblies don't use the ASSEMBLY element, or the HOME element. Those elements are used or updated when the assembly is installed. For example, within assembly dynamide-apps-59, the web-apps.xml file looks like this:

               <web-apps>
                  <app>
<URI>/Shop/Catalog</URI>
<APPNAME>catalog</APPNAME>
</app> </web-apps>

but once installed in a user's home directory, it should look like this

              <web-apps>
                  <app>
<URI>/Shop/Catalog</URI>
<APPNAME>catalog</APPNAME>
<ASSEMBLY>
com-acme-catalog-6</ASSEMBLY> </app> </web-apps>

and if installed in Self-Hosted Mode, all entries should be filled in.

              <web-apps>
                  <app>
<URI>/Shop/Catalog</URI>
<APPNAME>catalog</APPNAME>
<ASSEMBLY>
com-acme-catalog-6</ASSEMBLY> <HOME>acme</HOME> </app> </web-apps>

There are currently no tools to perform these installations -- simply edit the files and promote them into the correct directories.

AN IMPORTANT POINT: URI's inside the web-apps.xml file in an assembly are not consulted at runtime. They are there to help the manual and automated (not implemented) processes that install the applications. The result of the installation is updating of the global web-apps.xml file, or the one in homes/$account, depending on the action taken by the administrator and the administrator's permissions.

To sumarize, here is a series of web-apps.xml files for a Self-Hosted Mode host:

The precedence is :
    First:  homes/web-apps.xml
    Second: homes/acme/web-apps.xml
    Third:  homes/acme/assemblies/com-acme-catalog-6/web-apps.xml


When you log in, you get assigned roles, and permissions.  Dynamide objects require role permissions.

Roles:
    ROOT_ADMIN
    LOCAL_ADMIN
    DEVELOPER
    USER

Permissions:
    WRITE
    READ

Objects:
    ROOT_WEBAPPS
   HOME_WEBAPPS
    ASSEMBLY_WEBAPPS   

In Hosted Mode, only the Dynamide host administrator gets ROOT_ADMIN.
In Self-Hosted Mode, you can appoint a list of users to participate in the ROOT_ADMIN role.

Here are the permissions related to the web-apps.xml file:

Object
Example File
Write Access Requires
Read Access Requires
ROOT_WEBAPPS
homes/web-apps.xml
ROOT_ADMIN.WRITE USER.READ
HOME_WEBAPPS
homes/acme/web-apps.xml
LOCAL_ADMIN.WRITE
USER.READ
ASSEMBLY_WEBAPPS
homes/acme/assemblies/com-acme-catalog-6/web-apps.xml
DEVELOPER.WRITE
USER.READ



Directories in Dynamide Source Distribution


Directories in Dynamide WAR-file Distribution

Note: you may have sites outside of the war file also. You may install these where you wish, accessible to the Resin box via the (possibly network) filesystem These are configured through the conf/web-apps.xml. You point to your conf/web-app.xml with a serlet parameter in resin.conf. You can have multiple web-apps.xml files in the same folder, just name them differently and register them in the resin.conf file. You would do this if Q/A and Dev happened to point at the same source, for example. 




These are the task involved in installing a new WAR file.
back up conf file
install war file
merge conf file changes in
point conf to local sites file
sites/yoursite/conf contains a backup of conf. (maybe a local conf for all of this site?)
secure file system resources
set any non-standard ports you use
check resin.conf file
Site file has db connection strings, url mappings