Skip to content

Functional Manifests

Carsten Stocklöw edited this page Apr 26, 2018 · 2 revisions

Table of Contents

Introduction

As the main communication at space-level (between different universAAL-aware nodes/peers) in universAAL is realized via the different communication buses (service bus, context bus, and ui bus), there is a need for an appropriate security mechanism. This mechanism is provided by an extension of the bus model and the functional manifests that are inspired by security mechanisms from OSGi and Android.

The Functional Manifest

The functional manifest basically is a list of all bus operations that an application can perform on the different buses. For example, if a ServiceCallee registers a ServiceProfile, then this profile needs to be part of the functional manifest. During registration, the actual profile is matched against the profile(s) defined in the functional manifest and is accordingly accepted or rejected.

The main purpose of this is to show all these bus operations from the functional manifest during installation to the user (i.e. the deployer) who can decide whether an application is allowed to perform these operations. This is similar to the permissions of an Android App, but in an extendable way by using the extendable set of ontologies. In universAAL, this can also be used to further restrict the permissions and change the permissions at runtime.

The following table lists all bus members and the permissions that must be provided in the functional manifest

bus member permission type
ServiceCallee ServiceProfile advertisement
ServiceCaller ServiceRequest requirement
ContextPublisher ContextEventPattern advertisement
ContextSubscriber ContextEventPattern requirement
UICaller UIRequest requirement
UIHandler UIHandlerProfile advertisement

It is important to note, that the manifest must contain all possible permissions. For example, if you are sending requests to turn on a specific light source, then the ServiceRequest contains the URI of that light source. However, as it is normally not known which light sources are available, the ServiceRequest in the functional manifest must be written in a way that this value is a variable. This can be done automatically if you create the functional manifest as a unit test (see below).

Creating a functional manifest

The functional manifest must be available in the bundle manifest in a certain format. To simplify the creation, there are currently two ways possible, a manual one and a way based on unit tests. Both ways are integrated into the maven lifecycle and executed during maven-install. It is recommended to use unit tests for manifest creation.

Integration in Maven Lifecycle

When calling a maven goal (like install) maven runs through a set of goals in a certain order, compare also for the Maven Lifecycle. These goals include, for example, compiling, performing unit tests, packaging as bundle, performing integration tests, and installing into the local repository.

The creation of functional manifests is integrated into this lifecycle as follows:

  • create functional manifest (phase: test)
    During unit tests, the functional manifest can be created programmatically in XML-format
  • prepare functional manifest (phase: prepare-package)
    The functional manifests created manually or via unit tests are tranformed into the format used by jar files. As input, the files uaal-manifest.xml (manual) and target/uaal-manifest.xml (from unit test) are considered and combined. The output is the file target/uaal-manifest.mf.
  • create jar file (phase: package)
    The bundle is created and the manifest is added.
  • integration test with manifests (phase: integration-test)
    During integration tests, the functional manifest is available and can be included in the test.
Please note, that maven needs to be configured correctly for this to work. This is already done if you use uAAL.pom as parent in your maven pom file.

Manual Creation

You can manually create a functional manifest at your bundle directory (where the pom file is located) in a file called uaal-manifest.xml. The basic structure in XML format is as follows:

 <application>
    <permissions>
       <bus name>
          <type>
             <title>-- human-readable title --</title>
             <description>-- human-readable description --</description>
             <serialization>
                -- serialization in turtle format --
             </serialization>
          </type>
          .. more types here
       </bus name>
       .. more buses here
    </permissions>
 </application>
The tag bus name is one of {mw.bus.context, mw.bus.service, mw.bus.ui} and type is one of {advertisement, requirement} as given in the table above.

Creation with Unit Tests

Functional manifests can also be created programmatically during unit tests. This has the advantage that the normal API can be used and, typically, also existing methods can be exploited. For example, if you already have a method getAllLampsRequest() that returns a ServiceRequest, then this method can be called from the unit test. For requests with specific values there is a possibility to generalize the request so that this value is variable.

The unit tests looks like this:

 public class ManifestTest extends ManifestTestCase {
    protected void setUp() throws Exception {
        super.setUp();
        // register required ontologies here
        OntologyManagement.getInstance().register(mc, new LocationOntology());
        OntologyManagement.getInstance().register(mc, new ShapeOntology());
        OntologyManagement.getInstance().register(mc, new PhThingOntology());
        OntologyManagement.getInstance().register(mc, new LightingOntology());
    }
    public void testCreateManifest() {
        add("title", "description", permission);
        // more calls to 'add' here
        writeManifest();
    }
 }
In the method setUp all the required ontologies are registered (in the right order). The method testCreateManifest actuall creates the manifest by calling the method add with title, description, and the permission (ServiceRequest, ServiceProfile, ContextEventPattern etc) for all the permissions. At the end, you have to call writeManifest which dumps all the information into the file target/uaal-manifest.xml.

There are some special cases:

  • For the context bus, a ContextEventPattern must be provided for both, publisher and subscriber. To distinguish between the two, the add-method requires another parameter - a boolean value that determines whether it is a publisher or not.
  • For service requests, there are two methods to determine how a generalization should be done. The first method requires a boolean parameter to determine whether everything or nothing should be generalized. The second method requires an int parameter that is a mask to determine what exactly should be generalized. Possible values are provided in the super class ManifestTestCase. For example, EXTEND_HASVALUE will try to generalize all owl:hasValue restrictions and EXTEND_CHANGE_EFFECT will try to generalize all change effects. For example, if you have a request to set the brightness of a light source, then a concrete request would contain a concrete light source URI as a filtering input (which is an owl:hasValue restriction) and a concrete value for the desired brightness as a change effect. This can be extended to a request which is valid for all light sources and an arbitrary int-value for the brightness. This generalized request should go into the manifest.

Execution

There are two parameters that influence the behaviour of the buses regarding the functional manifests:

  • org.universaal.bus.permission.mode
    determines whether the manifests should be evaluated and how the system should react. Possible values:
    • none: the functional manifest is ignored, everything is allowed.
    • log: the functional manifest is used but no action is taken except from a log message.
    • full: the functional manifest is used. Depending on the implementation of the specific bus, a SecurityException may be thrown.
  • org.universaal.bus.permission.modeupdate
    Possible values:
    • always: for each bus operation, the mode is updated and read out as a system parameter. This allows to change the mode during runtime. This value can be useful during development.
    • never: The mode is only set at start up and can not be changed. This value is preferred in deployments.
These parameters are system parameters and can be set when starting universAAL with -D. The default is log/always which is optimal for development but this also means that this security feature must be enabled explicitely. To enable this feature, use:
 -Dorg.universaal.bus.permission.mode=full -Dorg.universaal.bus.permission.modeupdate=never

Example

An example is available with the lighting sample (server, client, and ui client). Please have a look at the unit tests and (after calling maven-install) the generated manifest files in target/uaal-manifest.xml and inside the jar file.

Known issues and limitations

  • Changing the permissions at runtime is not yet possible, it's all or nothing.

Support:

Found a problem?
  • Report suggestions, missing, outdated or wrong documentation creating an Issue with "documentation" tag
Clone this wiki locally