Avoka Blog: Adobe LiveCycle

June 30, 2008

Form Guide Rendering Explained

Filed under: Designing Forms, LiveCycle, LiveCycle Architecture — htreisman @ 4:05 pm

You probably already know that Form Guides are an exciting way to render an Adobe dynamic form via a Wizard-style interface. See this link for more details: http://help.adobe.com/en_US/livecycle/es/fggettingstarted.pdf

However, all this document says about how rendering a Form Guide works is:

“The process for rendering form guides is similar to the process used to render forms in PDF or HTML. You must create a new process in Workbench ES that uses the form guide rendering operation renderFormGuide.”

How does rendering a Form Guide really work?

The short answer is that it is similar to rendering a PDF. The longer answer is that there are some subtle differences, and these differences can have an impact on how you architect your solution. In particular, a Form Guide actually consists of three separate parts:

  1. An html page containing the Form Guide SWF file.
  2. Some Javascript libraries (mostly dealing with Browser Flash detection).
  3. The SWF file that is the Form Guide itself.

Each of these is loaded in a different interaction between the user’s browser, your custom servlet, a special LiveCycle servlet, and LiveCycle Forms itself.

The easiest way to explain this is via a sequence diagram:

Click For Full Size

(Click for larger image)

  1. HTML page
    1. The user clicks on the link to your Form Guide, sending a http request to your custom servlet.
    2. The servlet will invoke an orchestration defined in LiveCycle Workbench.
    3. The orchestration will obtain pre-population data if required (usually from some sort of database, using the logged-in user’s details)
    4. The orchestration will then invoke the LiveCycle Forms “render” operation, passing through the name of the XDP template, and the pre-population data.
    5. The render operation will return an html page. This page will contain some JavaScript references, and an <object> tag containing the SWF.
    6. The object tag will identify a uniquely named SWF file on the LiveCycle server
    7. The object tag will also include a “Flash Variable” embedded within the page – this Flash variable contains the pre-population data in an encoded form.
    8. The html page will be returned to the browser.
    9. Note: You could use Java code to directly invoke the LiveCycle Forms API, rather than using an orchestration.
  2. JavaScript
    1. The browser will identify the JavaScript libraries on the page, and request them from the LiveCycle server. Note that the request goes directly to JavaScript resources located within a web application on the LiveCycle server – your orchestration is not involved.
  3. Form Guide (SWF file)
    1. The browser will identify the object tag on the page.
    2. It will make a request to the LiveCycle server to obtain the object referenced in this page. This request goes directly to the LiveCycle supplied servlet, it does not involve your orchestration or custom code.
    3. The servlet will look at the unique object id specified, and will use this to locate the correct XDP template to turn into a SWF. (This is the same template that you specified when you called the “render” method.)
    4. The servlet will convert the XDP into MXML/ActionScript, and invoke the Flex compiler to generate the SWF file.
    5. It will then save the SWF file into the LiveCycle Forms cache. As long as the underlying XDP file doesn’t changed, (and assuming you don’t manually clear the cache), the servlet will serve up the SWF file from the cache from now on. This is because compiling the SWF file can be quite time-consuming.
    6. Finally, the SWF will be returned to the browser.
  4. Final display.
    1. The browser now has everything it needs to render the page. It will run the Javascript, and execute the SWF file, passing into it all the encoded pre-population data.
    2. Voila

Notes:

  • In a clustered environment, it doesn’t matter whether #2 and #3 go to the same member of the cluster, or a different member of the cluster – what’s returned to the browser is always identical.
  • LiveCycle only needs to generate the SWF the first time, because it’s always identical. The pre-population data is embedded in the html file, which is generated each time the client requests a Form Guide, and may be different for each invocation.
  • You should manually load the Form Guide the first time you publish the Form Guide into production – otherwise the first user to load it will experience a longer than usual delay.

Things can get a little more complicated in a real production environment.

Click to View Larger

The second diagram indicates a more real-life environment, where:

  • An Apache server has been introduced which front-ends the Application Server. The end-user can only “see” the Apache server, and cannot directly access the custom servlet or the LiveCycle Forms application server. This is generally considered to be a more secure way to architect any public-facing web application.
  • A firewall has been introduced between the custom servlet, and the LiveCycle server. Another firewall is usually inserted between the Apache server and the custom servlet, although this is omitted from the diagram.
  • A variation on this architecture is that the custom servlet may run on the LiveCycle application server.
  • The LiveCycle server may run in either the DMZ or within the corporate zone, depending on it’s accessibility requirements to databases and other corporate resources.

This requires some modifications to the architecture of our application.

  1. When rendering the form using LiveCycle Forms “render”, you must specify the URL of the Apache server, rather than the URL of the LiveCycle server. This ensures that the client’s browser will interact with the Apache server, rather than attempting to communicate directly with the LiveCycle server.
  2. You must set up Apache to “pass-through” requests for both the custom servlet and the LiveCycle servlet.
  3. You must somehow allows requests to the LiveCycle servlet to pass from Apache through to the LiveCycle servlet on the LiveCycle server. There are a number of ways of doing this:
    1. If the Apache server can “see” the LiveCycle server, you can set up a proxy rule to allow traffic for the servlet to be passed through.
    2. You may need to write a simple proxy service within your custom servlet. This is basically a servlet with the same name as the LiveCycle servlet, which passes any requests through to the LiveCycle servlet, and forwards any responses back to the browser.

Thanks to Rak Siva of Avoka and Gareth Faulkner of Adobe for assistance with this blog.

Advertisements

June 19, 2008

Best practise for pre-populating a Drop Down with data?

Filed under: Designing Forms, Designing Processes, LiveCycle — htreisman @ 1:53 pm

One of our internal consultants recently asked: “What is best practice for populating a Drop Down list in a PDF form with data?”

There are several ways to do it, and there is no “best” or “recommended” way. The suggestions below are roughly in order of complexity.

  1. You can just hard code the values in the form template.
  2. You can populate a hidden field with comma-separated data, and use JavaScript to split the items and add them to the drop down. (If you use a comma separator, make sure that your data doesn’t have any commas in it).
  3. You can bind a Drop Down directly to element in your form’s XML, using a feature called Dynamic Properties (in Designer). Then, instead of populating a hidden field, you just populate elements directly into your XML. No javascript required, but a bit more work in your XML Schema.
  4. You can have your form calling a web service in order to get the data it needs, and use Javascript to process the results, and populate the Drop Down. You can build the web service any way you like, including as a LiveCycle orchestration. This is often the only way to approach things if the contents of the drop down depends on other data in your form.

For #2 and #3, you can modify the LiveCycle Default Render process to inject the data into your XML.

The screenshot below shows how to turn on “Dynamic Properties” in Designer.

Dynamic Properties in LiveCycle Designer

If anyone reading this blog needs more information on exactly how to do this, email info-at-avoka.com

June 16, 2008

LiveCycle directories – Global Storage/Temp, clustering, and more…

Filed under: LiveCycle, LiveCycle Administration, LiveCycle Architecture — htreisman @ 11:03 am

The information in this Blog is correct to the best of my knowledge – if you discover any errors, please post on the comments area.

Thanks to Pete Spencer of Adobe for his expertise.

General

  • You need to specify various directories when you configure LiveCycle using the Configuration Manager. These include:
    • Global Document Storage (GDS) Directory
    • Temporary Directory
    • Font Directories
  • The values you enter into Configuration Manager are stored within the LiveCycle ear file. The values in this ear file are only used during initializing (bootstrapping) the LiveCycle database – after this, they are no longer used, and the values from the database are used instead.
  • All of the directories must be specified from the perspective of the application server, NOT the perspective of the machine running Configuration Manager. In other words, these directories must exist on the application server. It’s therefore simplest if you actually run Configuration Manager on the target machine.
  • You can modify the directory names in the database using Adminui at any time, including after installation. Home > Settings > Core System Settings > Configurations. You must restart the server before your changes take effect. You MUST move files from the old GDS to the new GDS while the server is stopped. You do not need to reconfigure or redeploy your ear files.
  • There is only one directory location stored in the database, no matter how many instances you have in your cluster. In a clustered environment, you must set up your servers so that all of them have the same GDS, temp and font directory names. (There’s a way around this for the temp directory – see below.)

For example: if you’re running LiveCycle on different operating systems, you cannot set the System Font directory to c:\windows\fonts on one machine, and c:\winnt\fonts on a different machine. You will have to make the directory the same on all machines, even if this means copying files to matching directories.

Another example: You cannot set the Global Storage Directory to “C:\Adobe\Global” on one machine, and “\\machine1\c$\Adobe\Global” on another. You can use “\\machine1\c$\Adobe\Global” on both machines (although this would create a single point of failure).

  • Make sure that the user under which you run the Application Server has read/write access to the temp/GDS directories, and read access to the Font directories.
  • You can use the same LiveCycle ear files for installs onto multiple boxes (eg Dev, Test, Production), even if the actual directories on a second box don’t match those that you specified for the first box. You can deploy the LiveCycle ear files, run LiveCycle, and bootstrap the database. Then you can modify the directories using Adminui, and restart LiveCycle. Once you’ve done this, you can complete the configuration by installing components and samples, etc. (Note: We haven’t thoroughly tested this, and don’t know for sure that those directories in the LiveCycle ear file aren’t used for some other purpose – we recommend that you create separate LiveCycle ear files for each machine configuration.)

Font Directories

  • These can be shared, or each application server in a cluster can have its own copy on a local drive.
  • If you’re running Configuration Manager on one machine, and deploying to another, you must copy the LiveCycle fonts from the installation directory (usually C:\Adobe\LiveCycle8\fonts) to a location on the application server machine.
  • Under Windows, the system fonts are generally either in C:\windows\fonts or c:\winnt\fonts.

Global Document Storage Directory (GDS)

  • The GDS should be considered an extension to the database, and is part of the persistent state of the LiveCycle system. Don’t “clean up” the files in this directory.
  • You should back up the files in this directory simultaneously with the database. See my previous post on this topic.
  • The GDS must be a single directory that is shared between all instances of LiveCycle in a cluster. Usually this means setting up the GDS on a shared drive, or a Storage Area Network (SAN).
  • It must also be referred to by exactly the same pathname for all instances of LiveCycle.
  • If you change the location of the GDS, you must ALSO move all the files to the new location while the server is stopped.

Temporary directory

  • Each running instance of LiveCycle requires its own temporary directory. There are a number of ways of specifying the temporary directory:
  • If you specific a non-blank directory in Configuration Manager (which also means a non-blank directory in adminui), then LiveCycle will use this value.
  • If you specify a blank directory in Configuration Manager/Adminui, then LiveCycle will use the Java VM java.io.tmpdir system property.
  • The java.io.tmpdir property can be set in several ways:
    • You can specify it explicitly in the command line that you use to launch the Java VM that runs LiveCycle. For example, “java -Djava.io.tmpdir=C:\temp …”
    • If you do not specify it explicitly, Java will set this value based on operating system defaults (eg value of “TEMP” system variable)
  • If you are using vertical clustering, the members of the cluster will each need their own temp directory, but they are sharing the same physical drive. Therefore
    • Leave the temporary directory blank in Configuration Manager/Adminui.
    • Specify a different java.io.tmpdir Java system property for each instance of LiveCycle.

June 6, 2008

Hot Back-ups of LiveCycle

Filed under: LiveCycle, LiveCycle Administration, LiveCycle Architecture — htreisman @ 4:17 pm

Most of LiveCycle’s data is held in the LiveCycle database. Backing up the database is easy – just use the native backup facilities provided by your database vendor.

Usually you can do a “hot” backup, while the application (i.e. LiveCycle) is still running. What the backup utility does is to set a “marker” in the database transaction log – the backup is the state of the entire database at the point in time the marker was set. The database will continue to run, and execute transactions, but the data from these new transactions won’t appear in the backup – so no matter how big the database is, you always get a consistent set of data.

LiveCycle is a bit more complicated, because it has the Global Document Storage directory (GDS). The GDS is really an extension or overflow for the database. For any large documents, these are actually stored in the GDS, rather than in the database – this helps with performance, and also helps to ensure that your database doesn’t grow too rapidly.

You always need to ensure that when you do a backup of your database, you do a backup of your GDS. Similarly, if you do a restore, you should also restore both the GDS and the database at the same time.

The trick is: how do you ensure that the database and GDS are consistent with each other? Any missing files in the GDS will cause LiveCycle to start throwing exceptions.

One technique is to shut down LiveCycle while you’re doing the backup. If you need to do hot backups, then there are different approaches depending on your version of LiveCycle.

LiveCycle 8 Update 1

In LiveCycle 8 update 1 (at the time of writing, in beta), Adobe have added “backup mode” to enable backups to be made more reliably. The steps are:

  • Turn on “backup mode” in the adminui – this will temporarily prevent LiveCycle from deleting any files from the GDS.
  • Backup the database.
  • Backup the GDS.
  • Turn backup mode off.

LiveCycle 8

There is no backup mode in LiveCycle 8. The following procedure is the one that we recommend for hot backups.

  • Backup the GDS
  • Backup the database
  • Backup the GDS again, to the same backup location. Ensure that you use a backup mode that adds any new or modified files, but does NOT remove any files that have been removed since the first backup.

You should also try to ensure that the entire process above occurs as quickly as possible. This may mean that you initially copy the files to a temporary location, and then perform the real backup (to tape or whatever) from there.

There is apparently a small window of possibility that errors occurs – if a file in the GDS is created and removed between the time that the first backup starts and the second backup completes. This is generally a small window. Thank you to Rob Ryan of Adobe for pointing this out.

Create a free website or blog at WordPress.com.