- The OcfServer API object
- The ServerResource interface
- The OcfRequest interface
A device that implements the OcfServer
API may provide special resources to handle CRUDN requests.
The OcfServer
API object exposed the following properties and methods.
Property | Type | Optional | Default value |
---|---|---|---|
platform |
OcfPlatform object |
no | implementation provided |
device |
OcfDevice object |
no | implementation provided |
Method signature | Description |
---|---|
register(resource) |
register a local resource with the OCF network |
oncreate(handler) |
save a handler for create requests on this device |
The platform
property is an OcfPlatform
object that represents properties of the hardware platform that hosts the current device.
The device
property is an OcfDevice
object that represents properties of the device (OCF stack).
Registers a resource in the OCF network.
The resource
argument is an object that should contain at least the following properties (other resource properties may also be specified):
resourcePath
as stringresourceTypes
as array of strings with at least one elementinterfaces
as array of strings (if not specified, then by default"oic.if.baseline"
is added)mediaTypes
as array of strings that can be empty (by default empty)discoverable
(by defaulttrue
)observable
(by defaulttrue
)secure
(by defaulttrue
)slow
(by defaultfalse
)- either
properties
as an object, orlinks
as array ofResourceLink
objects.
See the create example.
The method runs the following steps:
- Return a
Promise
objectpromise
and continue in parallel. - Send a request to register the given
resource
, and wait for the answer. - If there is an error during the request, reject
promise
with that error. - When the answer is received, update
resource
to be aServerResource
object. - Update the device's
types
property, ifresourceType
ofresource
is not intypes
. - Resolve
promise
withresource
.
Registers a function to handle OCF create resource
requests and returns this
for chaining. If the provided handler
argument is not a Function
, throw "TypeMismatchError"
.
Whenever the underlying platform notifies the implementation about an OCF create request, implementations should run the following steps:
- Create an
OcfRequest
objectrequest
as follows:- The value of
request.source
is theResourceId
of the client resource requesting the operation. - The value of
request.target
is theResourceId
of the server resource responsible to create the requested resource, ornull
if not specified. - The value of
request.options
is an object that contains a list of properties with values created by the implementation from the REST query options of the request. For instance this object may contain client hints on what measurement units should be used in the resource representation. - The value of
request.data
is an object that contains at least the following properties of the resource to be created:resourcePath
andresourceTypes
. In addition, other resource properties may also be specified, such asinterfaces
,mediaTypes
, andproperties
for resource representation initialization.
- The value of
- Let
handler
benull
. - If
request.target
is notnull
, run the following sub-steps:- Find the
ServerResource
objectresource
for whichresource.resourcePath
is equal torequest.target.resourcePath
. - If there is no such object, or if there is no registered create handler on
resource
, then invokerequest.respondWithError(error)
with"NotFoundError"
and terminate these steps. - Otherwise, let
handler
be the registered create handler onresource
.
- Find the
- Otherwise, if
request.target
isnull
, and if there is a registered create handler on the server object, lethandler
be that function. - If
handler
isnull
, invokerequest.respondWithError(error)
with"NotSupportedError"
and terminate these steps. - Invoke
handler
withrequest
as argument.
require('ocf').start("server").then(function(server) {
server.on('create', function(request) {
console.log("Client resource id: " + request.source.resourcePath);
console.log("Target resource id, responsible to create the resource: " + request.target.resourcePath);
console.log("Requested resource path: " + request.resource.resourcePath);
console.log("Requested resource type: " + request.resource.resourceType);
// Use a local function to create the resource.
let res = _createResource(request.target.resourcePath, request.resource);
// Use oneiota.org RAML definitions, the request options, and sensor documentation.
var translate = function (representation, requestOptions) {
switch (requestOptions.units) {
case "C" :
// use sensor-specific code to get Celsius units
representation.temperature = _getCelsiusFromSensorT1();
break;
case "F":
representation.temperature = _getFahrenheitFromSensorT1();
break;
case "K":
representation.temperature = _getKelvinFromSensorT1();
break;
}
}
return representation;
}
// Register the new resource and then respond to the request.
server.register(res)
.then(function(resource) {
resource.ontranslate(translate);
server.respond(request, null, resource);
}).catch(function(error) {
server.respond(request, error, res);
});
});
}).catch(function(error) { console.log("Error: " + error.message); });
Describes an object that is passed to server event listeners.
Property | Type | Optional | Default value | Represents |
---|---|---|---|---|
type |
string | no | undefined |
OCF request type |
source |
ResourceId |
no | undefined |
Requesting resource |
target |
ResourceId |
no | undefined |
Request handling resource |
data |
object | no | undefined |
Resource id or resource or resource representation |
options |
object | yes | undefined |
dictionary containing the request options |
observe |
boolean | no | undefined |
whether observation is to be on or off |
Method signature | Description |
---|---|
respond(data) |
respond to the protocol request with OK or data |
respondWithError(error) |
respond to the protocol request with error |
The type
property represents the OCF request type: "create"
, "retrieve"
, "update"
, "delete"
.
The data
property in a request is an object that contains data that depends on the request type
and is described in this document with the corresponding request.
The options
property is an object whose properties represent the REST
query parameters passed along with the request as a JSON-serializable dictionary. The semantics of the parameters are application-specific (e.g. requesting a resource representation in metric or imperial units). For instance request options may be used with the retrieve request.
The observe
property is a flag for OCF retrieve requests that tells whether observation for the requested resource should be on or off. For requests other than "retrieve"
the value SHOULD be undefined
.
- Sends a response to this request.
- The
data
argument is optional and used with requests such ascreate
andupdate
.
The method is typically used from request handlers, and internally reuses the request information in order to construct a response message.
The method runs the following steps:
- Return a
Promise
objectpromise
and continue in parallel. - Construct a response message to
request
, reusing the properties ofrequest
. - If
data
is notnull
, then include it in the response message (when the protocol message format supports that). - Send the response back to the sender.
- If there is an error during sending the response, reject
promise
with that error, otherwise resolvepromise
.
- Sends an error response to this request.
- The
error
argument is anError
object.
The method is typically used from request handlers, and internally reuses the request information in order to construct a response message.
The method runs the following steps:
- Return a
Promise
objectpromise
and continue in parallel. - Construct a response message to
request
, reusing the properties ofrequest
. - If
error
is notnull
and is an instance ofError
, then mark the error in the response message (the error may be application-specific). Otherwise, mark a generic error in the response message. - Send the response back to the sender.
- If there is an error during sending the response, reject
promise
with that error, otherwise resolvepromise
.
ServerResource
extends Resource
, so it has all the properties of Resource
as read-only, and in addition it has the following methods:
Method signature | Description |
---|---|
onretrieve(handler) |
save a handler for retrieve requests |
ontranslate(translateFunction) |
save a handler for a translating resource representation |
onupdate(handler) |
save a handler for update requests |
ondelete(handler) |
save a handler for delete requests |
notify() |
notify all OCF observers of this resource |
unregister(resourceId) |
unregister the resource from the OCF network |
Registers a callback function handler
for translation and returns this
for chaining. If the provided handler
argument is not a Function
, throw "TypeMismatchError"
.
The handler
function will be invoked by the implementation when the client requests a certain representation of the resource by the means of request options. The handler
function will receive as argument a dictionary object options
that contains the REST request options parsed into property-value pairs. The handler
can use options
and this.properties
in order to compute the modified resource representation object.
See the create example.
Registers the function handler
to handle OCF retrieve resource
requests and returns this
for chaining. If the provided handler
argument is not a Function
, throw "TypeMismatchError"
.
Whenever the underlying platform notifies the implementation about an OCF retrieve request, implementations should run the following steps:
- Create an
OcfRequest
objectrequest
as follows:- The value of the
source
property ofrequest
is theResourceId
of the resource requesting the operation. - The value of the
target
property ofrequest
is theResourceId
of the resource to be retrieved. - The value of the
data
property ofrequest
isundefined
. - The value of the boolean
request.observe
property ofrequest
tells if the client wants to also observe the resource for changes.
- The value of the
- Find the
ServerResource
objectresource
for whichresource.resourcePath
is equal torequest.target.resourcePath
. - If there is no such object, invoke
request.respondWithError(error)
with a new"NotFoundError"
and terminate these steps. - If there is a registered retrieve handler on
resource
, invoke that function withrequest
as argument. - If
request.observe
istrue
, set up change notifications for the resource, and send an OCF retrieve response including the resource representation every time the resource is changed, according to thenotify
algorithm. Ifrequest.options
is an object, then save that object in association withrequest.source
in order that it can be used by thenotify()
algorithm. - Otherwise, if
request.observe
isfalse
, reset change notifications sent to the client identified by therequest.source
property.
require('ocf').start("server").then(function(server) {
server.onretrieve(function(request) {
console.log("Client resource id: " + request.source);
console.log("Target resource id, to be retrieved: " + request.target.resourcePath);
// Retrieve resource in a device-specific way.
let res = _getResource(request.target);
let err = res ? null : new Error('retrieving resource failed');
let res = _getResource(request.target); // private function
if (!res) {
request.respondWithError(new Error('retrieving resource failed'));
return;
}
request.respond(res);
if (request.observe) {
console.log("Enabled change notifications for the resource.");
} else {
console.log("Disabled change notifications for the resource.");
}
});
}).catch(function(error) { console.log("Error: " + error.message); });
Registers the function handler
to handle OCF update resource
requests and returns this
for chaining. If the provided handler
argument is not a Function
, throw "TypeMismatchError"
.
Whenever the underlying platform notifies the implementation about an OCF update request, implementations should run the following steps:
- Create an
OcfRequest
objectrequest
as follows:- The value of the
source
property ofrequest
is theResourceId
of the resource requesting the operation. - The value of the
target
property ofrequest
is theResourceId
of the resource to be updated. - The
data
property ofrequest
should be an object that contains the resource representation properties that should be updated, according to the data model of the given resource.
- The value of the
- Find the
ServerResource
objectresource
for whichresource.resourcePath
is equal torequest.target.resourcePath
. - If there is no such object, invoke
request.respondWithError(error)
with a newNotFoundError
and terminate these steps. - If there is a registered update handler on
resource
, invoke that function withrequest
as argument.
It is the responsibility of the application to call notify()
after the resource is updated.
require('ocf').start("server").then (function(server) {
server.on('update', function(request) {
console.log("Client resource path: " + request.source.resourcePath);
console.log("Resource path to be updated: " + request.target.resourcePath);
let res = _updateResource(request.target, request.data); // private function
if (!res) {
request.respondWithError(new Error('updating resource failed'));
return;
}
request.respond(res);
server.notify(res);
});
}).catch(function(error) { console.log("Error: " + error.message); });
Registers the handler
function to handle OCF delete resource
requests and returns this
for chaining. If the provided handler
argument is not a Function
, throw "TypeMismatchError"
.
Whenever the underlying platform notifies the implementation about an OCF delete request, implementations should run the following steps:
- Create an
OcfRequest
objectrequest
as follows:- The value of the
source
property of the request is theResourceId
of the resource requesting the operation. - The value of the
target
property of the request is theResourceId
of the resource to be deleted. - The rest of
request
properties areundefined
.
- The value of the
- Find the
ServerResource
objectresource
for whichresource.resourcePath
is equal torequest.target.resourcePath
. - If there is no such object, invoke
request.respondWithError(error)
with a newNotFoundError
and terminate these steps. - If there is a registered delete handler on
resource
, invoke that function withrequest
as argument.
require('ocf').start("server").then(function(server) {
server.ondelete(function(request) {
console.log("Client resource id: " + request.source);
console.log("Resource to be deleted: " + request.target.resourcePath);
if(_deleteResource(request.target)) // private function
request.respond();
else
request.respondWithError(new Error('deleting resource failed'));
});
}).catch(function(error) { console.log("Error: " + error.message); });
Notifies subscribed clients about a resource representation change and returns a Promise
object.
See the example for the update
event.
The method runs the following steps:
- Return a
Promise
objectpromise
and continue in parallel. - For each client that requested observing
this.resourcePath
, run the following sub-steps:- If there were request options specified with the retrieve request associated with observing the resource, and if a translate function has been defined for the resource, then let
translatedRepresentation
be the result of invoking that translate function with the request options dictionary that has been saved for the observation request. - Send an OCF update notification to the client using
translatedRepresentation
.
- If there were request options specified with the retrieve request associated with observing the resource, and if a translate function has been defined for the resource, then let
- When all notifications are sent, resolve
promise
.
Unregisters the given resource from the OCF network and returns a Promise
object.
require('ocf').start("server").then(function(server) {
server.unregister(resource)
.then(resource) {
console.log("Successfully unregistered resource " + resource.resourcePath)
}.catch(error) {
console.log("Error: " + error.message)
};
}).catch(function(error) { console.log("Error: " + error.message); });
The method runs the following steps:
- Return a
Promise
objectpromise
and continue in parallel. - Send a request to unregister
this.resourcePath
onthis.deviceId
and wait for the answer. - If there is an error during the request, reject
promise
with that error. - When the answer is received, resolve
promise
.