visoft / ruby_odata

OData Consumer for Ruby
http://bit.ly/IntroRubyOData
MIT License
107 stars 52 forks source link

Service with additional request parameters not working #4

Closed mkoegel closed 13 years ago

mkoegel commented 13 years ago

Hi,

due to the multi-tenant nature of SAP gateway we have additional request parameters that determine the client like: http://gw.esworkplace.sap.com/sap/opu/sdata/sap/DEMO_FLIGHT/?sap_client=800

While determining the $metadata for this service ruby_odata just add the $metadata at the end of this URL instead of injecting it before the quesitionmark which doesn't work for us.

Correct should be: http://gw.esworkplace.sap.com/sap/opu/sdata/sap/DEMO_FLIGHT/$metadata?sap_client=800

Would it be possible to extend build_collection_and_classes in service.rb to support this?

You can go to http://www.sdn.sap.com/irj/sdn/gateway?rid=/webcontent/uuid/1051f6d9-e87a-2e10-d188-e2786c7878b1#section6 for same sample services.

Regards, Michael

visoft commented 13 years ago

Michael,

Is the query string only for getting the metadata or does that parameter need to be passed for every call? Take at a look at all the places that @uri is used, for example to query/act against a collection, to process a batch request, etc.

mkoegel commented 13 years ago

Hi Damien,

It's needed for everything call.

Regards, Michael

Sent from my iPad

On 20.09.2011, at 16:14, "Damien White" reply@reply.github.com wrote:

Michael,

Is the query string only for getting the metadata or does that parameter need to be passed for every call? Take at a look at all the places that @uri is used, for example to query/act against a collection, to process a batch request, etc.

Reply to this email directly or view it on GitHub: https://github.com/visoft/ruby_odata/issues/4#issuecomment-2150944

atejada commented 13 years ago

I've doing some work on this...and even when it's not working properly, I manage to get rid of the error:

build_collections_and_classes': undefined methodnamespaces' for nil:NilClass (NoMethodError)

So...right now, there's no error but no output either...here's what I have done so far:

def build_collections_and_classes @classes = Hash.new

Start of Blag Hack client = @uri #Assign the @uri to a temp variable regex = Regexp.new(/.+\?/) #RegEx to check if the string contain the ?sap_client=800 info matchdata = regex.match(client) if matchdata #If something is found client = client.sub(/.+\?/,"") #RegEx to substract everything that comes after the ? service = @uri #Assign the @uri to a temp variable service = service.sub(/\?.+/,"") #RegEx to substract everything that comes before the ? @uri = service + "$metadata?" + client #Concatenate the new @uri with the ?sap_client=800 info doc = Nokogiri::XML(RestClient::Resource.new("#{@uri}", @rest_options).get) else #No ?sap_client=800 info, so keep it like before... doc = Nokogiri::XML(RestClient::Resource.new("#{@uri}/$metadata", @rest_options).get) end
End of Blag Hack

I guess I would need to do this for all the place where @uri is used right? So maybe a method would be more suitable to avoid code duplication...will keep working on this, but please let me know what you think of my solution...

Greetings,

Blag.

visoft commented 13 years ago

I was going to make it so you could pass in n number of params to append each time (in the options hash). Then I was going make the @uri smarter, perhaps by using a "factory" type approach. instead of referencing just @uri, we would call the factory to get the proper URI for the call.

What do you think of that approach?

-Damien

atejada commented 13 years ago

Works for me...while the ?sap_client=800 get properly structured, then we're all good. My solution was kinda dirty, so I think your approach is cleaner and more consistent. Please let us know when it's done so we could keep testing it.

Greetings,

Blag.

visoft commented 13 years ago

Blag/Michael -

Give the latest fix in the develop branch a try: https://github.com/visoft/ruby_odata/commit/03eaab3c85d2af6927c50c4713bfb79ea4b96816

If it works for you, please close the issue.

Thanks, -Damien

atejada commented 13 years ago

Damien:

I tested, however...and this might be my mistake...I did to change two little lines of code...

This is how I'm calling the service:

svc = OData::Service.new "http://gw.esworkplace.sap.com/sap/opu/sdata/sap/DEMO_FLIGHT",{ :username => "GW@ESW", :password=> "ESW4GW", :additional_params=> "sap_client=800"}

What I getting an error because of the .to_query (wrong number of params), so I commented out:

Service.rb:

def build_metadata_uri uri = "#{@uri}/$metadata"

uri << "?#{@additional_params.to_query}" unless @additional_params.empty?

uri << "?#{@additional_params}" unless @additional_params.empty?
uri

end

Query_Builder.rb:

def query q = @root.clone query_options = [] query_options << "$expand=#{@expands.join(',')}" unless @expands.empty? query_options << "$filter=#{@filters.join('+and+')}" unless @filters.empty? query_options << "$orderby=#{@order_bys.join(',')}" unless @order_bys.empty? query_options << "$skip=#{@skip}" unless @skip.nil? query_options << "$top=#{@top}" unless @top.nil?

query_options << @additional_params.to_query unless @additional_params.empty?

query_options << @additional_params unless @additional_params.empty?
if !query_options.empty?
  q << "?"
  q << query_options.join('&')
end
return q

end

With that...everything works as expected! I got a response back from Gateway...so please let me know if .to_query should stay or not...maybe I'm calling the additional parameters in the wrong way...

Greetings,

Blag.

visoft commented 13 years ago

The additional parameters should be passed as a hash, not a string. I did this to eliminate the need to worry about string syntax (question marks, ampersands, etc), and I followed the basic structure of how Rails handles HTML attributes for an element. For example:

svc = OData::Service.new "http://gw.esworkplace.sap.com/sap/opu/sdata/sap/DEMO_FLIGHT",{ :username => "GW@ESW", :password=> "ESW4GW", :additional_params=> { :sap_client => 800 } }

You don't have to use a symbol if you don't want either, hash keys can be strings, but symbols are typically what's used for hash keys, e.g.:

:additional_params=> { 'sap_client' => 800 }
atejada commented 13 years ago

Now I see...it works just fine...for me, this issue is closed, but as Michael open it, I would like him to confirm.

Greetings,

Blag.

mkoegel commented 13 years ago

The additional parameter needs to be :additionalparams=> { 'sap-client' => 800 } '-' not '' Unfortunately :sap-client is not a valid symbol so need to go with 'sap-client' Works fine now.

Thanks for the quick help.