[CONTROLLER-474] PUT and POST uris and namespaces are inconsistent Created: 14/May/14  Updated: 14/Nov/17  Resolved: 14/Oct/14

Status: Resolved
Project: controller
Component/s: restconf
Affects Version/s: Helium
Fix Version/s: None

Type: Bug
Reporter: Rob Adams Assignee: Jozef Gloncak
Resolution: Cannot Reproduce Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: Linux
Platform: PC


External issue ID: 1012

 Description   

REST and POST should deal with the same URIs and expect data formatted in the same ways. Currently, they seem to treat namespaces differently (I guess; I haven't actually be able to figure out what the actual behavior is)

The API as presented in the swagger API explorer is reasonably, sane, telling me I can either POST or PUT into URIs such as /config/toaster:toaster.

However, only PUT actually works here, and the semantics are (as correct for PUT) to wipe out everything below that URI and replace it with the new PUT data.



 Comments   
Comment by Devin Avery [ 29/May/14 ]

In trying to nail down the expected behavior with post, I looked at the restconf spec:

https://tools.ietf.org/html/draft-bierman-netconf-restconf-02#section-3.4 it states that POST can be used on Datastore, Data, or operations. WE are focused on Datastore / Data with this item.

I believe the datastore aspect is working correctly. That is we can POST to /config and update that store as necessary.

===

Therefore this ticket should be about allowing POST to the "data" resource as defined here: https://tools.ietf.org/html/draft-bierman-netconf-restconf-02#section-5.3

According to the above restconf spec, it looks like POST is only valid on Containers or Lists.

Therefore, my interpretation is that we want the following behavior:

POST to /config/<container> should request a "creation" of that resource. Q: What happens if it already exists? Replace? Merge? Fail?

POST to /config/<cointainer>/<listId> should request the creation of a node in that list. Q: What happens if the node with the given ID already exists?

Also, there are mentions of query parameters. insert / point which should be considered.

Some more discussion/etc is required to understand the desired behavior of POST before we can work this ticket.

(Feel free to correct any false assumptions I made above.)

Comment by Tom Pantelis [ 29/May/14 ]

Since POST to a data resource is "treated as a request to create a resource or sub-resource", I think if it already exists then the "data-exists" error should be returned.

PUT is intended "to replace the target resource" so the operation is performed if the resource already exists.

I have noticed inconsistencies/differences between POST and PUT in ODL as to what is allowed in the URI and message body. It seems to me they should work the same.

Eg, I can PUT:
http://localhost:8080/restconf/config/toaster:toaster

{
toaster:

{ toasterModelNumber: "123", toasterManufacturer: "GE", toasterStatus: "up" }

}

But I can't POST the same thing. For POST I have to do:
http://localhost:8080/restconf/config/

{
toaster:toaster:

{ toasterModelNumber: "123", toasterManufacturer: "GE", toasterStatus: "up" }

}

Comment by Rob Adams [ 29/May/14 ]

Hi Tom,

Those inconsistencies were the original reason for this bug, though it's definitely good to make sure we have well-defined clean semantics for what the different verbs do.

POST as far as I can tell can only go to the root of the config model, and then you also need to format the body of the message differently for some reason. I don't understand why they would be different.

Comment by Reinaldo Penno [ 30/May/14 ]

I've hit this bug and the differences in URIs are very confusing.

BTW, PUT is idempotent. Therefore a create or update is the same for PUT. The final result is always the contents of the PUT request.

Comment by Tom Pantelis [ 30/May/14 ]

In section 3.4.1, for a POST, a "target resource type is a Datastore or Data resource". It seems currently we only support POST to a Datastore, therefore the URI must be "/restconf/config" and the input must define the fully-qualified path to the resource.

It seems what's missing for POST is allowing a specific target Data resource. Then you would be able to POST or PUT with the same URI and input and the swagger API would be correct.

Outside of allowed target resource type, the difference between POST and PUT is that, if the resource already exists, POST should do nothing and return the "data-exists" error tag whereas PUT replaces the resource and returns success.

Comment by Viera Zelcamova [ 11/Sep/14 ]

Hi Tom, Rob,

I`m re-assigning this bug to our team as we have available resource to continue with it. Pls let me know if you have any comment. Thank you.

Comment by Jozef Gloncak [ 16/Sep/14 ]

(In reply to Tom Pantelis from comment #2)
> Since POST to a data resource is "treated as a request to create a resource
> or sub-resource", I think if it already exists then the "data-exists" error
> should be returned.
>
> PUT is intended "to replace the target resource" so the operation is
> performed if the resource already exists.
>
> I have noticed inconsistencies/differences between POST and PUT in ODL as to
> what is allowed in the URI and message body. It seems to me they should work
> the same.
>
> Eg, I can PUT:
> http://localhost:8080/restconf/config/toaster:toaster
>
> {
> toaster:
>

{ > toasterModelNumber: "123", > toasterManufacturer: "GE", > toasterStatus: "up" > }

> }
>
> But I can't POST the same thing. For POST I have to do:
> http://localhost:8080/restconf/config/
>
> {
> toaster:toaster:
>

{ > toasterModelNumber: "123", > toasterManufacturer: "GE", > toasterStatus: "up" > }

> }

It is specified in
1.4.2.2. Create New Data Resources
and
1.4.2.3. Replace an Existing Data Resource
that PUT and POST should work like this

Comment by Jozef Gloncak [ 16/Sep/14 ]

I passed through this discussion. There is several suggestions but is there any definitive conclusion about what should be implemented or fixed?

Comment by Jozef Gloncak [ 16/Sep/14 ]

My comments inlines.
(In reply to Devin Avery from comment #1)
> In trying to nail down the expected behavior with post, I looked at the
> restconf spec:
>
> https://tools.ietf.org/html/draft-bierman-netconf-restconf-02#section-3.4 it
> states that POST can be used on Datastore, Data, or operations. WE are
> focused on Datastore / Data with this item.
>
> I believe the datastore aspect is working correctly. That is we can POST
> to /config and update that store as necessary.
>
> ===
>
> Therefore this ticket should be about allowing POST to the "data" resource
> as defined here:
> https://tools.ietf.org/html/draft-bierman-netconf-restconf-02#section-5.3
>
> According to the above restconf spec, it looks like POST is only valid on
> Containers or Lists.
>
> Therefore, my interpretation is that we want the following behavior:
>
> POST to /config/<container> should request a "creation" of that resource. Q:
> What happens if it already exists? Replace? Merge? Fail?
Currently this works (I tested in POSTMAN and swager. In BrokerFacade is called merge datastore operation.
>
> POST to /config/<cointainer>/<listId> should request the creation of a node
> in that list. Q: What happens if the node with the given ID already exists?
This also works. Behavior is still the same (merge operation)
>
> Also, there are mentions of query parameters. insert / point which should be
> considered.
As I know insert and point parameters aren't implemented. Place where to insert data is specified via URI. BTW I do not understand what is difference between insert and point.
>
> Some more discussion/etc is required to understand the desired behavior of
> POST before we can work this ticket.
>
> (Feel free to correct any false assumptions I made above.)

Comment by Tom Pantelis [ 16/Sep/14 ]

Good question. I recall my confusion was when I was able to PUT to /config/toaster:toaster but not POST, however it's working as defined in the RFC.

It sounds like you tested POST to a data resource and it works - I think that wasn't working when this bug was created.

Rob mentioned that the swagger UI presented invalid POST urls (e.g. /config/toaster:toaster). If that's still the case then I think swagger should be fixed. Other than that, I would say close this bug.

(In reply to Jozef Gloncak from comment #8)
> I passed through this discussion. There is several suggestions but is there
> any definitive conclusion about what should be implemented or fixed?

Comment by Jozef Gloncak [ 25/Sep/14 ]

I tested POST in swagger. My results are as follows.

YANG container or list which contains can have as subchild:

  • case1: one container or list
  • case2: several container or list

case1
=====
I successfully
POST-ed data via toaster POST swager link with following data
{
"toaster":

{ "darknessFactor": 1 }

}

case2
=====
It was necessary somehow present collection of all subchild lists and container to one swagger POST link.
For example opendaylight-inventory swagger POST link /config/opendaylight-inventory:nodes/node/

{id}/ contains at top level JSON object (config)nodePOST. POST suffix tells that this json object contains list of all possible POSTs for this URI. Here is this json

(config)nodePOST {
switch-features (object[(config)switch-features], optional),
supported-actions (object[(config)supported-actions], optional),
meter (array[(config)meter], optional),
meter-features (object[(config)meter-features], optional),
group-features (object[(config)group-features], optional),
supported-instructions (object[(config)supported-instructions], optional),
table (array[(config)table], optional),
supported-match-types (object[(config)supported-match-types], optional),
group (array[(config)group], optional),
node-connector (array[(config)node-connector], optional),
pass-through (object[(config)pass-through], optional)
}

It means that from swagger POST link /config/opendaylight-inventory:nodes/node/{id}

/ can be posted containers and lists

  • switch-features
  • supported-actions
  • ....
  • pass-through

This container and lists are detailed specified below this JSON object

Then there is in swagger POST link /config/opendaylight-inventory:nodes/node/

{id}

/ section Parameters which contains:

  • id - it is value of key for yang list node
  • several rectangles which name always start with **. It means that one of this rectangle has to be filled.

I tested:

  • id - 40
  • **(config)node-connector -
    {
    "opendaylight-inventory:node-connector": { "id":"id43" }

    }
    INSERTING WAS SUCCESSFUL

I specified

  • id - 41
  • **(config)meter-features
    {
    "netconf-node-inventory:pass-through":{
    }
    }

INSERTING WAS SUCCESSFUL

after getting data from via swagger GET link /config/opendaylight-inventory:nodes
I got
{
"nodes": {
"node": [

{ "id": "controller-config" }

,
{
"id": "40",
"node-connector": [

{ "id": "id40" }

]
},
{
"id": "41",
"netconf-node-inventory:pass-through": {}
}
]
}
}

So I think that POST-ing data via swager works.

Originally I suggested to generate standalone POST links for every child which wasn't accepted (see https://bugs.opendaylight.org/show_bug.cgi?id=932 comment 4).

I can't see any problem here. So if nobody will point to some other problem I will close this bug next week. Thanks

Comment by Jozef Gloncak [ 14/Oct/14 ]

No other problems were reported so I closed the bug.

Generated at Wed Feb 07 19:53:07 UTC 2024 using Jira 8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d.