Object Storage offers persistent storage for binary objects. Objects are stored in named locations known as containers. Containers can be nested thus objects can be stored hierarchically. The main aim of this section is to show an example that allows you to understand how to use this API.
If you want to use this feature, first of all you have to modify your config.xml
file and add a new Feature
named ObjectStorage within Requirements. For example, if you use XML to set up the configuration of your widget, your code should look similar to the following one. Note that we have also added a preference that will be useful to store the KeyStone server URL.
<?xml version='1.0' encoding='UTF-8'?>
<widget xmlns="http://wirecloud.conwet.fi.upm.es/ns/macdescription/1" vendor="Wirecloud" name="objectstorage-test-widget" version="1.0">
<details>
<title>Wirecloud Object Storage API test widget</title>
<authors>aarranz</authors>
<email>aarranz@conwet.com</email>
<image>images/catalogue.png</image>
<smartphoneimage>images/catalogue_iphone.png</smartphoneimage>
<description>This widget is used to test whether the Object Storage API is usable by widgets</description>
<doc>doc/index.html</doc>
</details>
<requirements>
<feature name="ObjectStorage"/>
</requirements>
<preferences>
<preference name="keystone_url" type="text" label="Keystone Server" description="Keystone Server where the Object Storage server to use for testing the integration between Wirecloud and the Object Storage GE is registered" default="https://cloud.lab.fiware.org/keystone"/>
</preferences>
<wiring/>
<contents src="test.html" contenttype="text/html" charset="utf-8" useplatformstyle="true"/>
<rendering height="24" width="6"/>
</widget>
In case you prefer to use RDF, your code should be similar to the following one:
!
<?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:gr="http://purl.org/goodrelations/v1#"
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: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#Wirecloud/objectstorage-test-widget/1.0">
<dcterms:creator>
<foaf:Person rdf:nodeID="N2cda3cef67eb47558145c705d0d3b191">
<foaf:name>aarranz</foaf:name>
</foaf:Person>
</dcterms:creator>
<wire:displayName>Wirecloud Object Storage API test widget</wire:displayName>
<foaf:page rdf:resource="doc/index.html"/>
<dcterms:description>This widget is used to test whether the Object Storage API is usable by widgets</dcterms:description>
<wire:hasPlatformPreference>
<wire:PlatformPreference rdf:nodeID="Nf5128b00c737420f91385f002c272954">
<dcterms:description>Keystone Server where the Object Storage server to use for testing the integration between Wirecloud and the Object Storage GE is registered</dcterms:description>
<rdfs:label>Keystone Server</rdfs:label>
<wire:index>0</wire:index>
<wire:type>text</wire:type>
<dcterms:title>keystone_url</dcterms:title>
<wire:default>https://cloud.lab.fiware.org/keystone</wire:default>
</wire:PlatformPreference>
</wire:hasPlatformPreference>
<wire:hasImageUri rdf:resource="images/catalogue.png"/>
<usdl:versionInfo>1.0</usdl:versionInfo>
<dcterms:title>objectstorage-test-widget</dcterms:title>
<vcard:addr>
<vcard:Work rdf:nodeID="N353ea6f0c6c24daf8e3e2ba8b1b6396c">
<vcard:email>aarranz@conwet.com</vcard:email>
</vcard:Work>
</vcard:addr>
<usdl:hasProvider>
<gr:BusinessEntity rdf:nodeID="Naf20bf95bb5d4a6484f501744b75deb4">
<foaf:name>Wirecloud</foaf:name>
</gr:BusinessEntity>
</usdl:hasProvider>
<wire:hasPlatformWiring>
<wire:PlatformWiring rdf:nodeID="Na67dd8db508d48338034a1f14ab4f2c9"/>
</wire:hasPlatformWiring>
<usdl:utilizedResource>
<usdl:Resource rdf:about="test.html">
<wire:usePlatformStyle>true</wire:usePlatformStyle>
</usdl:Resource>
</usdl:utilizedResource>
<wire:hasPlatformRendering>
<wire:PlatformRendering rdf:nodeID="Nb55500a19f324a88bc5eff01d3d0bd8d">
<wire:renderingHeight>24</wire:renderingHeight>
<wire:renderingWidth>6</wire:renderingWidth>
</wire:PlatformRendering>
</wire:hasPlatformRendering>
<!-- Here we add the Feature -->
<wire:hasRequirement>
<wire:Feature rdf:nodeID="N2cdd6eec5a4c43ad8cd68d09f51c100c">
<rdfs:label>ObjectStorage</rdfs:label>
</wire:Feature>
</wire:hasRequirement>
<wire:hasiPhoneImageUri rdf:resource="images/catalogue_iphone.png"/>
</wire:Widget>
</rdf:RDF>
To start using the ObjectStorage, first you have to set up the connection with the KeyStone server. To do so, you should create a new KeystoneAPI
:
var keystone = new KeystoneAPI(url, options)
See the ObjectStorage Javascript API documentation for the full list of supported options but, as summary, the url
is the ObjectStorage Server location. Also, if you are connecting to a ObjectStorage instance using the IdM authentication, you will need to pass the required authentication credentials. This can be accomplished in two ways:
token
option and passing directly the required Authentication headeruse_user_fiware_token
option to make the ObjectStorage use the token obtained by WireCloud from the IdMThis example shows you how to connect with the KeyStone server using the resources available in the FIWARE Testbed. Note that the Keystone URL used is the one obtained from the preferences:
var keystone = new KeystoneAPI(MashupPlatform.prefs.get('keystone_url'), {
use_user_fiware_token: true
});
Once that you are connected with the KeyStone server, you have to take into account is that a user can use several tenants to store the information. To get the list of available tenants for a user, you can use the getTenants
function:
keystone.getTenants([options])
The options
argument allows you to set two callbacks:
onSuccess
is called when the request finishes successfully. This function will receive a dictionary with the field tenants that contains all the available tenants for the user that make the requestonFailure
is called when the request finish with errorsIn the following example, we call the function with both callbacks. If the request finish successfully, we will show the id of the first available tenant. Otherwise, we will show a message error:
keystone.getTenants({
onSuccess: function(data) {
document.getElementById('tenantId').textContent = data.tenants[0].id;
},
onFailure: function () {
document.getElementById('tenantId').textContent = 'Fail';
}
});
When you have selected the tenant that you want to use, you must get an authentication token using the getAuthToken
function:
keystone.getAuthToken([options])
options
argument include the following fields:
tenantName
: name of the tenant to be associated to the generated token. Both
the tenantId
and tenantName
attributes are optional, but should not be
specified togethertenantId
: 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 togetheronSuccess
: called when the request finishes successfully. This function will
receive two parameters:new_token
: the new token obtained that you can use to access the
ObjectStoragedata
: the catalogue of available services for the tenantonFailure
: called when the request finish with errorsThe next snippet shows you how to use this function. In this case we will use the tenant id obtained in the previous code. Note that we will also process the data parameter in order to get the ObjectStorage URL:
keystone.getAuthToken({
tenantId: data.tenants[0].id,
onSuccess: function (new_token, data) {
for (i = 0; i < data.access.serviceCatalog.length; i++) {
if (data.access.serviceCatalog[i].type === 'object-store') {
object_storage = data.access.serviceCatalog[i].endpoints[0].publicURL;
}
}
},
onFailure: function () {
document.getElementById('api_token').textContent = 'Fail';
}
});
Once that you have the URL of the ObjectStorage server, we can connect to it. To do so, we must use the following function:
objectStorage = ObjectStorageAPI(url)
In our case we have saved the ObjectStorage Server URL in the object_storage
variable, so our code should be the following one:
objectStorage = ObjectStorageAPI(object_storage)
When we are connected to a ObjectStorage Server, we are able to list all the content available in a container. To do so, we should use the listContainer
function:
objectStorage.listContainer(container[, options])
The container
argument is the name of the container while the options
argument should contain the following fields:
token
: The token obtained previously in the getAuthToken
functiononSuccess
: called when the request finishes successfully. This function
receives as argument the list of available files in the containeronFailure
: called when the request finish with errorsIn the next example, we will show we will get the available files in the integrationTests container, and we will show the name of the first one.
objectStorage.listContainer('integrationTests', {
token: token,
onSuccess: function(file_list) {
document.getElementById('file_name').textContent = file_list[0].name;
},
onFailure: function () {
document.getElementById('file_count').textContent = 'Fail';
}
});
If you are connected to the ObjectStorage, you can also upload a file easily. To do so, you must use the uploadFile function:
objectStorage.uploadFile(container, file[, options])
container
is the name where the file
is going to be uploaded, while file is
the content to be uploaded. The options
argument should contain the following
fields:
token
: The token
obtained previously in the getAuthToken
functionfile_name
: The name used to save the uploaded content in the container
onSuccess
: called when the request finishes successfully. This function does
not receive any argumentsonFailure
: called when the request finish with errorsHere you can see how to upload a text file containing "Hello world!".
var blob = new Blob(["Hello world!"], { type: "text/plain" });
objectStorage.uploadFile('integrationTests', blob, {
token: token,
file_name: 'test1.txt',
onSuccess: function() {
document.getElementById('file_upload').textContent = 'OK';
},
onFailure: function () {
document.getElementById('file_upload').textContent = 'Fail';
}
});
It's useful to upload a file, but in some occasions you will want to delete it.
To do so, you have to use the deleteFile
function:
objectStorage.deleteFile(container, file_name[, options])
container
is the name of the container where the file is going to be deleted
while file_name
is the name of the file to delete. The options
argument
should contain the following fields:
token
: The token obtained previously in the getAuthToken
functiononSuccess
: called when the request finishes successfully. This function does
not receive any argumentsonFailure
: called when the request finish with errorsThe following example shows how to delete the file that we have created in the previous step:
objectStorage.deleteFile('integrationTests', file_name, {
token: token,
onSuccess: function() {
document.getElementById('file_deletion').textContent = 'OK';
},
onFailure: function () {
document.getElementById('file_deletion').textContent = 'Fail';
}
});
We think that the best way to learn to use this feature is using it. For this reason we offer you a very simple example based on this guide. Check the code and modify as you like and test if it works. This widget will only work if you create a instanceTests container before running it, otherwise it will fail.
Table of Contents | t |
---|---|
Exposé | ESC |
Full screen slides | e |
Presenter View | p |
Source Files | s |
Slide Numbers | n |
Toggle screen blanking | b |
Show/hide slide context | c |
Notes | 2 |
Help | h |