We use proprietary and third party's cookies to improve your experience and our services, identifying your Internet Browsing preferences on our website; develop analytic activities and display advertising based on your preferences. If you keep browsing, you accept its use. You can get more information on our Cookie Policy
Cookies Policy
Application Mashup - Wirecloud - User and Programmer Guide - FIWARE Forge Wiki

Application Mashup - Wirecloud - User and Programmer Guide

From FIWARE Forge Wiki

Jump to: navigation, search
IMPORTANT NOTE: this page contains outdated WireCloud's documentation. New versions of this documentation are published at Read the Docs.

Contents

Introduction

This document describes the necessary steps for developing application mashups using the open source WireCloud Mashup Platform. In addition to this, this guide also describes how to develop the mashable application components that allows end users to create those application mashups.

Background and Detail

This User and Programmers Guide relates to the Application Mashup GE which is part of the Applications and Services chapter. Please find more information about this Generic Enabler in the following Open Specification.

Please note that this page contains outdated CKAN API's documentation. New versions of this documentation are published at Read the Docs.

User Guide

Web mashups integrate heterogeneous data, application logic, and UI components (widgets/gadgets) sourced from the Web to create new coherent and value-adding composite applications.

Web mashups are targeted at leveraging the "long tail" of the Web of Services by exploiting rapid development, DIY, and shareability. They typically serve a specific situational (i.e. immediate, short-lived, customised, specific) need, frequently with high potential for reuse. Is this "situational" character which preclude them to be offered as 'off-the-self' functionality by solution providers.

Web mashups can be manually developed using conventional web programming technologies (e.g. see http://programmableweb.com). But this approach fails to take full advantage of the approach. Mashup tools and platforms like WireCloud aim at development paradigms that do not require programming skills and, hence, address end users, thus leveraging the long tail of the Web of Services.

WireCloud builds on cutting-edge end-user development, RIA and semantic technologies to offer a next-generation end-user centred mashup platform aimed at leveraging the long tail of the Internet of Services.

Key Features

WireCloud helps end users to innovate through experimentation by choosing the best suited widgets and prefab mashups (a.k.a. mashup-lets) for your devised mashup from a vast, ever-growing distributed catalogue.

WireCloud offers its main features through two integrated tools:

  1. The wiring editor, which allows you to easily connect widgets in a mashup to create a full-fledged dashboard with RIA functionality
  2. The piping editor, which allows you to easily connect widgets to back-end services or data sources through an extendable set of operators, including filters, aggregators, adapters, etc.

Besides, WireCloud allows you to easily share your newly created mashup with other colleagues and users. Comment it, tag it and rate it to foster discoverability and shareability. WireCloud helps to build a strong community by commenting, tagging and rating others' widgets, operators and mashups. The platform will also do its best to complement your contribution.

Creating a new workspace

Mashups in WireCloud are built in the context of workspaces. A workspace consists of the set of widgets and operators that can be mashed-up, even spanning multiple tabs. Widgets and operators in a workspace can share data though data flow- or event-based mechanisms.

The workspace in use is shown in the upper area of the screen. It resembles the well-known REST nomenclature. For example, the following screenshot shows a workspace named “Workspace”, pertaining the user “admin” and running in the FIWARE Lab’s instance of WireCloud, i.e. it is named admin/Workspace.

Near the workspace name there is a button that you can click on to expand the workspace dropdown menu:

Once expanded, the menu shows a list of the already created workspaces (see Workspace, My Multimedia Workspace and IssueTrouble in the figure above) that allows you to quickly switch between them, followed by a list of options:

  • Rename changes the name of the current workspace
  • Settings changes the settings of the current workspace
  • Remove deletes the current workspace
  • New workspace creates a new workspace
  • Embed shows info about how to embed current workspace in other web pages
  • Upload to local catalogue allows you to save the current workspace to the local catalogue for later usage

If you want to create a new workspace named “History Info”, choose “New workspace” in the dropdown menu:

A dialog will pop up requiring a name for the new workspace. Type the desired name and click the accept button:

Once accepted, the name of the new workspace is shown in the upper of the window:

The following screenshot show the Settings menu, where you can set workspace features:


Browsing the Marketplace

Marketplaces and Stores

A mashup tool like WireCloud must support access to a marketplace made up of stores, where people can offer and deal with services made accessible through widgets and operators, like goods, and finally mashup them to create value added services and applications.

On the marketplace you can quickly find and compare widgets and operators, which enable you to attend an industry-ecosystem better than before. Widgets, operators, and even pre-built mashups become tradable goods, which can be offered and acquired on Internet based marketplaces. Partner companies and other users can combine existing services to new services whereby new business models will be incurred and the value added chain is extended.

We differentiate the marketplace from a store. While a store is owned by a store owner who has full control over the specific (limited) widget, operator and mashup portfolio and offerings, a marketplace is a platform for many stores to make their offerings available to a broader audience and enable consumers to search and compare widgets, operators and pre-built mashups and find the store, where to buy. The final business transaction (buying) is done at the store and the whole back office process is handled by the store.

The following figure shows a screenshot of WireCloud where you can see the FIWARE Lab marketplace and the different stores made available through it.


Managing marketplaces

When looking for an offer of widgets, operators and mashups, you first need to choose a marketplace. Use the dropdown menu shown in the workspace path for this purpose.

As shown in the previous screenshot, this menu allows you to choose among the different marketplaces you have access to. To add a new marketplace, you only need to provide its endpoint (URL). You can also delete the current markeplace through the "Delete Marketplace" option in the context menu.

You can add the FIWARE marketplace using "Add new marketplace", as shown in the following screenshots (**NOTE:** use "http://130.206.81.113/FiwareMarketplace/v1/" for now, we are working on integrating and migrating current contents to WMarket).


WireCloud offers a built-in local catalogue, which allows you to search among the widgets, operators and mashups currently available for the user. The following figure shows a screenshot of the local catalogue for a user in a given instance of WireCloud.

If you are a widget developer with brand new widgets to share, or you just have downloaded a WireCloud-compliant widget from anywhere, you can easily upload your new widgets to the built-in local catalogue through the "Upload" button available on the "My Resources" view.

Choosing an available store

Stores in WireCloud are associated to a specific marketplace. Therefore, to surf a store you first need to choose the FIWARE Lab marketplace that publishes it. In the following figure, the user uses the dropdown menu to choose FIWARE Lab’s marketplace:

Once in the FIWARE Lab marketplace, the store dropdown menu shows all its available stores (CoNWeT, WStore FIWARE Lab and Another Store). The following figure shows the options available in the stores dropdown menu:

Last, but not least, you can return to surf the entire marketplace and see the global offer at a glance by selecting the “All stores” option.

Publishing mashable application components into Stores

  1. Go to the local catalogue:
  2. Open the mashable application component details clicking on it:
  3. Click on Publish:
  4. Check the marketplace and the Store where the mashable application component is going to be uploaded
  5. That's all!. Now you will be able to create new offerings at the selected Store using the uploaded resource. See the WStore documentation for more information on how to create offering using the uploaded resources.

Building a new mashup

If you followed the instructions documented in the "Creating a new workspace" section, you should have a "History Info" workspace. Let's assume that we start from this point:

Go then to the Marketplace to choose among the widgets available in the catalogue those you want to use in your mashup:

To ensure that you find the required widgets/operators for this example mashup, go to the FIWARE Lab marketplace and install them using the WireCloudUserGuide offering. You can also download them using the following URLs:

Once installed, you should be able to see all the widgets/operators used in this example in the "My Resources" view:

Go to the editor view and click on the "Add widget" button:

Look for the Linear Graph widget and click on the "Add to workspace" button:

This will add the Linear Graph widget into the dashboard, you can move and resize it until you obtain the desired layout:

Add the “Map Viewer” widget to the dashboard following the same steps for adding the Linear Graph widget. After rearranging it you will be presented with the following view, which shows you the two widgets in the default tab. You can see the tabs used in your workspace at the footer bar, and you can create new tabs to better organize the distribution of the widgets in your mashup.

Changing the settings of a widget

Once you have added the desired widgets to your mashup and you have placed and resized them to configure the information dashboard of your choice, you can change their settings. To do so, go to the upper-right corner of the widget and click the properties icon as shown in the following screen shot

You will then be presented with a dropdown menu with several options.

  • Rename changes the widget name shown in workspace editor and wiring Editor views
  • Settings shows a form for changing the settings of the current widget
  • Log shows a dialog with the log history of the widget
  • Reload reloads the widget
  • User's Manual will open the widget documentation
  • Full Dragboard maximises the selected widget, so it will take up the full canvas area. This option becomes Exit Full Dragboard if the widget is already on "Full Dragboard" mode. In that case, this option will restore the size of the widget to the one it had before maximising it
  • Extract from grid lifts up the widget from the canvas, allowing you to place it wherever you want on the canvas, even on top of other widgets. This option becomes Snap to grid if the widget is currently outside the grid, in this case, this option docks the widget into the grid.

Finally, click on the settings and you will be prompted with a customised dialog for the settings of the widget. In this example, the Map Viewer should be provided with initial location, zoom level and mark shadow radius to customise the visualisation.

After configuring the settings, the widget will show the new location, Santander, with the new zoom.

At this time, you have created a mashup with two individual widgets. The Linear Graph widget is empty and need to be wired with something that provides information to draw, and the Map Viewer is a good option to show any kind of "Points of Interest" and allow the user to select them easily.

Wiring widgets and operators

Once you have chosen the desired widgets, you can wire them to enable their intercommunication and to achieve coordinated behaviour. Widgets and operators in WireCloud, are capable of sending and/or receiving events and data through well-identified ports called endpoints. When you connect two compatible endpoints, the second one (i.e. the input or target endpoint) prepares to receive data flows and/or events coming from the first one (i.e. the output or source endpoint).

Basic wiring concepts

To wire the widgets and add operators to your mashup go to the Wiring view of the tool:

You will then be presented with the set of widgets currently added to the workspace and the set of operators currently available:

One of the most important characteristics that should be intrinsic to the design of widgets is that they must be as generic as possible. For example, it makes much more sense to have a generic Map Viewer widget that can be wired through an operator to any source of information of your choice, than to have an specific one that has hard-coded the source of data. Operators represents the means to achieve this generality, because they represents the means to dynamically associate the widgets with the concrete services or sources of information you want to use in the context of a particular mashup.

In this case, we have an NGSI source operator that is going to provide the data information to the Map Viewer widget. This kind of operators are called piping operators. So we have to add it to the wiring. To do so, drag the operator from the operator list to wiring canvas:


Now, we have the source of information that is going to be presented in the Map Viewer widget. So we need to add it to the wiring status following the same process for the operator, but dragging the widget instead of the operator:

The wiring editor comes with a recommendation system for connections. For example, move the pointer to the Provide entity endpoint. You will see that the endpoint get highlighted, this means that te recommendation system is searching for compatible endpoints. In this case there are no compatible endpoints.

This is because the output of the NGSI source cannot be connected directly with the Map Viewer widget. We can use a transform operator to convert the event data provided by the NGSI Source operator to the format used by the Map Viewer widget. In this example, the operator that is going to perform this transformation is NGSI Entity to PoI:

After adding the operator, we can move the pointer to the Provide entity endpoint to see that now we have a connection recommendation:

So, we can connect it. To do so, push down the mouse button on the Provide entity endpoint and drag the arrow to the Entity endpoint:


And we can also connect also the PoI endpoint of the NGSI Entity To PoI operator to the Insert/Update PoI endpoint on the Map Viewer widget:

If you return to the Editor view, you will see that the map widget has been updated and is showing the PoIs obtained from the NGSI Source operator.

You can use the Map Viewer moving the viewport, selecting PoI's, etc. But in really, what we have is just the Map Viewer widget connected to a source of data, but using piping and transformation operators that is going to give us a great flexibility.

Other wiring common tasks

One of the most common operations is the task of getting the connections removed in the wiring. For example, when you make some mistake for some reason, you can fix it by selecting the connection (by clicking on it) and then by clicking the red dot that appears in the middle of it.


Another common task is to change the shape of connections. This can be accomplished by moving the handles that appear when they are selected.


You can also minimize operators with the intention of improving space usage. This can be accomplished using the "Minimize" option that appears in the Widget's menu:


Cloncluding our example

Continue wiring the rest of the widgets in your mashup following your intuition, the documentation and the contextual help offered by each widget/operator. Anyway, just in case you have difficulties, you can see the final result in the following screenshot:

Operators, like widget has also settings that can be modified using the following steps:


Now you can play with your new workspace.



Sharing your mashups

Workspaces can be made public by means of modifying their settings as Follows:

  1. Click on the workspace menu button and click Settings:
  2. You will be presented with a dialog for editing workspace's settings:

After making a workspace public, you will be able to share the workspace URL with other users.

Embedding mashups inside other web pages

All workspaces can be embedded, but take into account that access rules are the same that applies when using the workspace directly from WireCloud. If you don't make the workspace public, you will require users to be logged in WireCloud and having enough access permission. This make changing sharing settings of the workspace a first step before embedding mashups into other web pages.

You can also obtain the code you have to copy & paste into other web pages following those steps:

  1. Click on the workspace menu button and click Embed:
  2. A new window showing you the code for embedding the mashup. Copy & paste it into you HTML document.

Additional sources of information

See the Application Mashup GE fundamentals course at the FIWARE Academy for detailed documentation on how to use WireCloud from different perspectives (end-user, developer and administrators). Another source of information is the WireCloud website where you can find more general information and other interesting resources such as demo videos.

Programmer Guide

Widget and Operator development

Before starting the creation of a widget, the developer should be aware of certain design principles of the widgets:

  • Widgets are supposed to be small, reusable and user centric web applications.
  • Generic widgets are desirable, but ad-hoc solutions are allowed too if they are quick and cheap enough.
  • Widgets should be adapted to real problems.
  • Widgets are elements of the front-end layer (View). It's not desirable for widgets to perform back-end layer functions (controller or model) because they can be provided by the platform (persistent state).
  • During the development of widgets any technology accepted by web browsers (XHTML, JavaScript, SVG, Flash, applets ....) can be used.

Widgets are formed by three different components:

  • Template, which is a declarative description of the widget, and represents its main entry point. This file contains, among other things, references to the rest of resources of a widget.
  • Code, composed of HTML, JavaScript and CSS files containing the definition and the behaviour of the widget.
  • Static resources, such as images, documentation and other static resources.

Operators are very similar to Widgets. The main difference is that operators doesn't have a view. This means that operators descriptors doesn't use an initial HTML document as entry point. Instead, operators define the list of javascript files in their descriptor file. There are three types of operators:

  • Data sources operators: Operators that provide information that can be consumed by other widgets/operators. For example, an operator that retrieves some type of information from a web service.
  • Data targets operators: Operators that are provided information and use it to do some tasks. For example, an operator that receives some information and push it to a web service.
  • Data transformation operators: This type of operators can be very useful since they can transform data in order to make it usable by widgets or operators that expect data structure to be slightly different.

Javascript API

The Javascript API allow Widgets and Operators to access the functionalities offered by the Application Mashup GE like widget/operator interconnection, state persistence, access to the cross-domain proxy, ...

MashupPlatform.http

buildProxyURL

builds a URL suitable for working around the cross-domain problem. It is usually handled using the WireCloud proxy but it also can be handled using the access control request headers if the browser has support for them. If all the needed requirements are meet, this function will return a URL without using the proxy.

MashupPlatform.http.buildProxyURL(url, options)

Example usage:

var internal_url = 'http://server.intranet.com/image/a.png';
var url = MashupPlatform.http.buildProxyURL(internal_url, {forceProxy: true});
var img = document.createElement('img');
img.src = url;
makeRequest

Sends an HTTP request. This method internally calls the buildProxyURL method for working around any possible problem related with the same-origin policy followed by browser (allowing CORS requests).

MashupPlatform.http.makeRequest(url, options)
  • url is the URL to which to send the request.
  • options is an object with a list of request options (see the request options section for more details).

Example usage:

$('loading').show();
MashupPlatform.http.makeRequest('http://api.example.com', {
    method: "POST",
    postBody: JSON.stringify({key: value}),
    contentType: "application/json",
    onSuccess: function (response) {
        // Everything went ok
    },
    onFailure: function (response) {
        // Something went wrong
    },
    onComplete: function () {
        $('loading').hide();
    }
});
request options

General options:

  • contentType (String): The Content-Type header for your request. If it is not provided, the content-type header will be extrapolated from the value of the postBody option (defaulting to application/x-www-form-urlencoded if the postBody value is a String). Specify this option if you want to force the value of the Content-Type header.
  • encoding (String; default UTF-8): The encoding for the contents of your request. It is best left as-is, but should weird encoding issues arise, you may have to tweak this.
  • method (String; default POST): The HTTP method to use for the request.
  • responseType (String; default: ""): Can be set to change the response type. The valid values for this options are: "", "arraybuffer", "blob" and "text".
  • parameters (Object): The parameters for the request, which will be encoded into the URL for a GET method, or into the request body when using the PUT and POST methods.
  • postBody (ArrayBufferView, Blob, Document, String, FormData): The contents to use as request body (usually used in post and put requests, but can be used by any request). If it is not provided, the contents of the parameters option will be used instead. Finally, if there are not parameters, request will not have a body.
  • requestHeaders (Object): A set of key-value pairs, with properties representing header names.
  • supportsAccessControl (Boolean; default false: Indicates whether the target server supports the Access Control headers, and thus, you want to make a request without using the cross-domain proxy if possible.
  • forceProxy (Boolean; default false): Sends the request through the proxy regardless of the other options passed.
  • context (Object; default null): The value to be passed as the this parameter to the callbacks. If context is null the this parameter of the callbacks is left intact.

Callback options:

  • onSuccess: Invoked when a request completes and its status code belongs in the 2xy family. This is skipped if a code-specific callback is defined (e.g., on200), and happens before onComplete. Receives the response object as the first argument.
  • onFailure: Invoked when a request completes and its status code exists but is not in the 2xy family. This is skipped if a code-specific callback is defined (e.g. on403), and happens before onComplete. Receives the response object as the first argument.
  • onXYZ (with XYZ representing any HTTP status code): Invoked just after the response is complete if the status code is the exact code used in the callback name. Prevents execution of onSuccess and onFailure. Happens before onComplete. Receives the response object as the first argument.
  • onComplete: Triggered at the very end of a request's life-cycle, after the request completes, status-specific callbacks are called, and possible automatic behaviours are processed. Guaranteed to run regardless of what happened during the request. Receives the response object as the first argument.
  • onException: Triggered whenever an exception arises running any of the onXYZ, onSuccess, onFailure and onComplete callbacks. Receives the request as the first argument, and the exception object as the second one.
response object
  • request (Request): The request for the current response.
  • status (Number): The status of the response to the request. This is the HTTP result code (for example, status is 200 for a successful request).
  • statusText (String): The response string returned by the HTTP server. Unlike status, this includes the entire text of the response message ("200 OK", for example).
  • response (ArrayBuffer, Blob, String): The response entity body according to responseType, as an ArrayBuffer, Blob or string. This is null if the request is not complete, was not successful or the responseType option of the requests was "".
  • responseText (String): The response to the request as text, or null if the request was unsuccessful or the responseType option of the requests was different to "".

MashupPlatform.log

Object containing the following constants:

  • ERROR: Used for indicating an Error level.
  • WARN: Used for indicating a Warning level.
  • INFO: : Used for indicating an Info level.

MashupPlatform.prefs

get

Retrieves the value of a preference.

MashupPlatform.prefs.get(key)
  • key is the preference to fetch.

Example usage:

MashupPlatform.prefs.get('boolean-pref'); // true or false
MashupPlatform.prefs.get('number-prefs'); // a number value
MashupPlatform.prefs.get('text-prefs');   // a string value
registerCallback

Registers a callback for listening preference changes.

MashupPlatform.prefs.registerCallback(callback)
  • callback is the callback function that will be called when a change in one or more preferences is detected. This callback will receive a key-value object with the changed preferences and their new values.

Example usage:

MashupPlatform.prefs.registerCallback(function (new_values) {
    if ('some-pref' in new_values) {
        // some-pref has been changed
        // new_values['some-pref'] contains the new value
    }
});
set

Sets the value of a preference.

MashupPlatform.prefs.set(key, value)
  • key is the identifier of the preference.
  • value is the new value to use for the preference.

Example usage:

MashupPlatform.prefs.set('boolean-pref', true);

MashupPlatform.operator

This module is only available for operators.

id

returns the operator id.

MashupPlatform.operator.id
context

This attribute contains the context manager of the operator.

Example usage:

MashupPlatform.operator.context.get('version');
log

writes a message into the WireCloud's log console.

MashupPlatform.operator.log(msg, level)
  • msg is the text of the message to log.
  • level is an optional parameter with the level to uses for logging the message. (See #MashupPlatform.log for available log levels. default: MashupPlatform.log.ERROR).

Example usage:

MashupPlatform.operator.log('error message description');
MashupPlatform.operator.log('warning message description', MashupPlatform.log.WARN);

MashupPlatform.widget

This module is only available for widgets.

id

returns the widget id.

MashupPlatform.widget.id
context

This attribute contains the context manager of the widget.

Example usage:

MashupPlatform.widget.context.get('version');
getVariable

returns a widget variable by its name.

MashupPlatform.widget.getVariable(name)
  • name is the name of the variable to retrieve.

Example usage:

var variable = MashupPlatform.widget.getVariable('persistent-var');
variable.set(JSON.stringify(data));
drawAttention

makes WireCloud notify that the widget needs user's attention.

MashupPlatform.widget.drawAttention()
log

writes a message into the WireCloud's log console.

MashupPlatform.widget.log(msg, level)
  • msg is the text of the message to log.
  • level is an optional parameter with the level to uses for logging the message. (See #MashupPlatform.log for available log levels. default: MashupPlatform.log.ERROR).

Example usage:

MashupPlatform.widget.log('error message description');
MashupPlatform.widget.log('info message description', MashupPlatform.log.INFO);

MashupPlatform.wiring

pushEvent

sends an event through the wiring.

MashupPlatform.wiring.pushEvent(outputName, data)
  • outputName is the name of the output endpoint as defined in the MACDL.
  • data is the content of the event.

Example usage:

MashupPlatform.wiring.pushEvent('outputendpoint', 'event data');
registerCallback

registers a callback for a given input endpoint. If the given endpoint already has registered a callback, it will be replaced by the new one.

MashupPlatform.wiring.registerCallback(inputName, callback)
  • inputName is name of the input endpoint as defined in the MACDL.
  • callback is the callback function to use when an event reaches the given input endpoint.

Example usage:

MashupPlatform.wiring.registerCallback('inputendpoint', function (data_string) {
    var data = JSON.parse(data_string);
    ...
});

Pub Sub API

Once the pub sub add-on is installed and activated, widgets and operators declaring the use of the PubSub feature can take advantage of the PubSub functionalities through the MashupApplication.SilboPS object. Currently, the MashupApplication.SilboPS object only exports the PubEndPoint, SubEndPoint and Filter classes defined by the original javascript bindings provided by SilboPS. Full documentation of SilboPS is available at https://svn.forge.morfeo-project.org/4caast/trunk/WP6/pubsub/README.md.

Examples

Widget description using the XML flavour of the MACDL
<?xml version="1.0" encoding="UTF-8"?>
<Template xmlns="http://wirecloud.conwet.fi.upm.es/ns/template#">

    <Catalog.ResourceDescription>
        <Vendor>CoNWeT</Vendor>
        <Name>tourist-social-comments</Name>
        <DisplayName>Tourist - Social comments</DisplayName>
        <Version>0.27</Version>
        <Author>UPM</Author>
        <Mail>4caast@conwet.es</Mail>
        <Description>Chat widget for commenting about tourist locations. Uses Pub/Sub as communication channel</Description>
        <ImageURI>images/tourist-social.png</ImageURI>

        <Requirements>
            <Feature name="PubSub" />
        </Requirements>

    </Catalog.ResourceDescription>

    <Platform.Wiring>
        <InputEndpoint name="place" type="text" description="publish location" label="Messages Location" friendcode="connect_location" />
    </Platform.Wiring>

    <Platform.Link>
        <XHTML href="ps.html"/>
    </Platform.Link>

    <Platform.Rendering width="9" height="25"/>

</Template>
Widget description using the RDF flavour of the MACDL
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix usdl: <http://www.linked-usdl.org/ns/usdl-core#> .
@prefix vcard: <http://www.w3.org/2006/vcard/ns#> .
@prefix wire: <http://wirecloud.conwet.fi.upm.es/ns/widget#> .

<http://wirecloud.conwet.fi.upm.es/ns/widget#CoNWeT/tourist-social-comments/0.27> a wire:Widget;
    dcterms:creator [ a foaf:Person;
            foaf:name "UPM" ];
    dcterms:description "Chat widget for commenting about tourist locations. Uses Pub/Sub as communication channel";
    dcterms:title "tourist-social-comments";
    wire:displayName "Tourist - Social comments";
    wire:hasImageUri <images/tourist-social.png>;
    wire:hasPlatformRendering [ a wire:PlatformRendering;
            wire:renderingHeight "25";
            wire:renderingWidth "9" ];
    wire:hasPlatformWiring [ a wire:PlatformWiring;
            wire:hasInputEndpoint [ a wire:InputEndpoint;
                    rdfs:label "Messages Location";
                    dcterms:description "publish location";
                    dcterms:title "place";
                    wire:friendcode "connect_location";
                    wire:inputActionLabel "None";
                    wire:type "text" ] ];
    wire:hasRequirement [ a wire:Feature;
            rdfs:label "PubSub" ];
    usdl:hasProvider [ a <http://purl.org/goodrelations/v1#BusinessEntity>;
            foaf:name "CoNWeT" ];
    usdl:utilizedResource <ps.html>;
    usdl:versionInfo "0.27";
    vcard:addr [ a vcard:Work;
            vcard:email "4caast@conwet.es" ] .

<ps.html> a usdl:Resource;
    wire:codeCacheable "True" .
Publishing
  1. Get a PubEndpoint from the SilboPS.
    var myPubEndPoint = new MashupPlatform.SilboPS.PubEndPoint({
        open: function(endpoint) {
            // react to onopen.
        },
        close: function(endpoint) {
            // react to onclose.
        }
    );
    
  2. Create an Advertise object.
  3. var advertise = new MashupPlatform.SilboPS.Advertise()
                        .attribute("number", MashupPlatform.SilboPS.Type.LONG)
                        .attribute("other", MashupPlatform.SilboPS.Type.STRING);
    
  4. Advertise it.
    myPubEndPoint.advertise(advertise);
    
  5. Create a Notification object.
    var notification = new MashupPlatform.SilboPS.Notification()
                        .attribute("number", MashupPlatform.SilboPS.Type.LONG, 5)
                        .attribute("other", MashupPlatform.SilboPS.Type.STRING, "don't care");
    
  6. Publish it.
    myPubEndPoint.publish(notification);
    
  7. Close the endpoint.
    myPubEndPoint.close();
    
Subscribing
  1. Get a PubEndpoint from the SilboPS.
    var mySubEndPoint = new MashupPlatform.SilboPS.SubEndPoint({
        open: function(endpoint) {
                 // react to onopen.
        },
        close: function(endpoint) {
                 // react to onclose.
        },
        ...
        advertise: function(endpoint, advertise) {
                 // handle advertise
        },
        unadvertise: function(endpoint, unadvertise) {
                 // handle unadvertise
        },
        notify: function(endpoint, notification) {
                 // handle notification
        }
    });
    
  2. Subscribe to a filter.
    var cxtFunc = new MashupPlatform.SilboPS.ContextFunction();
    var filter = new MashupPlatform.SilboPS.Filter()
        .constrain("other", MashupPlatform.SilboPS.Type.STRING).startsWith("don't")
        .filter()
    
    mySubEndPoint.subscribe(filter, cxtFunc);
    
  3. Handle notifications.
    // Use "notify" handler.
    // ...
        notify: function(endpoint, notification) {
                 // handle notification
        }
    //...
    
  4. Close the endpoint
    mySubEndPoint.close();
    

NGSI API

First of all, widgets and operators wishing to use the javascript bindings provided by WireCloud for accessing the FI-WARE NGSI Open RESTful API in order to seamlessly interoperate with the Orion Pub/Sub Context Broker must add the NGSI feature as a requirement into their description files (config.xml files).

The following is an example of a widget description using the XML flavour of the MACDL:

<?xml version="1.0" encoding="UTF-8"?>
<Template xmlns="http://wirecloud.conwet.fi.upm.es/ns/template#">
    <Catalog.ResourceDescription>
        <Vendor>CoNWeT</Vendor>
        <Name>observation-reporter</Name>
        <DisplayName>Observation Reporter</DisplayName>
        <Author>aarranz</Author>
        <Version>1.0</Version>
        <Mail>aarranz@conwet.com</Mail>
        <Description>Creates a new observation</Description>
        <ImageURI>images/catalogue.png</ImageURI>
        <iPhoneImageURI>images/smartphone.png</iPhoneImageURI>
        <WikiURI>http://www.envirofi.eu/</WikiURI>

        <Requirements>
            <Feature name="NGSI"/>
        </Requirements>

    </Catalog.ResourceDescription>

    <Platform.Link>
        <XHTML href="index.html" content-type="text/html" cacheable="true" use-platform-style="true"/>
    </Platform.Link>

    <Platform.Rendering width="5" height="20"/>
</Template>

The RDF flavour of the same widget description is:

<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF
  xmlns:foaf="http://xmlns.com/foaf/0.1/"
  xmlns:wire="http://wirecloud.conwet.fi.upm.es/ns/widget#"
  xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
  xmlns:usdl="http://www.linked-usdl.org/ns/usdl-core#"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:ns1="http://purl.org/goodrelations/v1#"
  xmlns:dcterms="http://purl.org/dc/terms/"
  xmlns:vcard="http://www.w3.org/2006/vcard/ns#"
>
  <wire:Widget rdf:about="http://wirecloud.conwet.fi.upm.es/ns/widget#CoNWeT/observation-reporter/1.0">
    <vcard:addr>
      <vcard:Work rdf:nodeID="Nb17ce611aa2645e488515f86eb855e53">
        <vcard:email>aarranz@conwet.com</vcard:email>
      </vcard:Work>
    </vcard:addr>
    <usdl:utilizedResource>
      <usdl:Resource rdf:about="index.html">
        <wire:codeCacheable>True</wire:codeCacheable>
      </usdl:Resource>
    </usdl:utilizedResource>
    <wire:hasPlatformWiring>
      <wire:PlatformWiring rdf:nodeID="Neecb97db81ed40859b8c04e935a9a9cc"/>
    </wire:hasPlatformWiring>
    <wire:displayName>Observation Reporter</wire:displayName>
    <wire:hasiPhoneImageUri rdf:resource="images/smartphone.png"/>
    <usdl:versionInfo>1.0</usdl:versionInfo>
    <usdl:hasProvider>
      <ns1:BusinessEntity rdf:nodeID="N9a6bf56577c741ac806997a80281afff">
        <foaf:name>CoNWeT</foaf:name>
      </ns1:BusinessEntity>
    </usdl:hasProvider>
    <wire:hasImageUri rdf:resource="images/catalogue.png"/>
    <wire:hasPlatformRendering>
      <wire:PlatformRendering rdf:nodeID="N713e5ea11dce4750a592c754c748def7">
        <wire:renderingHeight>20</wire:renderingHeight>
        <wire:renderingWidth>5</wire:renderingWidth>
      </wire:PlatformRendering>
    </wire:hasPlatformRendering>
    <wire:hasRequirement>
      <wire:Feature rdf:nodeID="N3cb336bd9b6243ecbf345c80442498f9">
        <rdfs:label>NGSI</rdfs:label>
      </wire:Feature>
    </wire:hasRequirement>
    <dcterms:title>observation-reporter</dcterms:title>
    <dcterms:description>Creates a new observation</dcterms:description>
    <dcterms:creator>
      <foaf:Person rdf:nodeID="Ndb72cb5a7f3844b29b72f304baaa14a7">
        <foaf:name>aarranz</foaf:name>
      </foaf:Person>
    </dcterms:creator>
  </wire:Widget>
</rdf:RDF>

Once the NGSI feature is added to the widget/operator description file, widgets and operators will have access to the NGSI javascript object that conforms the core of the API. See the Publish/Subscribe Broker - Orion Context Broker - User and Programmers Guide for more details on the operations that can be invoked using the RESTful API. That guide can be used for reference as each of the Pub/Sub Context Broker operations have an equivalent operation in the javascript bindings.

What follows exemplifies the use of this API for updating an entity.

var connection = new NGSI.Connection('<url of the Orion Pub/Sub Context Broker instance>');
connection.updateAttributes([{
    entity: {
        id: 'iss8',
        type: 'Issue'
    },
    attributes:[{
        name: 'technician',
        contextValue: 'tech1'
    }]
}], {
    onSuccess: function () {
        // notify success
    },
    onFailure: function () {
        // show error
    }
});

Data types used by the library

  • The Entity type is used to reference entities. This type is defined as an object composed of the following fields:
    • id is a string with the id of the entity. Some times you will be able to use patterns in this field.
    • isPattern is a boolean indicating whether the id field contains a regular expression pattern. This field is optional.
    • type is the type of the entity. This field is optional.
  • The Attribute type is used to reference attributes. This type is defined as an object composed of the following fields:
    • name is the name of the attribute.
    • type is the type of the Attribute. This field is optional.
  • The Condition type is used to declare the condition that will trigger notifications. This type is defined as an object composed of the following fields:
    • type is an String containing 'ONTIMEINTERVAL' or 'ONCHANGE'.
    • values is an Array of String. The meaning of this field depends on the value of the type field:
      • 'ONTIMEINTERVAL': exactly one value SHALL be present and SHALL represent the time interval between notifications (using the Duration type).
      • 'ONCHANGE': this element SHALL contain the name(s) of the Context Attributes to be monitored for changes.
  • The AttributeValue type is used to assign values to attributes. This type is defined as an object composed of the following fields:
    • name is the name of the attribute.
    • type is the type of the attribute. This field is optional.
    • contextValue is the value to assign to the attribute.
  • The AttributeUpdate type is used to describe a context update. This type is defined as an object composed of the following fields:
    • entity is the entity affected by the update. Type: Entity.
    • attributes is the new values for the attributes of the entity. Type: AttributeValue.
  • The AttributeDeletion type is used to describe the deletion of attributes from an entity. This type is defined as an object composed of the following fields:
    • entity is the entity affected by the update. Type:Entity.
    • attributes is the new values for the attributes of the entity. Type:Attribute.

NGSI.Connection

A new NGSI.Connection can be instantiated using the following constructor:

 NGSI.Connection(url[, options])
  • url (String): is the url of the Orion Pub/Sub Context Broker instance.
  • options (Object; default null):is an object with extra options. This parameter may be null if no extra option is needed. Current supported options are:
    • ngsi_proxy_url (String; default null): URL of the NGSI proxy used for subscriptions.
    • request_headers (Object; default null): A set of key-value pairs, with properties representing header names. These extra headers will be use when making request to the context broker.
    • use_user_fiware_token (Boolean; default: false): Use current user authentication token retrieved from the IdM system.

All the methods of NGSI.Connection supports an options parameter. This parameter is used, among other things, to pass callbacks functions. This parameter is a JavaScript object containing pairs of key value options. Moreover, all the method of NGSI.Connection support at least the following callbacks:

  • onSuccess is called when the request finishes successfully. The parameters passed to this callback depends on the invoked method.
  • onFailure is called when the request finish with errors.
  • onComplete is called when the request finish regardless of whether the request is successful or not.
createRegistration

Register context information (entities and attributes) in the NGSI server.

createRegistration(entities, attributes, duration, providingApplication[, options])
  • entities is the list of Entities that are going to be registered.
  • attributes is a list of the Attributes that are going to be assigned to the previous list of entities.
  • duration is the Duration for this registration.
  • providingApplication is the URI of the application to which this registration belongs to.


The onSuccess callback will receive an object with the following fields:

  • registrationId is the final assigned id. This id can be used in the updateRegistration and cancelRegistration methods.
  • duration is the final assigned duration for this registration.

Usage example:

connection.createRegistration([
        {type: 'Technician', id: 'entity1'}
    ], [
        {name: 'attr1', type: 'string'},
        {name: 'attr2'},
        {name: 'attr3', type: 'number'}
    ],
    'PT24H',
    'http://app.example.com/',
    {
        onSuccess: function (data) {
            //data.subscriptionId
        }
    }
)
updateRegistration

Updates a particular registration.

updateRegistration(regId, entities, attributes, duration, providingApplication[, options])
  • regId is the id of the registration to update.
  • entities is the list of Entities that its going to replace the previous established one.
  • attributes is a list of the Attributes that are going to be assigned to the provided list of entities.
  • duration is the new Duration for the registration identified by regId.
  • providingApplication is the new value for the providingApplication property of the registration.


The onSuccess callback will receive an object with the following fields:

  • registrationId is the id of the registration.
  • duration is the final assigned duration for this registration.


Example usage:

connection.updateRegistration("167",
    [
        {type: 'Technician', id: 'entity1'}
    ],
    [
        {name: 'attr1', type: 'string'},
        {name: 'attr2'}
    ],
    'PT24H',
    'http://app.example.com/'
);
cancelRegistration

Cancels or deletes a particular registration.

cancelRegistration(regId[, options])
  • regId is the id of the registration to cancel.

Example usage:

connection.cancelRegistration("167", {
    onSuccess: function () {
        // Registration cancelled successfully
    }
});
discoverAvailability

Discover context information registrations in the NGSI server.

discoverAvailability(entities, attributeNames[, options])
  • entities is the list of Entities that are going to be queried.
  • attributeNames is the list of attribute names that are going to be queried. This parameter is optional and thus null is a valid value.

Example usage:

connection.discoverAvailability([
        {type: 'Technician', id: 'entity1'},
        {type: 'Van', id: '.*', isPattern: true},
    ],
    null,
    {
        onSuccess: function (registrations) {
            ...
        }
    }
);
query

Query for context information.

query(entities, attributeNames[, options])
  • entities is the list of Entities to query.
  • attributeNames is the list of attribute names to query. Use null for retrieving all the attributes.

The query method supports an extra option:

  • flat (Boolean; default: false): This options is used for simplifying the data structure used for representing the returned data. This simplification relies in making the following assumptions about the returned entry set:
    • given an entity id there is only one value for the entity's type parameter
    • entities doesn't have attributes called id or type
    • entities have only an attribute with a given name
    • attribute types don't matter or are already known

For example, this is the value of the data parameter passed to the onSuccess callback when using the flat is false (default value):

[
    {
        "entity": {
            "id": "van1",
            "type": "Van"
        },
        "attributes": [
            {
                "name": "current_position",
                "type": "coordinates",
                "contextValue": "43.47557, -3.8048315"
            }
        ]
    },
    {
        "entity": {
            "id": "van2",
            "type": "Van"
        },
        "attributes": [
            {
                "name": "current_position",
                "type": "coordinates",
                "contextValue": "43.47258, -3.8026643"
            }
        ]
    },
    {
        "entity": {
            "id": "van3",
            "type": "Van"
        },
        "attributes": [
            {
                "name": "current_position",
                "type": "coordinates",
                "contextValue": "43.47866, -3.7991238"
            }
        ]
    },
    {
        "entity": {
            "id": "van4",
            "type": "Van"
        },
        "attributes": [
            {
                "name": "current_position",
                "type": "coordinates",
                "contextValue": "43.471214, -3.7994885"
            }
        ]
    }
]

Whereas this is the value of the data parameter when flat is true:

{
    "van1": {
        "id": "van1",
        "type": "Van",
        "current_position": "43.47557, -3.8048315"
    },
    "van2": {
        "id": "van2",
        "type": "Van",
        "current_position": "43.47258, -3.8026643"
    },
    "van3": {
        "id": "van3",
        "type": "Van",
        "current_position": "43.47866, -3.7991238"
    },
    "van4": {
        "id": "van4",
        "type": "Van",
        "current_position": "43.471214, -3.7994885"
    }
}

Example usage:

connection.query([
        {type: 'Technician', id: '.*', isPattern: true}
    ],
    null,
    {
        limit: 100,
        offset: 200,
        details: true
        onSuccess: function (data, details) {
            ...
        }
    }
);
updateAttributes

Update context information.

updateAttributes(update[, options])
  • update a list of AttributeUpdates.

Example usage:

connection.updateAttributes([
        {
            'entity': {type: 'Technician', id: 'entity1'},
            'attributes': [
                {name: 'mobile_phone', type: 'string', contextValue: '0034223456789'},
                {name: 'attr2', contextValue: 'value'},
                {name: 'attr3', contextValue: 5}
            ]
        }
    ], {
        onSuccess: function (data) {
        }
    }
);
addAttributes

Add/update entity attributes. This operation will create the attribute on those entities where they doesn't exist. In addition to this, this operation will also create entities if they doesn't exist (provided that entities were referenced without using patterns).

addAttributes(toAdd[, options])
  • toAdd a list of AttributeUpdates.

Example usage:

connection.addAttributes([
        {
            'entity': {type: 'Technician', id: 'entity1'},
            'attributes': {
                'name': 'new_attribute',
                'type': 'string',
                'contextValue': 'value'
            }
        }
    ], {
        onSuccess: function (data, partial_errors) {
        }
    }
);
deleteAttributes

Delete attributes form entities.

deleteAttributes(toDelete[, options])
  • toDelete a list of AttributeDeletion.

The `onSuccess` callback will receive an array with the response and a array with the not accepted updates as the first and the second parameter respectively.

Example usage:

connection.deleteAttributes([
        {
            'entity': {type: 'City', id: 'Madrid'},
            'attributes': {
                'name': 'position',
                'type': 'coords'
            }
        }
    ], {
        onSuccess: function (data, partial_errors) {
        }
    }
);
createSubscription

Subscribe to changes in the context information.

createSubscription(entities, attributeNames, duration, throttling, conditions, options)
  • entities is the list of Entities to query in this subscription.
  • attributeNames is the list of attribute names to query in this subscription.
  • duration is the Duration of this subscription.
  • throttling is the proposed minimum interval between notifications. This value must be provided using the Duration type. null is also valid.
  • conditions is a list of Conditions that will trigger queries using the provided information and their subsequent notifications to the onNotify callback.

This method, supports a new type of callback: onNotify. This callback is required and can be either an URL or a function. In the later case, the NGSI Connection must be created using a NGSI proxy and will be called every time a notification comes from the NGSI server.

The first parameter of a onNotify callback function will be an object with the response data.

Example usage:

connection.createSubscription([
        {type: 'Technician', id: 'tech*', isPattern: true},
        {type: 'Van', id: 'van1'},
    ],
    null,
    'PT24H',
    null,
    [{type: 'ONCHANGE', condValues: ['position']}],
    {
        onNotify: function (data) {
            // called when a notification arrives
        },
        onSuccess: function (data) {
            // subscription created successfully
            // data.subscriptionId contains the id associated with the created subscription
        }
    }
);
updateSubscription

Update context subscription.

updateSubscription(subId, duration, throttling, conditions[, options])
  • subId is the id of the context subscription to cancel.
  • duration is the Duration of this subscription.
  • throttling is the proposed minimum interval between notifications. This value must be provided using the Duration type. null is also valid.
  • conditions is a list of Conditions that will trigger queries using the provided information and their subsequent notifications to the onNotify callback.

Example usage:

connection.updateSubscription('5523abc11860a32c3dd51882',
    'PT20H',
    null,
    null,
    {
        onSuccess: function (response_data) {
            // subscription updated successfully
        }
    }
);
cancelSubscription

Cancels or deletes context subscriptions. A subscription cannot be updated after being cancelled.

cancelSubscription(subId[, options])
  • subId is the id of the context subscription to cancel.


Example usage:


connection.cancelSubscription('5523abc11860a32c3dd51882',
    {
        onSuccess: function (data) {
            // Subscription canceled successfully
            // data.subscriptionId should be equal to 'sub1'
        }
    }
);

ObjectStorage API

First of all, widgets and operators wishing to use the javascript bindings provided by WireCloud for accessing the FI-WARE Object Storage Open RESTful API in order to seamlessly interoperate with the Object Storage must add the ObjectStorage feature as a requirement into their description files (config.xml files).

The following is an example of a widget description using the XML flavour of the MACDL:

<?xml version="1.0" encoding="UTF-8"?>
<Template xmlns="http://wirecloud.conwet.fi.upm.es/ns/template#">
    <Catalog.ResourceDescription>
        <Vendor>CoNWeT</Vendor>
        <Name>observation-reporter</Name>
        <DisplayName>Observation Reporter</DisplayName>
        <Author>aarranz</Author>
        <Version>1.0</Version>
        <Mail>aarranz@conwet.com</Mail>
        <Description>Creates a new observation</Description>
        <ImageURI>images/catalogue.png</ImageURI>
        <iPhoneImageURI>images/smartphone.png</iPhoneImageURI>
        <WikiURI>http://www.envirofi.eu/</WikiURI>

        <Requirements>
            <Feature name="ObjectStorage"/>
        </Requirements>

    </Catalog.ResourceDescription>

    <Platform.Link>
        <XHTML href="index.html" content-type="text/html" cacheable="true" use-platform-style="true"/>
    </Platform.Link>

    <Platform.Rendering width="5" height="20"/>
</Template>

The RDF flavor of the same widget description is:

<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF
  xmlns:foaf="http://xmlns.com/foaf/0.1/"
  xmlns:wire="http://wirecloud.conwet.fi.upm.es/ns/widget#"
  xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
  xmlns:usdl="http://www.linked-usdl.org/ns/usdl-core#"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:ns1="http://purl.org/goodrelations/v1#"
  xmlns:dcterms="http://purl.org/dc/terms/"
  xmlns:vcard="http://www.w3.org/2006/vcard/ns#"
>
  <wire:Widget rdf:about="http://wirecloud.conwet.fi.upm.es/ns/widget#CoNWeT/observation-reporter/1.0">
    <vcard:addr>
      <vcard:Work rdf:nodeID="Nb17ce611aa2645e488515f86eb855e53">
        <vcard:email>aarranz@conwet.com</vcard:email>
      </vcard:Work>
    </vcard:addr>
    <usdl:utilizedResource>
      <usdl:Resource rdf:about="index.html">
        <wire:codeCacheable>True</wire:codeCacheable>
      </usdl:Resource>
    </usdl:utilizedResource>
    <wire:hasPlatformWiring>
      <wire:PlatformWiring rdf:nodeID="Neecb97db81ed40859b8c04e935a9a9cc"/>
    </wire:hasPlatformWiring>
    <wire:displayName>Observation Reporter</wire:displayName>
    <wire:hasiPhoneImageUri rdf:resource="images/smartphone.png"/>
    <usdl:versionInfo>1.0</usdl:versionInfo>
    <usdl:hasProvider>
      <ns1:BusinessEntity rdf:nodeID="N9a6bf56577c741ac806997a80281afff">
        <foaf:name>CoNWeT</foaf:name>
      </ns1:BusinessEntity>
    </usdl:hasProvider>
    <wire:hasImageUri rdf:resource="images/catalogue.png"/>
    <wire:hasPlatformRendering>
      <wire:PlatformRendering rdf:nodeID="N713e5ea11dce4750a592c754c748def7">
        <wire:renderingHeight>20</wire:renderingHeight>
        <wire:renderingWidth>5</wire:renderingWidth>
      </wire:PlatformRendering>
    </wire:hasPlatformRendering>
    <wire:hasRequirement>
      <wire:Feature rdf:nodeID="N3cb336bd9b6243ecbf345c80442498f9">
        <rdfs:label>ObjectStorage</rdfs:label>
      </wire:Feature>
    </wire:hasRequirement>
    <dcterms:title>observation-reporter</dcterms:title>
    <dcterms:description>Creates a new observation</dcterms:description>
    <dcterms:creator>
      <foaf:Person rdf:nodeID="Ndb72cb5a7f3844b29b72f304baaa14a7">
        <foaf:name>aarranz</foaf:name>
      </foaf:Person>
    </dcterms:creator>
  </wire:Widget>
</rdf:RDF>

Once the ObjectStorage feature is added to the widget/operator description file, widgets and operators will have access to the ObjectStorageAPI javascript object that conforms the core of the API. See the Object Storage - User and Programmers Guide for more details on the operations that can be invoked using the RESTful API. That guide can be used for reference as each of the Object Storage operations have an equivalent operation in the javascript bindings.

What follows exemplifies the use of this API for uploading a File.

 var object_storage = new ObjectStorageAPI('<url of the Object Storage instance>');
 
 var fileParts = ["<a id=\"a\"><b id=\"b\">hey!<\/b><\/a>"];
 var myBlob = new Blob(fileParts, { "type" : "text\/xml" });
 
 object_storage.uploadFile('folder_name', myBlob, token, {
     file_name: 'myFile.xml',
     onSuccess: function () {
         alert('File uploaded successfully');
     },
     onFailure: function () {
         alert('Something went wrong while uploading the file');
     }
 });

KeystoneAPI

A new KeystoneAPI can be instantiated using the following constructor:

 KeystoneAPI(url, options)
  • url is the url of the Keystone server.
  • options:
    • token (String): is the token to used for authenticating request to the Keystone server.
    • use_user_fiware_token (Boolean): make KeystoneAPI to use the token obtained by WireCloud for the current user from the FI-WARE's IdM server. Takes precedence over the token option.

The token and use_user_fiware_token options are optional. When passed to the KeystoneAPI constructor, these values are stored internally and used as the default value in the invocation of its methods. In any case, these options can also be passed to the KeystoneAPI methods.

getTenants

List all of the tenants in the keystone server available for the authenticated user.

getTenants([options])

The onSuccess callback will receive the list of tenants as the first argument.

getAuthToken

Gets an authentication token that permits access to the Object Storage API.

getAuthToken([options])

Extra options:

  • tenantName (String): The name of the tenant to be associated to the generated token. Both the tenantId and tenantName attributes are optional, but should not be specified together.
  • tenantId (String): The id of the tenant to be associated to the generated token. Both the tenantId and tenantName attributes are optional, but should not be specified together.

The onSuccess callback will receive auth token info as the first argument.

ObjectStorageAPI

A new ObjectStorageAPI can be instantiated using the following constructor:

 ObjectStorageAPI(url[, options])
  • url is the url of the Object Storage server.
  • options:
    • token (String): is the token to use by default for authenticating requests to the Object Storage server.

All the methods of ObjectStorageAPI supports an options parameter. This parameter is used, among other things, to pass callbacks functions. This parameter is a JavaScript object containing pairs of key value options. Moreover, all the method of ObjectStorageAPI support at least the following option:

  • token (String): is the token to used for authenticating the request.

and the following callbacks:

  • onSuccess is called when the request finishes successfully. The parameters passed to this callback depends on the invoked method.
  • onFailure is called when the request finish with errors.
  • onComplete is called when the request finish regardless of whether the request is successful or not.
createContainer

Creates a container in which other containers and objects can be stored.

createContainer(container[, options])
  • container is the name of the container to create.
listContainer

Returns a list of the contents of a container.

listContainer(container[, options])
  • container is the name of the container to list.
deleteContainer

Deletes a specified container from the storage system.

deleteContainer(container[, options])
  • container is the name of the container to delete.
getFile

Retrieves a specified object from the storage system.

getFile(container, file_name[, options])
  • container is the name of the container where the file is.
  • file_name is the name of the file to download.

Extra options:

  • response_type (String, default: "blob"): Valid values are all the supported by the responseType option (see the request options section for more details), except "".
uploadFile

Stores a binary object in the specified location.

uploadFile(container, file[, options])
  • container is the name of the container where the file is going to be uploaded.
  • file is the content to be uploaded. Must be an instance of Blob or File.

Extra options:

  • file_name: name to use for uploading the file. This option is required when passing a Blob as the file argument. This option is not required when passing a File instance as the name is obtained from its name attribute. Anyway, the name passed with this options has precedence over the name attribute of the File instances.
deleteFile

Deletes a specified object from the storage system.

deleteFile(container, file_name[, options])
  • container is the name of the container where the file is going to be deleted.
  • file_name is the name of the file to delete.

WireCloud IDE

Installation

  • Download the latest version of the "Eclipse IDE for Java EE Developers" package for your platform from the Eclipse's downloads section.
  • Download the WireCloud IDE plugin from the FI-WARE PPP Public Files area.
  • Install the WireCloud IDE plugin:
    • Help -> Install New Software...
    • Add a new repository using the Add button
    • Click Archive and select the WireCloud IDE plugin file downloaded in previous steps
    • Select the WireCloud IDE entry
    • Click Next and complete the wizard.

Adding WireCloud servers

WireCloud IDE support deploying Widget/Operator projects into WireCloud servers. You can manage WireCloud servers from the "Server" view (usually located in the lower half of Eclipse's development screen). If you don't have such a view, you can add it via Window -> Show View -> Servers:

  • Right click inside the "Server" tab to open the New Server dialogue:
  • In the next step, select WireCloud as the type of server to define (you will find it under the CoNWeTLab category), update the host name of the server where WireCloud is located and give it a name. After filling this info, click Next:
  • Review the protocol and port configuration. You will also need to provide a client id and a client secret obtained from the IdM (see how to create new OAuth2 applications on the KeyRock's User and Programmers Guide). You will need to use [WIRECLOUD_SERVER_URL]/oauth2/default_redirect_uri for the callback URL field. Once finished click Next:
  • The next step is authorising WireCloud IDE to install and uninstall resources on the server. This will require you to log in to the WireCloud server.
  • And to confirm the authorisation:
  • After which, a confirmation message should be displayed:
  • At this step you can choose between clicking Next and selecting a list of projects to upload initially to the server, or clicking Finish as all the required info has been provided. In any case, after finishing the wizard, a new WireCloud server should appear in the "Server" tab:

How to create Widget/Operator projects from scratch

  • Open the new project wizard page:
  • And select the Widget/Operator project depending on the type of resource you want to create (you will find them on the Wirecloud Project category):
  • Give a name to the project and click Finish:

Once created the project, you will obtain the following features in addition to the ones provided directly by Eclipse:

  • JavaScript API autocompletion.
  • Assistance for editing Widget/Operator descriptions.
  • Support for installing and uninstalling them from the configure WireCloud servers.

Tutorial

  • First of all, download this initial code from this link. This code contains a widget example skeleton including basic html/style code.
  • Import the downloaded file into a Widget project:
  • Follow the "Making requests and wiring" tutorial.
  • Add the widget to the WireCloud server using the Servers view (see the Adding WireCloud servers sections for more info). The first step is opening the "Add and remove ..." view:
  • Once opened the "Add and Remove" view, you will need to move the project from the available section to the configured one:
  • Click Finish and the widget will be uploaded to the selected server where you will be able to test your widget following the steps documented on the tutorial.

Additional sources of information

See the Application Mashup GE fundamentals course at the FIWARE Academy for detailed documentation on how to use WireCloud from different perspectives (end-user, developer and administrators). Another source of information is the WireCloud website where you can find more general information and other interesting resources such as demo videos.

Personal tools
Create a book