← Back to Index

7.4 Release Notes

For Developers

Data Visualization

A set of elements (custom HTML tags) has been implemented for fetching aggregated data on the workflows, the repository and the audit. Combined with graphical elements (like Google Chart or Chart.js libraries) they allow to build meaningful business dashboards very quickly.

Ex: The one below allows to get arrays of information on data stored in documents of the repository (of type Insurance Claim).

<nuxeo-repository-data ecm-primary-type="InsuranceClaim"
where="[[_incidentBetween(startDate, endDate)]]"
grouped-by="incl:incident_us_state"
data="{{kindPerState}}">
</nuxeo-repository-data>

The one below fetches aggregated information on the TravelExpenseValidation workflow.

<nuxeo-workflow-data workflow="TravelExpenseValidation"
task="wf.travelExpenses.create"
grouped-by="taskActor"
with-date-intervals="day"
metrics="sum(workflowVariables.amount)"
start-date="[[startDate]]" end-date="[[endDate]]"
data="{{amountPerUserPerDay}}">
</nuxeo-workflow-data>

More information can be found in the Nuxeo Data Visualization documentation .

Asynchronous Conversions

The Conversion service has been improved to handle asynchronous conversions. This new feature has also been exposed on the REST API, with new endpoints. Launch an asynchronous conversion by doing a POST on the @convert adapter, with the parameter async to true:

POST http://localhost:8080/nuxeo/api/v1/path/to/file/@convert?async=true

This returns a JSON object with the following data:

{ "entity-type": "conversionScheduled", "conversionId": "id", "pollingURL": "http://localhost:8080/nuxeo/api/v1/conversion/id/poll" }

The new endpoint available to poll and get the result of a conversion:

GET http://localhost:8080/nuxeo/api/v1/conversion/id/poll

For conversion not completed, it returns the status of the conversion with a 200 HTTP code:

{ "entity-type": "conversionStatus", "conversionId": "id", "status": "running" // scheduled, completed }

For conversion completed, it returns the result URL in the Location header with a 303 HTTP code.

GET http://localhost:8080/nuxeo/api/v1/conversion/id/result

This returns the result Blob of the conversion if any, returns 404 if there is no conversion / no result yet for the conversion.

Upload by Chunks

The batch upload REST API has been improved to allow:

Resumable upload became a requirement otherwise uploading large files over a broken connection could take days. Using chunking is a good idea since: This is mainly a server-side feature, ultimately it will be used by:

Elasticsearch Passthrough: Audit Index and Contribuable Filters

The Elasticsearch API passthrough now allows to hit different indexes, like the audit one. Also, an extension point has been added for being able to plug different logics of filtering depending on the index name that is hit. For instance for the "workflow" index, a logic has been added for returning only audit events that are related to the workflow instances for which the workflow model is one on which the user has the permission "Data Visualization". Here is an exemple of such a contribution:

<?xml version="1.0"?>
<component name="org.nuxeo.elasticsearch.http.readonly.audit.filter" version="1.0">
<require>org.nuxeo.elasticsearch.http.readonly.RequestFilterService</require>
<extension target="org.nuxeo.elasticsearch.http.readonly.RequestFilterService"
point="filters">
<requestFilter filterClass="org.nuxeo.elasticsearch.http.readonly.filter.AuditRequestFilter"
index="audit" />
</extension>
</component>

More information on the Nuxeo Elasticsearch Passthrough documentation .

Batch Manager Uses the Transiant Store

Now the Batch Manager relies on the Transient Store to allow several implementations among which the Redis one that is cluster aware.

Theme Removal and Styling Methods Evolutions

Former Theme Framework has been Removed

The page layout is now relying on a standard XHTML page instead of an XML contribution to Nuxeo runtime extension points.
JavaScript and CSS resources to be presented on the page are now served by a wro4j servlet ( http://wro4j.github.io/wro4j/ ). This allows to use standard ways of managing these resources, and eases up style customization through Studio, thanks to standard CSS cascading features.
Also, the favicon can now be customized by flavor (like the logo already was).
Updated documentation and migration instructions are available.

From .css to Sass .scss

The styles framework is now using Sass. Thanks to this major evolution of Nuxeo's styles framework, the styles will be updated in the next versions of the product to have a cleaner structure, a neat logic, and have a better maintenability. The variables customizable by Studio are contained in one file, default_variable.scss. The old variables used by the Theme engine are now obsolete and will be moved to theme-webapp-compat.

DIV Instead of Tables

The container widget used in Nuxeo Studio has been lightened and displays now a div instead of a table on some cases. The main left column is now independant from the main area, allowing user to scroll only in the required area.

ACLs and Security Framework

New Methods on Java ACL Object

New methods were added on ACL object:

The ACL#addACE method implementation was modified to take care of the ACLs order: method take care of the ACLs order:

New Content Enricher: Allowed Permissions

A new enricher "AllowedPermissions" allows to fetch accepted UI Permissions for the given document according to the permission extension point.

File Download Security Policy

In addition to the permissions applying to a document, which restrict access to a document as a whole, it's now possible to specify more fine-grained permissions to disallow the download of some file attachments. To additionally restrict the download of a given blob inside a document, you can contribute to the following extension point:

<extension target="org.nuxeo.ecm.core.io.download.DownloadService" point="permissions">
<permission name="myperm">
<script language="JavaScript">
function run() {
if (CurrentUser.getName() != "bob") {
return false;
}
return true;
}
</script>
</permission>
</extension>

In the JavaScript context, access is provided when relevant to the Document, the XPath where the file is stored, the rendition name, the current user, the blob itself, and more contextual information.

Nuxeo Elements

The Nuxeo team has started implementing some Web Components, i.e. custom HTML elements that you can include in your HTML page, wherever that one is hosted. This set of custom elements allows to fetch data from the Nuxeo Platform: documents, directories, users. It also allows to easily execute some rest calls as well as some Nuxeo Automation operations calls. Those elements are a way to build an integration very quickly between a portal and Nuxeo Plaform, or any tierce application and Nuxeo Plaform. That's what was used for implementing the Salesforce connector. See the list of existing elements as well as a quick start .

Runtime Configuration Service

A new extension point has been added to define configuration properties to be checked by application code. This allows to tweak some of the application behaviours thanks to standard runtime contributions, in particular from a Studio project. Here is a sample contribution to use ajaxified tabs:

<component name="org.nuxeo.ecm.platform.ajaxified.tabs">
<extension target="org.nuxeo.runtime.ConfigurationService"
point="configuration">
<property name="nuxeo.jsf.useAjaxTabs">true</property>
</extension>
</component>

Those configuration properties aim at being at application level while the nuxeo.conf properties will be assigned to deployment level.

New and Enriched Audit Events

Search Events

A new parameter on the page provider allows to enable audit on page providers, thanks to an implementation in the AbstractPageProvider class that logs:

Tracking can be enabled at the Pageprovider level at the XML Contribution level, by just adding:

<trackUsage>true</trackUsage>

or in nuxeo.conf with the property:

nuxeo.pageprovider.track

Workflow Events

Information logged on workflow events has been greatly extended and more events are logged. You can find the details in the documentation .

Automation Scripting: Documents are Returned as DocumentWrappers

Documents (input, output, etc.) are now DocumentWrappers like in Automation Chains, allowing to use same sytnax such as Document["dc:title"].

New Insert Zone on Content Views

A new include zone, "bottom_buttons", has been added on content views. It can be easily overriden by JSF Templating composition.

New API to Compare Pictures

The org.nuxeo.diff.pictures.DiffPictures class allows to compare two pictures (must be same format and same dimensions), either from two Documents or two Blobs, and returns the image (as Blob) of the difference. Parameters can be used to setup the fuzz and the highlight colors. It requires ImageMagick.

Use \ to escape wildcards in NXQL LIKE

Possibility has been added to escape _ and % wildcards using a \ in a LIKE query:

SELECT ... WHERE dc:title LIKE 'foo\_'

This will only match foo_ but not for instance foo1. Without the \ it matches foo_ and foo1. This is now true for all backends that make use of NXQL Queries: VCS, MongoDB, Elasticsearch.

No Search On First Display

When accessing the Search tab for the first time, the rendering of results trigger a search that presents all documents. Some users would rather wait for the search filter form to be submitted at least once for this search to be triggered. This can be handled by detecting if user has already clicked on "Filter" at least once. Display of results should also be adapted when search has not been performed yet. The content view accepts a boolean property for this behaviour, as well as a customizable sentence to display when no result is shown because of this setting:

<component name="org.nuxeo.ecm.platform.ajaxified.tabs">
<extension target="org.nuxeo.runtime.ConfigurationService"
point="configuration">
<property name="nuxeo.jsf.useAjaxTabs">true</property>
</extension>
</component>

New Java API can be used to adapt display:

CMIS

ETag for CMIS Renditions

CMIS renditions now support an ETag like regular CMIS streams.

Flag to Allow Computation of CMIS Renditions Info

Set framework property org.nuxeo.cmis.computeRenditionInfo to true to have all renditions return a width, height, length and MIME type.

Template Rendering Samples

Installing Nuxeo Template Rendering package won't install samples anymore, which avoids you to have undesired documents in the repository. Updated sample documents are now available in a dedicated addon, NUxeo Template Rendering Samples .

Cluster Invalidator Made Pluggable

To customize the cluster invalidation mechanism for VCS, you can now define in the repository descriptor:

<clusterInvalidatorClass>some.class.name</clusterInvalidatorClass>

Here the class implements org.nuxeo.ecm.core.storage.sql.ClusterInvalidator. The default is org.nuxeo.ecm.core.storage.sql.jdbc.JDBCClusterInvalidator.

Core-IO tooling For Transtypage

Core-io can now be used to handle a migration between two Nuxeo repositories where there are some changes in the doc types or other kind of transformations. Several "transformers" have been added:

Ex:

final ExtensibleDocumentTreeReader reader = new ExtensibleDocumentTreeReader(root.getCoreSession(), root);
XMLDirectoryWriter writer = new XMLDirectoryWriter(destination);
writer.setSkipBlobs(skipBlobs);
// register extensions ! reader.registerExtension(new VersionInfoExportExtension());
reader.registerExtension(new LockExporterExtension());
DocumentPipe pipe = new TransactionBatchingDocumentPipeImpl(10);
pipe.setReader(reader);
pipe.setWriter(writer);
pipe.addTransformer(new DoctypeToFacetTranslator("Invoice", "File", "Invoice"));
pipe.addTransformer(new FacetRemover(null, "IOnlyExistsInV1"));
pipe.addTransformer(new FacetRemover(null, "Immutable"));
pipe.addTransformer(new FieldMapper("deprecated", "dep:fieldA", "invoice", "inv:A"));
pipe.addTransformer(new FieldMapper("deprecated", "dep:fieldB", "invoice", "inv:B"));
pipe.addTransformer(new FieldMapper("deprecated", "dep:fieldC", "new", "nw:Y"));
pipe.addTransformer(new SchemaRemover(null, "deprecated"));
pipe.addTransformer(new SchemaRenamer("invoice", "invoiceNew", "iv"));
pipe.run();