[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

soap4r mapping problem when using google adwords api

Patrick Chanezon

6/23/2005 1:53:00 PM

The Google Adwords sample that Nahi included in the samples at
http://dev.ctor.org/soap4r/file/trunk/sample/wsdl/googleAdwords...
does not work.

In the course of fixing it I ran into a roadblock.
Here's my current fix. I highlight the problems I have fixed, and
areas where I'm not very happy with the fix I found.
---
#!/usr/local/bin/ruby

require 'soap/wsdlDriver'
require 'soap/header/simplehandler'

#wsdl = 'https://adwords.google.com/api/.../CampaignService...
wsdl = 'CampaignService.wsdl'

class HeaderHandler < SOAP::Header::SimpleHandler
def initialize(tag, value)
super(XSD::QName.new(nil, tag))
@tag = tag
@value = value
end

#the initial handler from the sample was wrong, it generated 2 level of tags
def on_simple_outbound
@value
end
end

#problem: wsdl2ruby does not pick up soap/property file, so yields a
certificate error when running against this https url
#run it on local file
# To generate deafult.rb, do like this;
# % wsdl2ruby.rb --wsdl
"https://adwords.google.com/api/.../CampaignService?...
--classdef --force
require 'default'

# I don't have an account of AdWords so the following code is not tested.
# Please tell me (nahi@ruby-lang.org) if you will get good/bad result in
# communicating with AdWords Server...
drv = SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver
#problem: http protocol properties set in soap/property from rubyhome
are not picked up
drv.loadproperty('soap/property')
#print drv.options["client"]["ssl_config"].inspect
#problem: wiredump_dev does not output anything when running in SSL mode
drv.wiredump_dev = STDOUT
#the file based logger works
drv.wiredump_file_base = "log"
drv.headerhandler << HeaderHandler.new('email', 'patlist@chanezon.com')
drv.headerhandler << HeaderHandler.new('password', 'your_password_here')
drv.headerhandler << HeaderHandler.new('useragent', 'P@ playing with
the API from ruby')
drv.headerhandler << HeaderHandler.new('token', 'your_token_here')
camplist = drv.call("getAllAdWordsCampaigns", GetAllAdWordsCampaigns.new(123))
print camplist
---

When I run that with a valid adwords developer account, the call is
made and the correct repsonse is sent back, as seen in the filke log.
However the mapper barfs.

I incldue the relevant data.
Any idea of where to look for next is welcome.
I run soap4r soap4r-1_5_4, which seem to have fixed a few things
regarding doc/literal encoding style.

stack trace
/usr/lib/ruby/1.8/soap/mapping/wsdlliteralregistry.rb:73: warning:
Object#type is deprecated; use Object#class
/usr/lib/ruby/1.8/soap/mapping/wsdlliteralregistry.rb:73:in
`soap2obj': cannot map SOAP::SOAPElement to Ruby object
(SOAP::Mapping::MappingError)
from /usr/lib/ruby/1.8/soap/mapping/mapping.rb:126:in `_soap2obj'
from /usr/lib/ruby/1.8/soap/mapping/mapping.rb:49:in `soap2obj'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:417:in `response_doc_lit'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `collect'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `each'
from /usr/lib/ruby/1.8/soap/baseData.rb:473:in `each'
from /usr/lib/ruby/1.8/soap/baseData.rb:473:in `each'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `collect'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `response_doc_lit'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:382:in `response_doc'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:289:in `response_obj'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:129:in `call'
from /usr/lib/ruby/1.8/soap/rpc/driver.rb:177:in `call'
from ./client.rb:44
in soap2obj #<SOAP::SOAPElement:0x369636
{https://adwords.google.com/api/...}getAllAdWordsCampaignsResponse>

the trace in soap2obj is a print node.inspect

here is the response log
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envel...
xmlns:xsd="http://www.w3.org/2001/XMLSc...
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Header><re...
soapenv:actor="http://schemas.xmlsoap.org/soap/actor/...
soapenv:mustUnderstand="0"
xmlns="https://adwords.google.com/api/...">23</responseTime><operations
soapenv:actor="http://schemas.xmlsoap.org/soap/actor/...
soapenv:mustUnderstand="0"
xmlns="https://adwords.google.com/api/...">3</operations></soapenv:Header>
<soapenv:Body>
<getAllAdWordsCampaignsResponse
xmlns="https://adwords.google.com/api/...">
<getAllAdWordsCampaignsReturn><id>6000213</id><name>Campaign
#1</name><status>Active</status><startDate>2005-04-16T21:27:50.000Z</startDate><endDate>2011-01-01T07:59:59.000Z</endDate><dailyBudget>1000000</dailyBudget><optInSearchNetwork>true</optInSearchNetwork><optInContentNetwork>true</optInContentNetwork><languageTargeting><languages>en</languages></languageTargeting><geoTargeting
xsi:nil="true"/></getAllAdWordsCampaignsReturn>
...
</getAllAdWordsCampaignsResponse></soapenv:Body></soapenv:Envelope>

It seems to barf on <getAllAdWordsCampaignsResponse
xmlns="https://adwords.google.com/api/...">

Here is the rb file generated by wsdl2ruby
require 'xsd/qname'

# {https://adwords.google.com/api/...}getCampaign
class GetCampaign
@@schema_type = "getCampaign"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["id", "SOAP::SOAPInt"]]

attr_accessor :id

def initialize(id = nil)
@id = id
end
end

# {https://adwords.google.com/api/...}getCampaignResponse
class GetCampaignResponse
@@schema_type = "getCampaignResponse"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["getCampaignReturn", "Campaign"]]

attr_accessor :getCampaignReturn

def initialize(getCampaignReturn = nil)
@getCampaignReturn = getCampaignReturn
end
end

# {https://adwords.google.com/api/...}getCampaignList
class GetCampaignList
@@schema_type = "getCampaignList"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["ids", "SOAP::SOAPInt[]"]]

attr_accessor :ids

def initialize(ids = [])
@ids = ids
end
end

# {https://adwords.google.com/api/...}getCampaignListResponse
class GetCampaignListResponse
@@schema_type = "getCampaignListResponse"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["getCampaignListReturn", "Campaign[]"]]

attr_accessor :getCampaignListReturn

def initialize(getCampaignListReturn = [])
@getCampaignListReturn = getCampaignListReturn
end
end

# {https://adwords.google.com/api/...}getAllAdWordsCampaigns
class GetAllAdWordsCampaigns
@@schema_type = "getAllAdWordsCampaigns"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["dummy", "SOAP::SOAPInt"]]

attr_accessor :dummy

def initialize(dummy = nil)
@dummy = dummy
end
end

# {https://adwords.google.com/api/...}getAllAdWordsCampaignsResponse
class GetAllAdWordsCampaignsResponse
@@schema_type = "getAllAdWordsCampaignsResponse"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["getAllAdWordsCampaignsReturn", "Campaign[]"]]

attr_accessor :getAllAdWordsCampaignsReturn

def initialize(getAllAdWordsCampaignsReturn = [])
@getAllAdWordsCampaignsReturn = getAllAdWordsCampaignsReturn
end
end

# {https://adwords.google.com/api/...}addCampaign
class AddCampaign
@@schema_type = "addCampaign"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["campaign", "Campaign"]]

attr_accessor :campaign

def initialize(campaign = nil)
@campaign = campaign
end
end

# {https://adwords.google.com/api/...}addCampaignResponse
class AddCampaignResponse
@@schema_type = "addCampaignResponse"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["addCampaignReturn", "Campaign"]]

attr_accessor :addCampaignReturn

def initialize(addCampaignReturn = nil)
@addCampaignReturn = addCampaignReturn
end
end

# {https://adwords.google.com/api/...}addCampaignList
class AddCampaignList
@@schema_type = "addCampaignList"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["campaigns", "Campaign[]"]]

attr_accessor :campaigns

def initialize(campaigns = [])
@campaigns = campaigns
end
end

# {https://adwords.google.com/api/...}addCampaignListResponse
class AddCampaignListResponse
@@schema_type = "addCampaignListResponse"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["addCampaignListReturn", "Campaign[]"]]

attr_accessor :addCampaignListReturn

def initialize(addCampaignListReturn = [])
@addCampaignListReturn = addCampaignListReturn
end
end

# {https://adwords.google.com/api/...}updateCampaign
class UpdateCampaign
@@schema_type = "updateCampaign"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["campaign", "Campaign"]]

attr_accessor :campaign

def initialize(campaign = nil)
@campaign = campaign
end
end

# {https://adwords.google.com/api/...}updateCampaignResponse
class UpdateCampaignResponse
@@schema_type = "updateCampaignResponse"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = []

def initialize
end
end

# {https://adwords.google.com/api/...}updateCampaignList
class UpdateCampaignList
@@schema_type = "updateCampaignList"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["campaigns", "Campaign[]"]]

attr_accessor :campaigns

def initialize(campaigns = [])
@campaigns = campaigns
end
end

# {https://adwords.google.com/api/...}updateCampaignListResponse
class UpdateCampaignListResponse
@@schema_type = "updateCampaignListResponse"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = []

def initialize
end
end

# {https://adwords.google.com/api/...}getOptimizeAdServing
class GetOptimizeAdServing
@@schema_type = "getOptimizeAdServing"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["campaignId", "SOAP::SOAPInt"]]

attr_accessor :campaignId

def initialize(campaignId = nil)
@campaignId = campaignId
end
end

# {https://adwords.google.com/api/...}getOptimizeAdServingResponse
class GetOptimizeAdServingResponse
@@schema_type = "getOptimizeAdServingResponse"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["getOptimizeAdServingReturn", "SOAP::SOAPBoolean"]]

attr_accessor :getOptimizeAdServingReturn

def initialize(getOptimizeAdServingReturn = nil)
@getOptimizeAdServingReturn = getOptimizeAdServingReturn
end
end

# {https://adwords.google.com/api/...}setOptimizeAdServing
class SetOptimizeAdServing
@@schema_type = "setOptimizeAdServing"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["campaignId", "SOAP::SOAPInt"], ["enable",
"SOAP::SOAPBoolean"]]

attr_accessor :campaignId
attr_accessor :enable

def initialize(campaignId = nil, enable = nil)
@campaignId = campaignId
@enable = enable
end
end

# {https://adwords.google.com/api/...}setOptimizeAdServingResponse
class SetOptimizeAdServingResponse
@@schema_type = "setOptimizeAdServingResponse"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = []

def initialize
end
end

# {https://adwords.google.com/api/...}getCampaignStats
class GetCampaignStats
@@schema_type = "getCampaignStats"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["campaignIds", "SOAP::SOAPInt[]"], ["start",
"SOAP::SOAPDateTime"], ["v_end", ["SOAP::SOAPDateTime",
XSD::QName.new(nil, "end")]]]

attr_accessor :campaignIds
attr_accessor :start

def end
@v_end
end

def end=(value)
@v_end = value
end

def initialize(campaignIds = [], start = nil, v_end = nil)
@campaignIds = campaignIds
@start = start
@v_end = v_end
end
end

# {https://adwords.google.com/api/...}getCampaignStatsResponse
class GetCampaignStatsResponse
@@schema_type = "getCampaignStatsResponse"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["getCampaignStatsReturn", "StatsRecord[]"]]

attr_accessor :getCampaignStatsReturn

def initialize(getCampaignStatsReturn = [])
@getCampaignStatsReturn = getCampaignStatsReturn
end
end

# {https://adwords.google.com/api/...}Keyword
class Keyword
@@schema_type = "Keyword"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["type", "KeywordType"], ["maxCpc",
"SOAP::SOAPLong"], ["adGroupId", "SOAP::SOAPInt"], ["language",
"SOAP::SOAPString"], ["status", "KeywordStatus"], ["negative",
"SOAP::SOAPBoolean"], ["destinationUrl", "SOAP::SOAPString"], ["text",
"SOAP::SOAPString"], ["id", "SOAP::SOAPInt"], ["exemptionRequest",
"SOAP::SOAPString"]]

attr_accessor :type
attr_accessor :maxCpc
attr_accessor :adGroupId
attr_accessor :language
attr_accessor :status
attr_accessor :negative
attr_accessor :destinationUrl
attr_accessor :text
attr_accessor :id
attr_accessor :exemptionRequest

def initialize(type = nil, maxCpc = nil, adGroupId = nil, language =
nil, status = nil, negative = nil, destinationUrl = nil, text = nil,
id = nil, exemptionRequest = nil)
@type = type
@maxCpc = maxCpc
@adGroupId = adGroupId
@language = language
@status = status
@negative = negative
@destinationUrl = destinationUrl
@text = text
@id = id
@exemptionRequest = exemptionRequest
end
end

# {https://adwords.google.com/api/...}LanguageTarget
class LanguageTarget < ::Array
@@schema_type = "string"
@@schema_ns = "http://www.w3.org/2001/XMLSc...
end

# {https://adwords.google.com/api/...}GeoTarget
class GeoTarget
@@schema_type = "GeoTarget"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["countries", "SOAP::SOAPString[]"], ["regions",
"SOAP::SOAPString[]"], ["metros", "SOAP::SOAPString[]"], ["cities",
"SOAP::SOAPString[]"]]

attr_accessor :countries
attr_accessor :regions
attr_accessor :metros
attr_accessor :cities

def initialize(countries = [], regions = [], metros = [], cities = [])
@countries = countries
@regions = regions
@metros = metros
@cities = cities
end
end

# {https://adwords.google.com/api/...}Campaign
class Campaign
@@schema_type = "Campaign"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["id", "SOAP::SOAPInt"], ["name",
"SOAP::SOAPString"], ["status", "CampaignStatus"], ["startDate",
"SOAP::SOAPDateTime"], ["endDate", "SOAP::SOAPDateTime"],
["dailyBudget", "SOAP::SOAPLong"], ["optInSearchNetwork",
"SOAP::SOAPBoolean"], ["optInContentNetwork", "SOAP::SOAPBoolean"],
["campaignNegativeKeywords", "Keyword[]"], ["languageTargeting",
"LanguageTarget"], ["geoTargeting", "GeoTarget"]]

attr_accessor :id
attr_accessor :name
attr_accessor :status
attr_accessor :startDate
attr_accessor :endDate
attr_accessor :dailyBudget
attr_accessor :optInSearchNetwork
attr_accessor :optInContentNetwork
attr_accessor :campaignNegativeKeywords
attr_accessor :languageTargeting
attr_accessor :geoTargeting

def initialize(id = nil, name = nil, status = nil, startDate = nil,
endDate = nil, dailyBudget = nil, optInSearchNetwork = nil,
optInContentNetwork = nil, campaignNegativeKeywords = [],
languageTargeting = nil, geoTargeting = nil)
@id = id
@name = name
@status = status
@startDate = startDate
@endDate = endDate
@dailyBudget = dailyBudget
@optInSearchNetwork = optInSearchNetwork
@optInContentNetwork = optInContentNetwork
@campaignNegativeKeywords = campaignNegativeKeywords
@languageTargeting = languageTargeting
@geoTargeting = geoTargeting
end
end

# {https://adwords.google.com/api/...}ApiException
class ApiException
@@schema_type = "ApiException"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["code", "SOAP::SOAPInt"], ["internal",
"SOAP::SOAPBoolean"], ["message", "SOAP::SOAPString"], ["trigger",
"SOAP::SOAPString"], ["violations", "SOAP::SOAPString"]]

attr_accessor :code
attr_accessor :internal
attr_accessor :message
attr_accessor :trigger
attr_accessor :violations

def initialize(code = nil, internal = nil, message = nil, trigger =
nil, violations = nil)
@code = code
@internal = internal
@message = message
@trigger = trigger
@violations = violations
end
end

# {https://adwords.google.com/api/...}StatsRecord
class StatsRecord
@@schema_type = "StatsRecord"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["averagePosition", "SOAP::SOAPDouble"],
["clicks", "SOAP::SOAPLong"], ["conversionRate", "SOAP::SOAPDouble"],
["conversions", "SOAP::SOAPLong"], ["cost", "SOAP::SOAPLong"], ["id",
"SOAP::SOAPLong"], ["impressions", "SOAP::SOAPLong"]]

attr_accessor :averagePosition
attr_accessor :clicks
attr_accessor :conversionRate
attr_accessor :conversions
attr_accessor :cost
attr_accessor :id
attr_accessor :impressions

def initialize(averagePosition = nil, clicks = nil, conversionRate =
nil, conversions = nil, cost = nil, id = nil, impressions = nil)
@averagePosition = averagePosition
@clicks = clicks
@conversionRate = conversionRate
@conversions = conversions
@cost = cost
@id = id
@impressions = impressions
end
end

# {https://adwords.google.com/api/...}KeywordStatus
module KeywordStatus
Deleted = "Deleted"
Disabled = "Disabled"
Disapproved = "Disapproved"
InTrial = "InTrial"
Normal = "Normal"
OnHold = "OnHold"
end

# {https://adwords.google.com/api/...}KeywordType
module KeywordType
Broad = "Broad"
Exact = "Exact"
Phrase = "Phrase"
end

# {https://adwords.google.com/api/...}CampaignStatus
module CampaignStatus
Active = "Active"
Deleted = "Deleted"
Ended = "Ended"
Paused = "Paused"
Pending = "Pending"
Suspended = "Suspended"
end

The error happens in soap/mapping/wsdlliteralregistry.rb

# node should be a SOAPElement
def soap2obj(node, obj_class = nil)
print "in soap2obj #{node.inspect}"
unless obj_class.nil?
raise MappingError.new("must not reach here")
end
begin
return any2obj(node)
rescue MappingError
end
if @excn_handler_soap2obj
begin
return @excn_handler_soap2obj.call(node) { |yield_node|
Mapping._soap2obj(yield_node, self)
}
rescue Exception
end
end
raise MappingError.new("cannot map #{node.type.name} to Ruby object")
end

I guess the problem must lie in the fact that the class
GetAllAdWordsCampaignsResponse is not known to the registry, to be
applied to the response element
{https://adwords.google.com/api/...}getAllAdWordsCampaignsResponse>

# {https://adwords.google.com/api/...}getAllAdWordsCampaignsResponse
class GetAllAdWordsCampaignsResponse
@@schema_type = "getAllAdWordsCampaignsResponse"
@@schema_ns = "https://adwords.google.com/api/..."
@@schema_element = [["getAllAdWordsCampaignsReturn", "Campaign[]"]]

How is this registry informed about the classes that must be used for
mapping when using the wsdl files?
Is there a message to be sent to drv in order to let it know about
default.rb classes?

A few hours later after finding this other sample
I now generate the client driver myself using wsdl2ruby
wsdl2ruby.rb --wsdl CampaignService.wsdl --type client

Now I understand where the mapping is defined.
Still the new program yields the same error

---
#!/usr/local/bin/ruby

require 'soap/wsdlDriver'
require 'soap/header/simplehandler'

wsdl = 'https://adwords.google.com/api/.../CampaignService...

class HeaderHandler < SOAP::Header::SimpleHandler
def initialize(tag, value)
super(XSD::QName.new(nil, tag))
@tag = tag
@value = value
end

#the initial handler from the sample was wrong, it generated 2 level of tags
def on_simple_outbound
@value
end
end

#problem: wsdl2ruby does not pick up soap/property file, so yields a
certificate error when running against this https url
#run it on local file
# To generate deafult.rb, do like this;
# % wsdl2ruby.rb --wsdl
"https://adwords.google.com/api/.../CampaignService?...
--classdef --force
#require 'default'

# I don't have an account of AdWords so the following code is not tested.
# Please tell me (nahi@ruby-lang.org) if you will get good/bad result in
# communicating with AdWords Server...
#drv = SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver

require 'defaultDriver.rb'
require 'yaml'

prefs = YAML::load( File.open('adwords.yaml', 'r'))
headers = prefs['headers']

drv = CampaignService.new()

#problem: http protocol properties set in soap/property from rubyhome
are not picked up
drv.loadproperty('soap/property')
#problem: wiredump_dev does not output anything when running in SSL mode
#drv.wiredump_dev = STDOUT
#the file based logger works
drv.wiredump_file_base = "log"

headers.each {|key, value| drv.headerhandler << HeaderHandler.new(key, value)}

puts drv.getAllAdWordsCampaigns(GetAllAdWordsCampaigns.new(123))
---

/usr/lib/ruby/1.8/soap/mapping/wsdlliteralregistry.rb:73:in
`soap2obj': cannot map SOAP::SOAPElement to Ruby object
(SOAP::Mapping::MappingError)
from /usr/lib/ruby/1.8/soap/mapping/mapping.rb:126:in `_soap2obj'
from /usr/lib/ruby/1.8/soap/mapping/mapping.rb:49:in `soap2obj'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:417:in `response_doc_lit'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `collect'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `each'
from /usr/lib/ruby/1.8/soap/baseData.rb:473:in `each'
from /usr/lib/ruby/1.8/soap/baseData.rb:473:in `each'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `collect'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `response_doc_lit'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:382:in `response_doc'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:289:in `response_obj'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:129:in `call'
from /usr/lib/ruby/1.8/soap/rpc/driver.rb:177:in `call'
from /usr/lib/ruby/1.8/soap/rpc/driver.rb:231:in
`getAllAdWordsCampaigns'
from /usr/lib/ruby/1.8/soap/rpc/driver.rb:226:in
`getAllAdWordsCampaigns'
from ./client.rb:39
in soap2obj #<SOAP::SOAPElement:0x36be68
{https://adwords.google.com/api/...}getAllAdWordsCampaignsResponse>

It is as if the mapping defined in CampaignService is not used.

Thanks in advance for any hints.

P@


1 Answer

Patrick Chanezon

6/23/2005 3:41:00 PM

0

adding some debug in proxy.rb
def response_doc_lit(body, mapping_registry)
puts "in proxy mapping = #{mapping_registry.inspect}"
body.collect { |key, value|
Mapping.soap2obj(value, mapping_registry)
}
end

shows that the mapping does not contain any information about the adwords types
in proxy mapping = #<SOAP::Mapping::WSDLLiteralRegistry:0x6eea34
@excn_handler_obj2soap=nil,
@schema_element_cache={GetAllAdWordsCampaigns=>[{"dummy"=>"SOAP::SOAPInt"},
[]]}, @schema_attribute_cache={GetAllAdWordsCampaigns=>nil},
@definedtypes=#<XSD::NamedElements:0x2a56fc
@cache={#<XSD::QName:0x3706ca {}dummy>=>nil, #<XSD::QName:0x3766b0
{https://adwords.google.com/api/...}getAllAdWordsCampaigns>=>nil},
@elements=[]>, @definedelements=#<XSD::NamedElements:0x2a56fc
@cache={#<XSD::QName:0x3706ca {}dummy>=>nil, #<XSD::QName:0x3766b0
{https://adwords.google.com/api/...}getAllAdWordsCampaigns>=>nil},
@elements=[]>, @excn_handler_soap2obj=nil>

Is the init generated by wsdl2ruby correct?
if RUBY_VERSION > "1.7.0"
def add_method_interface(name, param_count)
::SOAP::Mapping.define_singleton_method(self, name) do |*arg|
unless arg.size == param_count
raise ArgumentError.new(
"wrong number of arguments (#{arg.size} for #{param_count})")
end
call(name, *arg)
end
self.method(name)
end

On 6/23/05, Patrick Chanezon <chanezon@gmail.com> wrote:
> The Google Adwords sample that Nahi included in the samples at
> http://dev.ctor.org/soap4r/file/trunk/sample/wsdl/googleAdwords...
> does not work.
>
> In the course of fixing it I ran into a roadblock.
> Here's my current fix. I highlight the problems I have fixed, and
> areas where I'm not very happy with the fix I found.
> ---
> #!/usr/local/bin/ruby
>
> require 'soap/wsdlDriver'
> require 'soap/header/simplehandler'
>
> #wsdl = 'https://adwords.google.com/api/.../CampaignService?WSDL'
> wsdl = 'CampaignService.wsdl'
>
> class HeaderHandler < SOAP::Header::SimpleHandler
> def initialize(tag, value)
> super(XSD::QName.new(nil, tag))
> @tag = tag
> @value = value
> end
>
> #the initial handler from the sample was wrong, it generated 2 level of tags
> def on_simple_outbound
> @value
> end
> end
>
> #problem: wsdl2ruby does not pick up soap/property file, so yields a
> certificate error when running against this https url
> #run it on local file
> # To generate deafult.rb, do like this;
> # % wsdl2ruby.rb --wsdl
> "https://adwords.google.com/api/.../CampaignService?WSDL"
> --classdef --force
> require 'default'
>
> # I don't have an account of AdWords so the following code is not tested.
> # Please tell me (nahi@ruby-lang.org) if you will get good/bad result in
> # communicating with AdWords Server...
> drv = SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver
> #problem: http protocol properties set in soap/property from rubyhome
> are not picked up
> drv.loadproperty('soap/property')
> #print drv.options["client"]["ssl_config"].inspect
> #problem: wiredump_dev does not output anything when running in SSL mode
> drv.wiredump_dev = STDOUT
> #the file based logger works
> drv.wiredump_file_base = "log"
> drv.headerhandler << HeaderHandler.new('email', 'patlist@chanezon.com')
> drv.headerhandler << HeaderHandler.new('password', 'your_password_here')
> drv.headerhandler << HeaderHandler.new('useragent', 'P@ playing with
> the API from ruby')
> drv.headerhandler << HeaderHandler.new('token', 'your_token_here')
> camplist = drv.call("getAllAdWordsCampaigns", GetAllAdWordsCampaigns.new(123))
> print camplist
> ---
>
> When I run that with a valid adwords developer account, the call is
> made and the correct repsonse is sent back, as seen in the filke log.
> However the mapper barfs.
>
> I incldue the relevant data.
> Any idea of where to look for next is welcome.
> I run soap4r soap4r-1_5_4, which seem to have fixed a few things
> regarding doc/literal encoding style.
>
> stack trace
> /usr/lib/ruby/1.8/soap/mapping/wsdlliteralregistry.rb:73: warning:
> Object#type is deprecated; use Object#class
> /usr/lib/ruby/1.8/soap/mapping/wsdlliteralregistry.rb:73:in
> `soap2obj': cannot map SOAP::SOAPElement to Ruby object
> (SOAP::Mapping::MappingError)
> from /usr/lib/ruby/1.8/soap/mapping/mapping.rb:126:in `_soap2obj'
> from /usr/lib/ruby/1.8/soap/mapping/mapping.rb:49:in `soap2obj'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:417:in `response_doc_lit'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `collect'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `each'
> from /usr/lib/ruby/1.8/soap/baseData.rb:473:in `each'
> from /usr/lib/ruby/1.8/soap/baseData.rb:473:in `each'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `collect'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `response_doc_lit'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:382:in `response_doc'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:289:in `response_obj'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:129:in `call'
> from /usr/lib/ruby/1.8/soap/rpc/driver.rb:177:in `call'
> from ./client.rb:44
> in soap2obj #<SOAP::SOAPElement:0x369636
> {https://adwords.google.com/api/...}getAllAdWordsCampaignsResponse>
>
> the trace in soap2obj is a print node.inspect
>
> here is the response log
> <soapenv:Envelope
> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envel...
> xmlns:xsd="http://www.w3.org/2001/XMLSc...
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Header><re...
> soapenv:actor="http://schemas.xmlsoap.org/soap/actor/...
> soapenv:mustUnderstand="0"
> xmlns="https://adwords.google.com/api/...">23</responseTime><operations
> soapenv:actor="http://schemas.xmlsoap.org/soap/actor/...
> soapenv:mustUnderstand="0"
> xmlns="https://adwords.google.com/api/...">3</operations></soapenv:Header>
> <soapenv:Body>
> <getAllAdWordsCampaignsResponse
> xmlns="https://adwords.google.com/api/...">
> <getAllAdWordsCampaignsReturn><id>6000213</id><name>Campaign
> #1</name><status>Active</status><startDate>2005-04-16T21:27:50.000Z</startDate><endDate>2011-01-01T07:59:59.000Z</endDate><dailyBudget>1000000</dailyBudget><optInSearchNetwork>true</optInSearchNetwork><optInContentNetwork>true</optInContentNetwork><languageTargeting><languages>en</languages></languageTargeting><geoTargeting
> xsi:nil="true"/></getAllAdWordsCampaignsReturn>
> ...
> </getAllAdWordsCampaignsResponse></soapenv:Body></soapenv:Envelope>
>
> It seems to barf on <getAllAdWordsCampaignsResponse
> xmlns="https://adwords.google.com/api/...">
>
> Here is the rb file generated by wsdl2ruby
> require 'xsd/qname'
>
> # {https://adwords.google.com/api/...}getCampaign
> class GetCampaign
> @@schema_type = "getCampaign"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["id", "SOAP::SOAPInt"]]
>
> attr_accessor :id
>
> def initialize(id = nil)
> @id = id
> end
> end
>
> # {https://adwords.google.com/api/...}getCampaignResponse
> class GetCampaignResponse
> @@schema_type = "getCampaignResponse"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["getCampaignReturn", "Campaign"]]
>
> attr_accessor :getCampaignReturn
>
> def initialize(getCampaignReturn = nil)
> @getCampaignReturn = getCampaignReturn
> end
> end
>
> # {https://adwords.google.com/api/...}getCampaignList
> class GetCampaignList
> @@schema_type = "getCampaignList"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["ids", "SOAP::SOAPInt[]"]]
>
> attr_accessor :ids
>
> def initialize(ids = [])
> @ids = ids
> end
> end
>
> # {https://adwords.google.com/api/...}getCampaignListResponse
> class GetCampaignListResponse
> @@schema_type = "getCampaignListResponse"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["getCampaignListReturn", "Campaign[]"]]
>
> attr_accessor :getCampaignListReturn
>
> def initialize(getCampaignListReturn = [])
> @getCampaignListReturn = getCampaignListReturn
> end
> end
>
> # {https://adwords.google.com/api/...}getAllAdWordsCampaigns
> class GetAllAdWordsCampaigns
> @@schema_type = "getAllAdWordsCampaigns"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["dummy", "SOAP::SOAPInt"]]
>
> attr_accessor :dummy
>
> def initialize(dummy = nil)
> @dummy = dummy
> end
> end
>
> # {https://adwords.google.com/api/...}getAllAdWordsCampaignsResponse
> class GetAllAdWordsCampaignsResponse
> @@schema_type = "getAllAdWordsCampaignsResponse"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["getAllAdWordsCampaignsReturn", "Campaign[]"]]
>
> attr_accessor :getAllAdWordsCampaignsReturn
>
> def initialize(getAllAdWordsCampaignsReturn = [])
> @getAllAdWordsCampaignsReturn = getAllAdWordsCampaignsReturn
> end
> end
>
> # {https://adwords.google.com/api/...}addCampaign
> class AddCampaign
> @@schema_type = "addCampaign"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["campaign", "Campaign"]]
>
> attr_accessor :campaign
>
> def initialize(campaign = nil)
> @campaign = campaign
> end
> end
>
> # {https://adwords.google.com/api/...}addCampaignResponse
> class AddCampaignResponse
> @@schema_type = "addCampaignResponse"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["addCampaignReturn", "Campaign"]]
>
> attr_accessor :addCampaignReturn
>
> def initialize(addCampaignReturn = nil)
> @addCampaignReturn = addCampaignReturn
> end
> end
>
> # {https://adwords.google.com/api/...}addCampaignList
> class AddCampaignList
> @@schema_type = "addCampaignList"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["campaigns", "Campaign[]"]]
>
> attr_accessor :campaigns
>
> def initialize(campaigns = [])
> @campaigns = campaigns
> end
> end
>
> # {https://adwords.google.com/api/...}addCampaignListResponse
> class AddCampaignListResponse
> @@schema_type = "addCampaignListResponse"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["addCampaignListReturn", "Campaign[]"]]
>
> attr_accessor :addCampaignListReturn
>
> def initialize(addCampaignListReturn = [])
> @addCampaignListReturn = addCampaignListReturn
> end
> end
>
> # {https://adwords.google.com/api/...}updateCampaign
> class UpdateCampaign
> @@schema_type = "updateCampaign"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["campaign", "Campaign"]]
>
> attr_accessor :campaign
>
> def initialize(campaign = nil)
> @campaign = campaign
> end
> end
>
> # {https://adwords.google.com/api/...}updateCampaignResponse
> class UpdateCampaignResponse
> @@schema_type = "updateCampaignResponse"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = []
>
> def initialize
> end
> end
>
> # {https://adwords.google.com/api/...}updateCampaignList
> class UpdateCampaignList
> @@schema_type = "updateCampaignList"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["campaigns", "Campaign[]"]]
>
> attr_accessor :campaigns
>
> def initialize(campaigns = [])
> @campaigns = campaigns
> end
> end
>
> # {https://adwords.google.com/api/...}updateCampaignListResponse
> class UpdateCampaignListResponse
> @@schema_type = "updateCampaignListResponse"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = []
>
> def initialize
> end
> end
>
> # {https://adwords.google.com/api/...}getOptimizeAdServing
> class GetOptimizeAdServing
> @@schema_type = "getOptimizeAdServing"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["campaignId", "SOAP::SOAPInt"]]
>
> attr_accessor :campaignId
>
> def initialize(campaignId = nil)
> @campaignId = campaignId
> end
> end
>
> # {https://adwords.google.com/api/...}getOptimizeAdServingResponse
> class GetOptimizeAdServingResponse
> @@schema_type = "getOptimizeAdServingResponse"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["getOptimizeAdServingReturn", "SOAP::SOAPBoolean"]]
>
> attr_accessor :getOptimizeAdServingReturn
>
> def initialize(getOptimizeAdServingReturn = nil)
> @getOptimizeAdServingReturn = getOptimizeAdServingReturn
> end
> end
>
> # {https://adwords.google.com/api/...}setOptimizeAdServing
> class SetOptimizeAdServing
> @@schema_type = "setOptimizeAdServing"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["campaignId", "SOAP::SOAPInt"], ["enable",
> "SOAP::SOAPBoolean"]]
>
> attr_accessor :campaignId
> attr_accessor :enable
>
> def initialize(campaignId = nil, enable = nil)
> @campaignId = campaignId
> @enable = enable
> end
> end
>
> # {https://adwords.google.com/api/...}setOptimizeAdServingResponse
> class SetOptimizeAdServingResponse
> @@schema_type = "setOptimizeAdServingResponse"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = []
>
> def initialize
> end
> end
>
> # {https://adwords.google.com/api/...}getCampaignStats
> class GetCampaignStats
> @@schema_type = "getCampaignStats"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["campaignIds", "SOAP::SOAPInt[]"], ["start",
> "SOAP::SOAPDateTime"], ["v_end", ["SOAP::SOAPDateTime",
> XSD::QName.new(nil, "end")]]]
>
> attr_accessor :campaignIds
> attr_accessor :start
>
> def end
> @v_end
> end
>
> def end=(value)
> @v_end = value
> end
>
> def initialize(campaignIds = [], start = nil, v_end = nil)
> @campaignIds = campaignIds
> @start = start
> @v_end = v_end
> end
> end
>
> # {https://adwords.google.com/api/...}getCampaignStatsResponse
> class GetCampaignStatsResponse
> @@schema_type = "getCampaignStatsResponse"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["getCampaignStatsReturn", "StatsRecord[]"]]
>
> attr_accessor :getCampaignStatsReturn
>
> def initialize(getCampaignStatsReturn = [])
> @getCampaignStatsReturn = getCampaignStatsReturn
> end
> end
>
> # {https://adwords.google.com/api/...}Keyword
> class Keyword
> @@schema_type = "Keyword"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["type", "KeywordType"], ["maxCpc",
> "SOAP::SOAPLong"], ["adGroupId", "SOAP::SOAPInt"], ["language",
> "SOAP::SOAPString"], ["status", "KeywordStatus"], ["negative",
> "SOAP::SOAPBoolean"], ["destinationUrl", "SOAP::SOAPString"], ["text",
> "SOAP::SOAPString"], ["id", "SOAP::SOAPInt"], ["exemptionRequest",
> "SOAP::SOAPString"]]
>
> attr_accessor :type
> attr_accessor :maxCpc
> attr_accessor :adGroupId
> attr_accessor :language
> attr_accessor :status
> attr_accessor :negative
> attr_accessor :destinationUrl
> attr_accessor :text
> attr_accessor :id
> attr_accessor :exemptionRequest
>
> def initialize(type = nil, maxCpc = nil, adGroupId = nil, language =
> nil, status = nil, negative = nil, destinationUrl = nil, text = nil,
> id = nil, exemptionRequest = nil)
> @type = type
> @maxCpc = maxCpc
> @adGroupId = adGroupId
> @language = language
> @status = status
> @negative = negative
> @destinationUrl = destinationUrl
> @text = text
> @id = id
> @exemptionRequest = exemptionRequest
> end
> end
>
> # {https://adwords.google.com/api/...}LanguageTarget
> class LanguageTarget < ::Array
> @@schema_type = "string"
> @@schema_ns = "http://www.w3.org/2001/XMLSc...
> end
>
> # {https://adwords.google.com/api/...}GeoTarget
> class GeoTarget
> @@schema_type = "GeoTarget"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["countries", "SOAP::SOAPString[]"], ["regions",
> "SOAP::SOAPString[]"], ["metros", "SOAP::SOAPString[]"], ["cities",
> "SOAP::SOAPString[]"]]
>
> attr_accessor :countries
> attr_accessor :regions
> attr_accessor :metros
> attr_accessor :cities
>
> def initialize(countries = [], regions = [], metros = [], cities = [])
> @countries = countries
> @regions = regions
> @metros = metros
> @cities = cities
> end
> end
>
> # {https://adwords.google.com/api/...}Campaign
> class Campaign
> @@schema_type = "Campaign"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["id", "SOAP::SOAPInt"], ["name",
> "SOAP::SOAPString"], ["status", "CampaignStatus"], ["startDate",
> "SOAP::SOAPDateTime"], ["endDate", "SOAP::SOAPDateTime"],
> ["dailyBudget", "SOAP::SOAPLong"], ["optInSearchNetwork",
> "SOAP::SOAPBoolean"], ["optInContentNetwork", "SOAP::SOAPBoolean"],
> ["campaignNegativeKeywords", "Keyword[]"], ["languageTargeting",
> "LanguageTarget"], ["geoTargeting", "GeoTarget"]]
>
> attr_accessor :id
> attr_accessor :name
> attr_accessor :status
> attr_accessor :startDate
> attr_accessor :endDate
> attr_accessor :dailyBudget
> attr_accessor :optInSearchNetwork
> attr_accessor :optInContentNetwork
> attr_accessor :campaignNegativeKeywords
> attr_accessor :languageTargeting
> attr_accessor :geoTargeting
>
> def initialize(id = nil, name = nil, status = nil, startDate = nil,
> endDate = nil, dailyBudget = nil, optInSearchNetwork = nil,
> optInContentNetwork = nil, campaignNegativeKeywords = [],
> languageTargeting = nil, geoTargeting = nil)
> @id = id
> @name = name
> @status = status
> @startDate = startDate
> @endDate = endDate
> @dailyBudget = dailyBudget
> @optInSearchNetwork = optInSearchNetwork
> @optInContentNetwork = optInContentNetwork
> @campaignNegativeKeywords = campaignNegativeKeywords
> @languageTargeting = languageTargeting
> @geoTargeting = geoTargeting
> end
> end
>
> # {https://adwords.google.com/api/...}ApiException
> class ApiException
> @@schema_type = "ApiException"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["code", "SOAP::SOAPInt"], ["internal",
> "SOAP::SOAPBoolean"], ["message", "SOAP::SOAPString"], ["trigger",
> "SOAP::SOAPString"], ["violations", "SOAP::SOAPString"]]
>
> attr_accessor :code
> attr_accessor :internal
> attr_accessor :message
> attr_accessor :trigger
> attr_accessor :violations
>
> def initialize(code = nil, internal = nil, message = nil, trigger =
> nil, violations = nil)
> @code = code
> @internal = internal
> @message = message
> @trigger = trigger
> @violations = violations
> end
> end
>
> # {https://adwords.google.com/api/...}StatsRecord
> class StatsRecord
> @@schema_type = "StatsRecord"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["averagePosition", "SOAP::SOAPDouble"],
> ["clicks", "SOAP::SOAPLong"], ["conversionRate", "SOAP::SOAPDouble"],
> ["conversions", "SOAP::SOAPLong"], ["cost", "SOAP::SOAPLong"], ["id",
> "SOAP::SOAPLong"], ["impressions", "SOAP::SOAPLong"]]
>
> attr_accessor :averagePosition
> attr_accessor :clicks
> attr_accessor :conversionRate
> attr_accessor :conversions
> attr_accessor :cost
> attr_accessor :id
> attr_accessor :impressions
>
> def initialize(averagePosition = nil, clicks = nil, conversionRate =
> nil, conversions = nil, cost = nil, id = nil, impressions = nil)
> @averagePosition = averagePosition
> @clicks = clicks
> @conversionRate = conversionRate
> @conversions = conversions
> @cost = cost
> @id = id
> @impressions = impressions
> end
> end
>
> # {https://adwords.google.com/api/...}KeywordStatus
> module KeywordStatus
> Deleted = "Deleted"
> Disabled = "Disabled"
> Disapproved = "Disapproved"
> InTrial = "InTrial"
> Normal = "Normal"
> OnHold = "OnHold"
> end
>
> # {https://adwords.google.com/api/...}KeywordType
> module KeywordType
> Broad = "Broad"
> Exact = "Exact"
> Phrase = "Phrase"
> end
>
> # {https://adwords.google.com/api/...}CampaignStatus
> module CampaignStatus
> Active = "Active"
> Deleted = "Deleted"
> Ended = "Ended"
> Paused = "Paused"
> Pending = "Pending"
> Suspended = "Suspended"
> end
>
> The error happens in soap/mapping/wsdlliteralregistry.rb
>
> # node should be a SOAPElement
> def soap2obj(node, obj_class = nil)
> print "in soap2obj #{node.inspect}"
> unless obj_class.nil?
> raise MappingError.new("must not reach here")
> end
> begin
> return any2obj(node)
> rescue MappingError
> end
> if @excn_handler_soap2obj
> begin
> return @excn_handler_soap2obj.call(node) { |yield_node|
> Mapping._soap2obj(yield_node, self)
> }
> rescue Exception
> end
> end
> raise MappingError.new("cannot map #{node.type.name} to Ruby object")
> end
>
> I guess the problem must lie in the fact that the class
> GetAllAdWordsCampaignsResponse is not known to the registry, to be
> applied to the response element
> {https://adwords.google.com/api/...}getAllAdWordsCampaignsResponse>
>
> # {https://adwords.google.com/api/...}getAllAdWordsCampaignsResponse
> class GetAllAdWordsCampaignsResponse
> @@schema_type = "getAllAdWordsCampaignsResponse"
> @@schema_ns = "https://adwords.google.com/api/..."
> @@schema_element = [["getAllAdWordsCampaignsReturn", "Campaign[]"]]
>
> How is this registry informed about the classes that must be used for
> mapping when using the wsdl files?
> Is there a message to be sent to drv in order to let it know about
> default.rb classes?
>
> A few hours later after finding this other sample
> I now generate the client driver myself using wsdl2ruby
> wsdl2ruby.rb --wsdl CampaignService.wsdl --type client
>
> Now I understand where the mapping is defined.
> Still the new program yields the same error
>
> ---
> #!/usr/local/bin/ruby
>
> require 'soap/wsdlDriver'
> require 'soap/header/simplehandler'
>
> wsdl = 'https://adwords.google.com/api/.../CampaignService?WSDL'
>
> class HeaderHandler < SOAP::Header::SimpleHandler
> def initialize(tag, value)
> super(XSD::QName.new(nil, tag))
> @tag = tag
> @value = value
> end
>
> #the initial handler from the sample was wrong, it generated 2 level of tags
> def on_simple_outbound
> @value
> end
> end
>
> #problem: wsdl2ruby does not pick up soap/property file, so yields a
> certificate error when running against this https url
> #run it on local file
> # To generate deafult.rb, do like this;
> # % wsdl2ruby.rb --wsdl
> "https://adwords.google.com/api/.../CampaignService?WSDL"
> --classdef --force
> #require 'default'
>
> # I don't have an account of AdWords so the following code is not tested.
> # Please tell me (nahi@ruby-lang.org) if you will get good/bad result in
> # communicating with AdWords Server...
> #drv = SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver
>
> require 'defaultDriver.rb'
> require 'yaml'
>
> prefs = YAML::load( File.open('adwords.yaml', 'r'))
> headers = prefs['headers']
>
> drv = CampaignService.new()
>
> #problem: http protocol properties set in soap/property from rubyhome
> are not picked up
> drv.loadproperty('soap/property')
> #problem: wiredump_dev does not output anything when running in SSL mode
> #drv.wiredump_dev = STDOUT
> #the file based logger works
> drv.wiredump_file_base = "log"
>
> headers.each {|key, value| drv.headerhandler << HeaderHandler.new(key, value)}
>
> puts drv.getAllAdWordsCampaigns(GetAllAdWordsCampaigns.new(123))
> ---
>
> /usr/lib/ruby/1.8/soap/mapping/wsdlliteralregistry.rb:73:in
> `soap2obj': cannot map SOAP::SOAPElement to Ruby object
> (SOAP::Mapping::MappingError)
> from /usr/lib/ruby/1.8/soap/mapping/mapping.rb:126:in `_soap2obj'
> from /usr/lib/ruby/1.8/soap/mapping/mapping.rb:49:in `soap2obj'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:417:in `response_doc_lit'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `collect'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `each'
> from /usr/lib/ruby/1.8/soap/baseData.rb:473:in `each'
> from /usr/lib/ruby/1.8/soap/baseData.rb:473:in `each'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `collect'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:416:in `response_doc_lit'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:382:in `response_doc'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:289:in `response_obj'
> from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:129:in `call'
> from /usr/lib/ruby/1.8/soap/rpc/driver.rb:177:in `call'
> from /usr/lib/ruby/1.8/soap/rpc/driver.rb:231:in
> `getAllAdWordsCampaigns'
> from /usr/lib/ruby/1.8/soap/rpc/driver.rb:226:in
> `getAllAdWordsCampaigns'
> from ./client.rb:39
> in soap2obj #<SOAP::SOAPElement:0x36be68
> {https://adwords.google.com/api/...}getAllAdWordsCampaignsResponse>
>
> It is as if the mapping defined in CampaignService is not used.
>
> Thanks in advance for any hints.
>
> P@
>