-
Notifications
You must be signed in to change notification settings - Fork 28
Produce() method should ignore instance specific information #156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Where is that claimed? The produce() algorithm doesn't. However, it is indeed missing some steps/information. When creating a new Thing by consuming a TD and using the object to supply to produce(), it doesn't really harm if IP address and content type are provided as a Thing model, since the algorithm of the produce() method should state what are the minimum set of properties in a TD init object that should be there, and what happens if an IP address and content type are provided - the implementation may take it as a hint, but that information there will be overridden in the newly created ExposedThing object. |
The function description has the following:
After looking at the definition of ThingModel:
And after looking at the ThingDescription definition:
So this means that Scripting API uses the same definition of the Thing Description as the Thing Description spec which in turn means that produce() method must be able to accept a normal TD and generate an Exposed Thing according to that.
I also don't see what this means :) In my head, there has to be a clause/sentence saying that the forms of a TD are instance specific and that the produce() method can recreate an ExposedThing object with the same instance only if the instance is the same. This being a very rare case, we should make it possible to add instance specific information such as contenttype, method, (href). Since we may have multiple forms, there should be something like addForm() that can be called on an InteractionFragment which would push a Form into the array of forms. |
This is a JavaScript API and a function can accept any initialization object or any of its property subset. The algorithm tells how to use the init object. Instance in this context means the JavaScript object. Multiple forms are passed as array property in the init object. |
Doesn't this imply that the meaning of the TD object as an argument can have two different meanings for two different implementations? |
No, it's not a TD object yet, it is a JavaScript object that is used for initializating an ExposedThing object which represents a TD "object" in the same way a ConsumedThing represents a TD "object". One script might be different from another script of course, and may use different initialization objects. But they can use also the same ones, as the developer decides. |
But the scripting API spec says that the argument is a serialized form of the TD defined in the TD spec. |
ExposedThing.expose() does not accept arguments. As the spec says, WoT.produce() accepts a string (serialized TD which is used for initializing the new ExposedThing object) or a dictionary object that is used for initializing the new ExposedThing object, i.e. its properties become the ExposedThing object properties and the other required properties in the TD spec are initialized with default values. Sorry I don't understand the source of your concern. |
Sorry, I meant produce() instead of expose() in my previous comment.
This is exactly what I mean and I think we are on the same point. If we say that ExposedThing is initialized with the properties of the argument TD string, then the forms field of the argument TD string should be present in the ExposedThing. This is what I mean by instance-specific information of a TD. Without instance specific information, we would simply get a TD template (Thing fragment) and the current Scripting API spec does not tell that we can actually accept "only" a TD template. I have put only in quotes since if the exposer of that TD (that came in the argument) can fulfill instance specific requirements, its ExposedThing will have exactly the same values for every key. I think there has to be at least a note about this constraint. |
Not necessarily. The ExposedThing creation algorithm does not have to take all input as it is, instead it may take it as a hint when determining the init value of the property in the ExposedThing object, so implementations may override the provided init values under conditions specified in the produce() algorithm. Indeed we need to extend/clarify the produce() algorithm how does it initialize the new ExposedThing based on the input (string or object). |
Should be fixed by #174. |
I am not sure if this is fixed now since there is still no mention of the following details:
|
I think there may be a misunderstanding about the intended work flow when creating an ExposedThing. From the network API point of view, we see that a new Thing is created on a device that serves requests and exposes a TD. How does that happen? A script gets [deployed and] executed on that device. That includes instantiating a request handler for each Form declared in the TD template object and making sure external requests be dispatched to the right request handler and Form. So the questions in this issue are basically encapsulated by expose() implementation, but the developer needs to know the following:
|
I do agree that it happens in the end with the expose() method but the TD is given only in the produce() so it concerns it too. Basically, the developer needs to know the 3 bullet points you have listed but also needs a warning (by the implementation or Scripting API) that not having this information might result in a TD that is different than the one given to the produce() method. Background information: In node-wot, all the forms in a TD that is given to the produce() method are ignored and replaced by node-wot's default forms. |
Let me add an example. Suppose the following TD for
In node-wot we used to replace all existing forms entries with the one created from the node-wot runtime enhanced with bindings (e.g., for http, coap etc). Assuming one wants to report an SVG image one can do something like this
Doing so failed in node-wot so far because the provided Hence I think the Scripting API spec needs to specify (not sure though how) that at least Having said that, I think there are cases where the Scripting API does not work anymore. Imagine the case that for HTTP one wants to report The method |
I agree it is not possible now but there is nothing inherently limiting this. Something similar happened on the Consumer side which is now fixed with defining the form index in the InteractionOptions. A similar solution could be done on the Consumer side too:
thing.setPropertyReadHandler("myProperty", {"protocol":"http"}, () => { //maybe href with wildcards?
// return something if the request is http
});
// need to define what happens in this case since normally the second setPropertyReadHandler would overwrite the previous one
thing.setPropertyReadHandler("myProperty", {"contentType":"image/jpeg"} , () => {
// return a jpeg
});
thing.setActionHandler("myAction", {"protocol":"http","contentType":"application/json"}, () => {
// do the following if the request is HTTP
// parse JSON input
// do and return something
}); Disadvantage: Cannot write scripts like "Do this if the request is coap and do that if the request is http"
thing.setPropertyReadHandler("myProperty", (formOptions) => { //maybe href with wildcards?
if (formOptions.protocol == "http"){
// return something if the request is http
} else if (formOptions.contentType == "image/jpeg"){
// return a jpeg
}
});
thing.setActionHandler("myAction", (value,formOptions) => {
// do the following if the request is HTTP and JSON
if (formOptions.protocol == "http" && formOptions.contentType == "application/json"){
// parse JSON input
// do and return something
}
}); I think this method is better. |
I agree the second way is better. |
I think we need to break down the produce() and expose() algorithms a little bit in more detail. The init dictionary (TD template), together with the handler functions should be in full control to implement a TD interaction. An app that implements the ExposedThing might want to use its own dependencies for bindings and HW APIs and we should provide a mechanism for that in Scripting implementations. The implementation (node-wot) can make ExposedThing implementations easier, by providing some bindings by default and translating to bindings where DataSchema and some supported content types are provided in the TD init dict. However, we should make sure we document the mechanisms used in implementations for dispatching interaction requests. The examples above are very good and I wonder is there any formal heuristic we could distill from best practices and make it a standard dispatching mechanism for request handling. |
Not sure if it is a valid use case but at the moment it is possible to use the ExposedThing as a value container without the need to specify any handlers (i.e., some clients can write the image and other clients read the image)... |
Should be clarified/solve by #218, please check. |
I think this issue resonates with the current PR about |
Pr #289 was merged, please feel free to reopen the issue if the current spec is not sufficiently specific about how to produce an ExposedThing from an |
At the current state, produce() method claims to accept a Thing Description that always contains instance specific information such as href's IP address and contenttype. It should be made clear that this is not possible since a server cannot replicate the IP address of another server or that this server may not be able to provide the same contenttype.
The text was updated successfully, but these errors were encountered: