Intel Cloud Platform: Context Services

pullfarmInternet και Εφαρμογές Web

3 Νοε 2013 (πριν από 3 χρόνια και 10 μήνες)

121 εμφανίσεις




Intel
Cloud
Platform:
Context

Services

June

1
7

2013

This document is part of a series focused on the Intel® Cloud Service
Platform APIs: Identity, Location Based, Commerce and Context. This
document explores
Context

Services specifically and how best to
develop using these features on Android,
Windows 8

and
Tizen

devices.

Documentation
for Developers
Using Intel
Identity Based
Cross
-
Platform
APIs on Varied
Devices






2


Contents

Introduction

................................
................................
................................
................................
..................

3

Intel Cloud Services Platform

................................
................................
................................
........................

3

Intel Developer Portal

................................
................................
................................
................................
...

3

A Revi
ew of Intel Cloud Identity Services

................................
................................
................................
.....

4

Using Intel Cloud Context Services


Android

................................
................................
...............................

4

Using Intel Cloud Context Services


Windows 8

................................
................................
.........................

9

Using Intel Cloud Location Services


Tizen

................................
................................
................................

12

Closing

................................
................................
................................
................................
.........................

19




3


Introduction

The Intel Cloud Services Platform is web
-
based functionality providing identity, location
-
based, commerce
and context services for use in desktop and mobile applications for both business and consumer use. In
this whitepaper, we will show how to use the In
tel®
Context

Services of the Intel Cloud Services Platform
API

on a variety of platforms.
The
Context Services APIs enable you to build context
-
aware applications
and services that are aware of, responsive to, and personalized to a user's situation while
empowering
users with ultimate control over their privacy.



Store and retrieve context.



Enable users to control access to their data.



Watch for new context and get automatic notifications.



Predict next location and cuisine preferences.

Intel Cloud Services

Platform

Intel® Cloud Services Platform is a set of online cloud
-
based, scalable services that provide key
capabilities such as location, identity, commerce and context to developers for use in server, desktop and
mobile applications aimed at both consum
ers and businesses. All services are identity
-
based to provide
rich interoperability and seamless app experiences.

For developers, Intel Identity Services provide a mechanism to build apps that use one identity service to
carry users across devices and pla
tforms. We understand that managing and storing data associated with
user profiles can be very cumbersome. These identity services were built to provide simpler data
management, storage and user profile management.

Today, limited interoperability across m
ultiple cloud services results in restricted sharing of data between
applications and services. When creating an application of any complexity, developers must often focus
on data handoff between services and multiple function calls

yet most of this work i
s not part of
developers’ core value add. Non
-
value
-
add work, especially on things like management of user
information that crosses more than one business domain or environment, saps precious development
time. This set of independent, affiliated cloud serv
ices, accessed via RESTful APIs, provides
differentiated capabilities. Because REST uses the HTTP protocol, it is supported in any language and
development environment that can do TCP/IP networking with the proper HTTP constructs.

Intel Developer Portal

Th
e first step in application development starts with the Intel® Developer Dashboard.

As a registered Intel
®

Cloud Services Platform developer, you can access all your profile information on
the Developer Portal at
https://cloudapi.intel.com
. Refer to
Intel Cloud Services Developer Sign
-
up
Tutorial

at
http://software.intel.com/en
-
us/articles/intel
-
cloud
-
service
-
register
-
tutorial

for information about
creating your Intel® Identity Services account. The developer dashboard helps you create and manage
your applications, provides statistics about your cloud

services API usage, and allows you to configure
your digital store.

4


A Review of Intel Cloud Identity Services

Identity Services are intended

to perform various operations such as user authentication, fetching user
profiles, modifying said profiles and so
forth. All CSP applications require the use of Intel® Identity
Service to authenticate the user and authorize the application. Authentication is performed using OAuth2.
For some operations you will need 2
-
legged, for some 3
-
legged, but our applications wil
l all request 3
-
legged because they work with user content. Working with the Identity Services API is covered in detail
in

Intel Cloud Platform: Identity Services
, another document in this series.

Using Intel Cloud
Context

Services


Android




Figure
1
:

Android
Context

Services application

Overview

For this example, we will implement a
simple

application that stores
a user’s
search history in
their

personal
area

on Intel
®

Cloud Services using the
context s
ervice

API
.
Each saved

search will
contain
the date the search was saved, the search term, what search engine was used and where the user was
(latitude and longitude) when the search was saved. At any point, the user can retrieve the list of saved
searches for review.

This ap
plication is written using the Context Services REST API.

Development Environment

In addition to an Intel
®

Cloud Services Platform developer account and Identity Services accounts on both
test and productions servers, you will need to download and install the Android SDK, which includes the
Eclipse IDE with built
-
in Android Developer Tools (ADT).

5


The
Main
Class

As an Identity scope we will use "
user:details user:scope

.

In addition, we require an additional scope for
each context item type the application will save. Our item type requires
location:enhanced
.
Details on how
to authenticate using Intel
®

Identity Services from an Android application are in
Intel Cloud Platform:
Identity Services
, another whitepaper in this series.

The m
ain class in this demo app is
ContextServiceManager
.

It contains one enum

for the possible
errors from invoking the context API:


public static enum ErrorType { PermissionDenied, ItemNotUploaded,







HistoryNotFetched }



In addition, there are two interfaces
: t
he first one
reports the status of

the
context
upload

and
related
errors
; the second one applies to context downloads (i.e. fetching the search history).

public static interface OnContextRequestsListener{


void itemUploaded();


void errorOccured(ErrorType errorType);

}


public static interface OnHistoryFetc
hedListener{


void searchHistoryFetched(List<SearchHistoryItem> history);

}


The following

predefined strings are used
, too:


private static final String BASIC_URL = "https://api.intel.com:8081";

private static final String UPLOAD_CONTEXT_ITEM_METHOD =
"/context/v1/items";

private static final String FETCH_CONTEXT_ITEMS_METHOD = "/context/v1/items";

private static final String CONTEXT_SEARCH_RESOURCE_TYPE_URI = "urn:x
-
intel:context:type:search";


Uploading a Context

To upload an item, we
first
need to generate a JSON description of our item (to see which
resources are
available, their schemas and the descriptions of each
field use
a GET call to
/typescatalog
).


private JSONObject generateSearchItemJson(String searchText, SearchSource
searchSourc
e, Location location) {


try {

6



SimpleDateFormat sdf = new SimpleDateFormat(



"yyyy'
-
'MM'
-
'dd'T'kk':'mm':'ss'Z'");


String dateTime = sdf.format(new Date());


JSONObject jsonObject = new JSONObject();


JSONObject dataObj = n
ew JSONObject();


JSONArray itemsArray = new JSONArray();


JSONObject itemObj = new JSONObject();


JSONObject valueObj = new JSONObject();


JSONObject valueLocationObj = new JSONObject();


valueObj.put("name", searchText)
;


valueObj.put("value", searchText);


valueObj.put("source_domain", searchSource.getName());


valueObj.put("type", searchSource.getType());


valueObj.put("datetime", dateTime);


valueLocationObj.put("lat", location.getLa
titude());


valueLocationObj.put("lon", location.getLongitude());


valueObj.put("location", valueLocationObj);


itemObj.put("contextType", CONTEXT_SEARCH_RESOURCE_TYPE_URI);


itemObj.put("clientCreatedTime", dateTime);


itemObj.put("value", valueObj);


itemsArray.put(itemObj);


dataObj.put("items", itemsArray);


jsonObject.put("data", dataObj);


return jsonObject;


} catch (JSONException e) {


e.printStackTrace();


return new
JSONObject();


}

}



SearchSource

class
has

two fields:
name

(used for
the
search service name) and
type

(general, travel
etc.).

The
contextType

parameter here is
a
special URI identifying
the
item type
; f
or our search app we will use
urn:x
-
intel:contex
t:type:search

URI
.

With this JSON object, we can upload our item to cloud


NetworkHelper.post(BASIC_URL + UPLOAD_CONTEXT_ITEM_METHOD,

generateSearchItemJson(searchText,

7


searchSource, location).toString(),

NetworkHelper.ContentType.Json,

identityServiceManager.getAuthManager().getToken());


This API call returns
a JSON

object
that lists if the item

uploaded
correctly
.

Retrieving Search History

After the user uploads several
items,

he or she

can fetch
his or her entire search

history

by usi
ng a
GET
request.



NetworkHelper.get(BASIC_URL + FETCH_CONTEXT_ITEMS_METHOD,
identityServiceManager.getAuthManager().getToken());



This request returns the JSON object with
a
single "data" property, which contains
an
array

of
named
"items". To parse the history items we use two methods: one for parsing the whole array and one for
parsing each element of this array.

To start,
fetch

each item with
parseSearchHistoryItem()

method
, which
simply parses
a
JSON object
and fetches the

data we need to show to the user. After
the item is

pars
ed
, we have list of
SearchHistoryItem's

(
a
simple class with
a
number of fields, similar to its ctor) which we
can
later

use as
a
source for
ArrayAdapter
.


private List<SearchHistoryItem>
getSearchItemsFromHistory(JSONObject
jsonObject) {


List<SearchHistoryItem> result = new ArrayList<SearchHistoryItem>();


JSONArray itemsArr;


try {


itemsArr = jsonObject.getJSONObject("data").getJSONArray("items");


} catch (JSONExcept
ion ex) {


ex.printStackTrace();


return result;


}


for (int i = 0; i < itemsArr.length(); ++i) {


SearchHistoryItem toAdd;


try {


toAdd = parseSearchHistoryItem(itemsArr.getJSONObject(i));


if (toA
dd != null)


result.add(toAdd);


} catch (JSONException e) {


e.printStackTrace();


}

8



}


return result;

}


private SearchHistoryItem parseSearchHistoryItem(JSONObject jsonObject) {


if (jsonObject == null)


return null;


String contextType = jsonObject.optString("contextType");


if (!contextType.equals(CONTEXT_SEARCH_RESOURCE_TYPE_URI))


return null;


String id;


String text;


String sourceName;


String sourceType;


double
latitude;


double longitude;


Date dateTime;


SimpleDateFormat sdf = new SimpleDateFormat(



"yyyy'
-
'MM'
-
'dd'T'kk':'mm':'ss'Z'");


JSONObject valueObject;


try {


valueObject = jsonObject.getJSONObject("value");


} catch (JSONExcep
tion e) {


e.printStackTrace();


return null;


}


id = jsonObject.optString("id");


text = valueObject.optString("value");


sourceName = valueObject.optString("source_domain");


sourceType = valueObject.optString("type");


try {


dateTime = sdf.parse(valueObject.optString("datetime"));


} catch (ParseException e) {


e.printStackTrace();


dateTime = new Date();


}


try {


JSONObject locationObject = valueObject.getJSONObject("location");



latitude = locationObject.optDouble("lat", 0.0);


longitude = locationObject.optDouble("lon", 0.0);

9



} catch (JSONException e) {


e.printStackTrace();


latitude = 0.0;


longitude = 0.0;


}


Location location

= new Location("reverseGeocoded");


location.setLatitude(latitude);


location.setLongitude(longitude);


SearchSource source = searchSourcesProvider.getSourceByName(sourceName);


if (source == null) {


source = searchSourcesProvider.addS
ource(sourceName, sourceType);


}


return new SearchHistoryItem(id, text, source, location, dateTime);

}

Using Intel Cloud
Context

Services


Windows 8


Figure

2
: Windows 8
Context

Services application

Overview

The Window 8
application

demonstrates how to use the Context Services API from
a Window
s
Presentation Foundation (WPF) application. Like the Android application, it saves searches and retrieves
the search history for later use. As an added feature, the application sh
ows the JSON objects along with
the parsed data.

10


Development Environment

In addition to an Intel® Cloud Services Platform developer account and Identity Services accounts on
both test and productions servers, you will need
Visual Studio 2012 for Windows 8

(the Express version
will work). To make it easier to parse the JSON messages from Cloud Services install the open source
Json.net (
http://json.codeplex.com
).

Authorizing the User

Because this application will access private user
data,

we will need to use 3
-
legged authentication, as
described in
Intel Cloud Platform: Identity Services
, another document in this series. Review the
Windows 8 example found in that document for details how to do 3
-
legged authentication from WPF.

Retrieving
Search History

If we are lucky enough to get an
approved

access request, we are free to download any previously
uploaded context items by calling the
ContextItemQuery

method, but not before we add an event
handler for the ContextService wrapper’s
ContextQueryEvent
.


IntelCloudServices.Instance.ContextService.ContextQueryEvent +=
ContextService_ContextQueryEvent;


...


//Context service item query(download) event handler


void ContextService_ContextQueryEvent(object sender,
ContextQueryEventA
rgs args)


{


//Check for errors


if (args.queryResponse.HasError())


Console.WriteLine("CONTEXT QUERY ERROR: "





+ args.queryResponse.error);


else


{


//Move work to the
ui thread


this.Dispatcher.InvokeAsync(() =>


{


//Clear the current context item list


m_dataContext.ListModel.Clear();


//Populate the list with new items



foreach (ContextItem item in






args.queryResponse.data.items)


{


if (item.contextType == context)


m_dataContext.ListModel.Add(

11







new SearchContextItem(item.value));



}


});


}


}



Here we just populate the window

s data context list model with the newly downloaded items, again
making sure to check for any errors.

Uploading a Context

With access request and item download
now in place, the only part remaining to make our application
functionally complete is new context item upload. This is again made simple using the provided helper
library.



//Create a new context item


ContextItem item = new Context
Item();


//Set the items context (context= urn:x
-
intel:context:type:search)


item.contextType = context;



//Create a new search item using the data provided by the user


SearchContextItem searchItem = new
Search
ContextItem(queryInput.Text, (string)engineSelector.SelectedValue,


queryInput.Text, (string)typeSelector.SelectedValue,


m_da
taContext.Latitude, m_dataContext.Longitude);


//set the context item's value by converting the searchItem into
a JObject(json)


item.value = searchItem.toJObject();



//Create a new context object instance


Cont
extObject obj = new ContextObject();


//Add the new item to the context object


obj.data.items.Add(item);



//Send an upload item request using the backend api


IntelCloudServices.Instance.ContextService.UploadCo
ntextObject(obj);


12


Using Intel Cloud Location Services


Tizen


Overview

The Tizen approach utilizes HTML5, JavaScript and the Context REST APIs in a
straightforward

process
of saving and retrieving a user’s contexts, one he or she has logged into the Intel® Identity Service.
T
he
Tizen
application demonstrates retrieving context types,
sav
ing a context item and
retriev
ing previous
stored items. It also shows how to
set a context watch, which only retrieves items that are new since the
last download
.

Development Environment

To develop applications for the Tizen platform you will need the Tizen 2.1 software developer kit (SDK),
which includes Eclipse IDE, Tizen emulato
r and toolchain. The SKD is available for Windows
®
, Ubuntu
®

and Mac OS X
®
.

Identify Supported Context Types

After successfully authenticating with Intel Identity Services
,

your application can download a list of
context types. The service returns a JSON schema describing all the types of context that the application
can upload and download from Context Services. We will be using context type
urn:x
-
intel:context:type:locatio
n:checkin:v1

for this test application. Note: you only need application
authorization
(2
-
legged)
to download context types.

//

//

Get a list of Context Types and display them

//

13


function GetContextTypes(outPutText) {


jQuery.support.cors = true;


$(out
PutText).val("In Progress...");


var outString;




var URL = BaseURL + '/context/v1/typescatalog';


var authorization = 'Bearer ' + AccessToken;


$.ajax({


url: URL,


type: "GET",


cache: false,


beforeSend: function (request)
{


request.setRequestHeader("authorization", authorization);


},


success: function (data, textStatus, jqxhr) {


$('#contextList').empty();


var json_parsed = $.parseJSON(jqxhr.responseText);


for(var u = 0; u <
json_parsed.data.items.length; u++) {


outString = json_parsed.data.items[u].shortName;


$('#contextList').append('<option value="'+ u +'">'




+ outString +'</option>');


}


},


error: function (jqxhr, textStatus, e
rrorThrown) {


$('#contextList').empty();


console.log("An error occurred: " + jqxhr.status + " "




+ textStatus + " " + errorThrown);


$('#contextList').append('<option value="0">'



+ errorThrown +'</option>');


},


timeo
ut: 5000


});

}


Upload and Download Context Information

With the following code, the application can upload a sample context item of type
urn:x
-
intel:context:type:location:checkin:v1
.


//

//

Upload test item

14


//

function Upload(outPutText) {


jQuery.support.cors = true;


$(outPutText).val("In Progress...");




var URL = BaseURL + '/context/v1/items';


var d = new Date();


var str = d.toISOString();


var stx = str.substr(0, 18) + "Z"; // truncate the date to the format








//

spe
cified by the
JSON

schema


var PostData = '{"data": {"items": [{"contextType": "urn:x
-



intel:context:type:location:checkin:v1","clientCreatedTime":



"2012
-
04
-
12T20:20:50Z","value": {"poiRef": {"domain":



"urn:x
-
intel:context:v1:object
-
domain:csp
-
po
i","href":



"https://api.intel.com/context/v1/pois/



50b845644fbf946e28000000"},"comment": "Yummy Pizza!"}}]}}';


var authorization = 'Bearer ' + AccessToken;


$.ajax({


url: URL,


type: "POST",


data: PostData,


beforeSend: func
tion(request) {


request.setRequestHeader("authorization", authorization);


},


success: function(data, textStatus, jqxhr) {


$(outPutText).val('Uploaded "Yummy Pizza!"');


},


error: function(jqxhr, textStatus,
errorThrown) {


console.log("An error occurred: " + jqxhr.status + " "



+ textStatus + " " + errorThrown);


$(outPutText).val(errorThrown);


},


timeout: 5000


});

}



Then, with the code below, the application downloads all o
f the previously uploaded items of type
urn:x
-
intel:context:type:location:checkin:v1
.


15


//

//

Downloas any test items

//

function ViewTestItems(outPutText) {


jQuery.support.cors = true;


$(outPutText).val("In Progress...");


var outString;




var U
RL = BaseURL + '/context/v1/items';


var authorization = 'Bearer ' + AccessToken;


$.ajax({


url: URL,


type: "GET",


beforeSend: function (request) {


request.setRequestHeader("authorization", authorization);


},


success: function (data, textStatus, jqxhr) {


var json_parsed = $.parseJSON(jqxhr.responseText);


for(var u = 0; u < json_parsed.data.items.length; u++) {


$('#downloadList').empty();


outString = json_parsed.data.ite
ms[u].value.comment;


$('#downloadList').append('<option value="'+ u +'">'




+ outString +'</option>');


}


},


error: function (jqxhr, textStatus, errorThrown) {


$('#downloadList').empty();


console.log("An
error occurred: " + jqxhr.status + " "



+ textStatus + " " + errorThrown);


$('#downloadList').append('<option value="0">'



+ errorThrown +'</option>');


},


timeout: 5000


});

}


Set a Watch and View New Items

The application can set

a watch for a particular context type
; a

watch allows the application to download
only the latest context items uploaded for a given context type. The following code sets a watch for new
context items of context type
urn:x
-
intel:context:type:location:chec
kin:v1
.

16



//

//

Set a Watch

//

function SetWatch(outPutText) {


jQuery.support.cors = true;


$(outPutText).val("In Progress...");




var URL = BaseURL + '/context/v1/watches';


var PostData = '{"data": {"contextType":




"urn:
x
-
intel:context:type:location:checkin:v1" }}';


var authorization = 'Bearer ' + AccessToken;


$.ajax({


url: URL,


type: "POST",


data: PostData,


beforeSend: function (request) {


request.setRequestHeader("authorization",
authorization);


},


success: function (data, textStatus, jqxhr) {


outString = JSON.stringify(jqxhr.responseText);


$(outPutText).val("Watch set");


},


error: function (jqxhr, textStatus, errorThrown) {


consol
e.log("An error occurred: " + jqxhr.status + " "





+ textStatus + " " + errorThrown);


$(outPutText).val(errorThrown);


},


timeout: 5000


});

}



After you set the watch, go back up to the "Upload Test Item" section and click
Execute

to
upload
another

context item

and t
hen, execute the code below to view the context items uploaded since the watch was
set.


//

//

Display any new items

//

17


function NewItems(outPutText) {


jQuery.support.cors = true;


$(outPutText).val("In
Progress...");


var outString;




var URL = BaseURL + '/context/v1/watches/newitems';


var authorization = 'Bearer ' + AccessToken;


$.ajax({


url: URL,


type: "GET",


beforeSend: function (request) {


request.setRequestHead
er("authorization", authorization);


},


success: function (data, textStatus, jqxhr) {


var json_parsed = $.parseJSON(jqxhr.responseText);


for(var u = 0; u < json_parsed.data.items.length; u++) {


$('#newList').empty();


outString = json_parsed.data.items[u].value.comment;


$('#newList').append('<option value="'+ u +'">'




+ outString +'</option>');


}


},


error: function (jqxhr, textStatus, errorThrown) {


$('#newList').e
mpty();


console.log("An error occurred: " + jqxhr.status + " "




+ textStatus + " " + errorThrown);


$('#newList').append('<option value="0">'




+ errorThrown +'</option>');


},


timeout: 5000


});

}



When you are finished
with the watch can delete the ones you have created.


//

//

Loop through each Watch and delete it

//

18


function DeleteWatch(data, outPutText) {


jQuery.support.cors = true;


$(outPutText).val("In Progress...");




var Items = data.data.items.length;


if(Items == 0) {


$(outPutText).val("No Watches to Delete");


return;


}



for(ilop = 0; ilop < Items; ilop++) {


if(data.data.items[ilop].contextType !=



"urn:x
-
intel:context:type:location:checkin:v1") {


break;


}




var ID = data.data.items[ilop].id;


$(outPutText).val("Deleting watch " + ID);



var URL = BaseURL + '/context/v1/watches/' + ID;


var authorization = 'Bearer ' + AccessToken;


$.ajax({


url: URL,


type: "DELETE",


beforeSend: function(request) {


request.setRequestHeader("authorization", authorization);


},


success: function(data, textStatus, jqxhr) {


var Val = $(outPutText).val();


Val = Val + JSON.string
ify(jqxhr.responseText);


$(outPutText).val(Val);


},


error: function(jqxhr, textStatus, errorThrown) {


console.log("An error occurred: " + jqxhr.status + " "





+ textStatus + " " + errorThrown);


$(
outPutText).val("Can't Delete Watch");


},


timeout: 5000


});


}

19


}


//

//

Clean up all Watches

//

function CleanUpWatches(outPutText) {


jQuery.support.cors = true;


$(outPutText).val("In Progress...");


var outString;




va
r URL = BaseURL + '/context/v1/watches';


var authorization = 'Bearer ' + AccessToken;


$.ajax({


url: URL,


type: "GET",


dataType: "json",


beforeSend: function(request) {


request.setRequestHeader("authorization",
authorization);


},


success: function(data, textStatus, jqxhr) {


var ReturnedData = data;


DeleteWatch(ReturnedData, outPutText);


},


error: function(jqxhr, textStatus, errorThrown) {


console.log("An error oc
curred: " + jqxhr.status + " "





+ textStatus + " " + errorThrown);


$(outPutText).val(errorThrown);


},


timeout: 5000


});

}


Closing

In this whitepaper, we created
covered using the

Intel® Cloud Services Platform
Context

API on
Android,
Windows 8 and
Tizen
.

You can download the full source for these demo apps at
http://some.address/with/sources

and then try them yourself or use them as reference material to create
your own applications with the Intel® Cloud Services Platform. For more information about the Cloud
Services Platform, go to:
http://software.intel.com/cloudservicesplatform



20


2013 © Intel Cloud Services Platform is a registered trademark of Intel. All other trade names and
trademarks belong to their respective owners.