Skip to content
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

Support for Addressing Links between Entries #10

Closed
bsaunder2002 opened this issue Nov 5, 2011 · 16 comments
Closed

Support for Addressing Links between Entries #10

bsaunder2002 opened this issue Nov 5, 2011 · 16 comments
Labels

Comments

@bsaunder2002
Copy link

ie:
http://www.odata.org/developers/protocols/uri-conventions#AddressingLinksBetweenEntries
3.2. Addressing Links between Entries

I learned Ruby 15 minutes ago (:))

I didnt see the word link in any of the .rb files.

Is there support for links?

Bill

@visoft
Copy link
Owner

visoft commented Nov 9, 2011

There's no support currently. I can add a link method to a query similar to skip or top. The resulting collection could be either URIs or just strings. Would that work for you?

@visoft
Copy link
Owner

visoft commented Nov 11, 2011

I added support for querying links in the develop branch 7de7dce.

Let me know if this works for you.

@bsaunder2002
Copy link
Author

Thanks for the response!
I'm currently querying my links via:
result = Array.new
url = "http://#{@cHOSTNAME}/xxx/XXX.svc/Suites(#{suiteId}L)/$links/Experiments?AuthenticationToken=#{@auth_token}"
xml_links = Net::HTTP.get_response(URI.parse(url)).body
doc_links = REXML::Document.new(xml_links)
doc_links.elements.each("links/uri") do |i|
a=i.to_a
b=a[0]
c=String(b).split('(')[1].split('L')[0]
result.push c
end
return result

Seems to work well (get an array of experiment id's that are related to a particular suite). I will look into switching to your query method as soon as I can. (managers - priorities :( )

I have been unable to find good examples of how to set or create links.
http://www.odata.org/media/6655/%5Bmc-apdsu%5D%5B1%5D.htm#_Toc246716600 - 2.2.7.1.2 InsertLink Request
This one is "complex". I wish people who write docs would provide examples.

Bill

@visoft
Copy link
Owner

visoft commented Nov 18, 2011

Do you need support for creating links between objects (thinking of like Silverlight's SetLink and AddLink methods)? I found some examples for doing that on the odata site (http://www.odata.org/developers/protocols/operations#ManipulatingLinks). I was thinking of adding this as the last thing before releasing v0.1.0.

@bsaunder2002
Copy link
Author

Sorry about the delays in responding.
Yes AddLink is exactly what I'm looking for.
I got as far as trying the atompub/json method listed on the odata.org site. Unfortunately my server kept feeding me a 500. So it must not like what I was trying.
I got lost trying to setup proxy support for plain Net:HTTP. The Rest proxy was easy to setup so I can use fiddler to troubleshoot your library.
Thx for the work. I wish my Ruby was good enough to support you. Just hacking at it...

Bill
bsaunder2002@yahoo.com

--- On Fri, 11/18/11, Damien White reply@reply.github.com wrote:

From: Damien White reply@reply.github.com
Subject: Re: [ruby_odata] Support for Addressing Links between Entries (#10)
To: "bsaunder2002" bsaunder2002@yahoo.com
Date: Friday, November 18, 2011, 7:07 AM
Do you need support for creating
links between objects (thinking of like Silverlight's
SetLink and AddLink methods)? I found some examples for
doing that on the odata site (http://www.odata.org/developers/protocols/operations#ManipulatingLinks).
I was thinking of adding this as the last thing before
releasing v0.1.0.


Reply to this email directly or view it on GitHub:
#10 (comment)

@visoft
Copy link
Owner

visoft commented Nov 20, 2011

I checked in a partial working add_link into the develop branch. It will allow you to add a child to a collection (and will fill the ruby object locally with the child). For example (from features/service_manage.feature):

Given a category: "cat1" exists
And a product: "prod1" exists
When I add a link between category: "cat1" and product: "prod1" on "Products"
And I save changes
Then the product: "prod1" should be one of category: "cat1"'s Products

After the add_link method call, cat1.Products.include? prod1 is true, but prod1.Category.nil? is true right now. You would need to reload prod1 (expanding on Category), then the Category would be filled in because everything works as expected in the database. I'm working on getting the Category to be filled in so that both objects represent the correct state.

@bsaunder2002
Copy link
Author

FYI
Thanks for the work on this. I was unable to use the query links option. From the README.rdoc I got the following:
@cproxy = "http://localhost:8888/"
RestClient.proxy = @cproxy
svc = OData::Service.new "http://..."
svc.Suites(1).links("Experiments")
svc.execute
=> Returns a 400. My devs decided that the 64 bit long format should be used for indexing. As you can see in my code from a previous post, I was adding an L after the suiteId. When I tried that with your code, I got:
svc.Suites(1L).links("Experiments")
=> irb(main):042:0> svc.Suites(1L).links("Experiments")
SyntaxError: (irb):42: syntax error, unexpected tCONSTANT, expecting ')'

Perhaps my devs need to fix their service and allow both 32 bit and 64 bit indexes? Perhaps ruby_odata needs to support both?
Either way, I need to keep attempting to use atompub to create links. :(

(Thx for your contributions, if my guys switch to 32bit index's, I'll start using your code and relay any issues I find.)

1 similar comment
@bsaunder2002
Copy link
Author

FYI
Thanks for the work on this. I was unable to use the query links option. From the README.rdoc I got the following:
@cproxy = "http://localhost:8888/"
RestClient.proxy = @cproxy
svc = OData::Service.new "http://..."
svc.Suites(1).links("Experiments")
svc.execute
=> Returns a 400. My devs decided that the 64 bit long format should be used for indexing. As you can see in my code from a previous post, I was adding an L after the suiteId. When I tried that with your code, I got:
svc.Suites(1L).links("Experiments")
=> irb(main):042:0> svc.Suites(1L).links("Experiments")
SyntaxError: (irb):42: syntax error, unexpected tCONSTANT, expecting ')'

Perhaps my devs need to fix their service and allow both 32 bit and 64 bit indexes? Perhaps ruby_odata needs to support both?
Either way, I need to keep attempting to use atompub to create links. :(

(Thx for your contributions, if my guys switch to 32bit index's, I'll start using your code and relay any issues I find.)

@bsaunder2002
Copy link
Author

(oops, didn't mean to close, I'll leave that up to you)
FYI
Thanks for the work on this. I was unable to use the query links option. From the README.rdoc I got the following:
@cproxy = "http://localhost:8888/"
RestClient.proxy = @cproxy
svc = OData::Service.new "http://..."
svc.Suites(1).links("Experiments")
svc.execute
=> Returns a 400. My devs decided that the 64 bit long format should be used for indexing. As you can see in my code from a previous post, I was adding an L after the suiteId. When I tried that with your code, I got:
svc.Suites(1L).links("Experiments")
=> irb(main):042:0> svc.Suites(1L).links("Experiments")
SyntaxError: (irb):42: syntax error, unexpected tCONSTANT, expecting ')'

Perhaps my devs need to fix their service and allow both 32 bit and 64 bit indexes? Perhaps ruby_odata needs to support both?
Either way, I need to keep attempting to use atompub to create links. :(

(Thx for your contributions, if my guys switch to 32bit index's, I'll start using your code and relay any issues I find.)

@visoft visoft reopened this Nov 22, 2011
@visoft
Copy link
Owner

visoft commented Nov 22, 2011

Thanks for the feedback. I'll look into that.
Off the top of my head, try wrapping the 1L in quotes. Does a normal query work? e.g.:

svc.Suites('1L')
suite = svc.execute.first

@bsaunder2002
Copy link
Author

Thanks, that seemed to work. Now svc.Suites('1L').links("Experiments") / svc.execute is working.

I ran into trouble with the add_links functionality.
mysuite = ews_addSuite(hostname, auth_to
myexp = ews_addExperiment(hostname, auth
property = 'Experiments'
#values retrieved from the mysuite and myexp
svc.Suites('76L')
suite76L = svc.execute.first
svc.Experiments('711L')
exp711L = svc.execute.first
property = 'Experiments'
svc.add_link(suite76L,property,exp711L)
svc.save_changes
=> true
But fiddler shows:
HTTP 202 - Error processing batch request. The following header is not valid ''.
and querying the links for Suite 76 show nothing.
Also, this is a "batch" request, with the url:
http://xxx/DataServices/EMODDataService.svc/$batch?AuthenticationToken=xxx

What's funny is that if I then run:
svc.add_link(suite76L,property,exp711L)
svc.save_changes
=> 403 You do not have permission to this resource
fiddler shows a "good" request missing the additional parameter AuthToken
(Normally my svc is svc = OData::Service.new "http://#{hostname}/DataServices/EMODDataService.svc", { :additional_params => {"AuthenticationToken" => auth_token} } )
The fiddler output for this request is showing:

POST http://xxx/DataServices/EMODDataService.svc/Suites(78L)/$links/Experiments HTTP/1.1
Accept: /; q=0.5, application/xml
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 81
User-Agent: Ruby
Host: xxx

{"uri":"http://xxx/DataServices/EMODDataService.svc/Experiments(713L)"}

So my questions are:
Why is it run as a batch request on the first save_changes but as a "good looking" post on the second try?
Why does the second request not observe the svc's "additional_params" setting?

Thanks again for your help. Feel free to drop this when you want to. I feel bad that my ruby experience is not enough to assist you.

I'm going to attempt to produce the post above by hand. That should get me past the linking problem.
Bill

@visoft
Copy link
Owner

visoft commented Nov 22, 2011

I haven't implemented the batch save yet (don't worry, it's on the list :)), so only a single save works. If you look in service.rb there are two save methods, one called single_save and one called batch_save. The second is a bug, I just pushed a fix (and also fixed another bug that I unearthed fixing the one you found). Thanks for all your testing.

@visoft
Copy link
Owner

visoft commented Nov 22, 2011

I overlooked that the first example tried to do a batch save. Based on what you showed, a batch save shouldn't have occurred. The service keeps a collection of operations (which I think I'll expose because I can see users wanting to see what's in the queue), and clears the collection after you call save_changes. There must have something else in collection that would push it into the batch_save method instead of single_save.

@visoft
Copy link
Owner

visoft commented Nov 23, 2011

Support for add_link within a batch save is in the latest develop branch.

@bsaunder2002
Copy link
Author

AWESOME...just tested it. add_links is now working for me!
#setup proxy
unless @cproxy == ""
RestClient.proxy = @cproxy
end
#set link direction
property = 'Simulations'
#establish connection
svc = OData::Service.new "http://#{hostname}/DataServices/EMODDataService.svc", { :additional_params => {"AuthenticationToken" => auth_token} }
#fetch exp object
svc.Experiments("#{expID}L")
fromExperiment = svc.execute.first
#fetch sim object
svc.Simulations("#{simID}L")
toSimulation = svc.execute.first
#create the link
svc.add_link(fromExperiment,property,toSimulation)
#save changes up to server
svc.save_changes

Whoohoo! Thank you very much!

@visoft
Copy link
Owner

visoft commented Nov 23, 2011

@bsaunder2002

Awesome.
By the way, I added an easier way to pull something by Id. It's not very feature rich at this point (e.g. there's no expand, etc), but you can do:

fromExperiment = Experiment.first("#{expID}L")

Instead of:

svc.Experiments("#{expID}L")
fromExperiment = svc.execute.first

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants