soap4r mapping problem when using google adwords api

Discussion in 'Ruby' started by Patrick Chanezon, Jun 23, 2005.

  1. The Google Adwords sample that Nahi included in the samples at
    http://dev.ctor.org/soap4r/file/trunk/sample/wsdl/googleAdwords/client.rb
    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 =3D 'https://adwords.google.com/api/adwords/v2/CampaignService?WSDL'
    wsdl =3D 'CampaignService.wsdl'

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

    #the initial handler from the sample was wrong, it generated 2 level of tag=
    s
    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/adwords/v2/CampaignService?WSDL"
    --classdef --force
    require 'default'

    # I don't have an account of AdWords so the following code is not tested.
    # Please tell me () if you will get good/bad result in
    # communicating with AdWords Server...
    drv =3D 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 =3D STDOUT
    #the file based logger works
    drv.wiredump_file_base =3D "log"
    drv.headerhandler << HeaderHandler.new('email', '')
    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 =3D 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/adwords/v2}getAllAdWordsCampaignsResponse>

    the trace in soap2obj is a print node.inspect

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

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

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

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

    attr_accessor :id

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

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

    attr_accessor :getCampaignReturn

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

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

    attr_accessor :ids

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

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

    attr_accessor :getCampaignListReturn

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

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

    attr_accessor :dummy

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

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

    attr_accessor :getAllAdWordsCampaignsReturn

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

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

    attr_accessor :campaign

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

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

    attr_accessor :addCampaignReturn

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

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

    attr_accessor :campaigns

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

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

    attr_accessor :addCampaignListReturn

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

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

    attr_accessor :campaign

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

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

    def initialize
    end
    end

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

    attr_accessor :campaigns

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

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

    def initialize
    end
    end

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

    attr_accessor :campaignId

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

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

    attr_accessor :getOptimizeAdServingReturn

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

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

    attr_accessor :campaignId
    attr_accessor :enable

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

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

    def initialize
    end
    end

    # {https://adwords.google.com/api/adwords/v2}getCampaignStats
    class GetCampaignStats
    @@schema_type =3D "getCampaignStats"
    @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    @@schema_element =3D [["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=3D(value)
    @v_end =3D value
    end

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

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

    attr_accessor :getCampaignStatsReturn

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

    # {https://adwords.google.com/api/adwords/v2}Keyword
    class Keyword
    @@schema_type =3D "Keyword"
    @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    @@schema_element =3D [["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 =3D nil, maxCpc =3D nil, adGroupId =3D nil, language =
    =3D
    nil, status =3D nil, negative =3D nil, destinationUrl =3D nil, text =3D nil=
    ,
    id =3D nil, exemptionRequest =3D nil)
    @type =3D type
    @maxCpc =3D maxCpc
    @adGroupId =3D adGroupId
    @language =3D language
    @status =3D status
    @negative =3D negative
    @destinationUrl =3D destinationUrl
    @text =3D text
    @id =3D id
    @exemptionRequest =3D exemptionRequest
    end
    end

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

    # {https://adwords.google.com/api/adwords/v2}GeoTarget
    class GeoTarget
    @@schema_type =3D "GeoTarget"
    @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    @@schema_element =3D [["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 =3D [], regions =3D [], metros =3D [], cities =
    =3D [])
    @countries =3D countries
    @regions =3D regions
    @metros =3D metros
    @cities =3D cities
    end
    end

    # {https://adwords.google.com/api/adwords/v2}Campaign
    class Campaign
    @@schema_type =3D "Campaign"
    @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    @@schema_element =3D [["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 :eek:ptInSearchNetwork
    attr_accessor :eek:ptInContentNetwork
    attr_accessor :campaignNegativeKeywords
    attr_accessor :languageTargeting
    attr_accessor :geoTargeting

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

    # {https://adwords.google.com/api/adwords/v2}ApiException
    class ApiException
    @@schema_type =3D "ApiException"
    @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    @@schema_element =3D [["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 =3D nil, internal =3D nil, message =3D nil, trigger =
    =3D
    nil, violations =3D nil)
    @code =3D code
    @internal =3D internal
    @message =3D message
    @trigger =3D trigger
    @violations =3D violations
    end
    end

    # {https://adwords.google.com/api/adwords/v2}StatsRecord
    class StatsRecord
    @@schema_type =3D "StatsRecord"
    @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    @@schema_element =3D [["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 =3D nil, clicks =3D nil, conversionRate =
    =3D
    nil, conversions =3D nil, cost =3D nil, id =3D nil, impressions =3D nil)
    @averagePosition =3D averagePosition
    @clicks =3D clicks
    @conversionRate =3D conversionRate
    @conversions =3D conversions
    @cost =3D cost
    @id =3D id
    @impressions =3D impressions
    end
    end

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

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

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

    The error happens in soap/mapping/wsdlliteralregistry.rb

    # node should be a SOAPElement
    def soap2obj(node, obj_class =3D 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/adwords/v2}getAllAdWordsCampaignsResponse>

    # {https://adwords.google.com/api/adwords/v2}getAllAdWordsCampaignsResponse
    class GetAllAdWordsCampaignsResponse
    @@schema_type =3D "getAllAdWordsCampaignsResponse"
    @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    @@schema_element =3D [["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 =3D 'https://adwords.google.com/api/adwords/v2/CampaignService?WSDL'

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

    #the initial handler from the sample was wrong, it generated 2 level of tag=
    s
    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/adwords/v2/CampaignService?WSDL"
    --classdef --force
    #require 'default'

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

    require 'defaultDriver.rb'
    require 'yaml'

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

    drv =3D 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 =3D STDOUT
    #the file based logger works
    drv.wiredump_file_base =3D "log"

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

    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/adwords/v2}getAllAdWordsCampaignsResponse>

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

    Thanks in advance for any hints.

    P@
     
    Patrick Chanezon, Jun 23, 2005
    #1
    1. Advertising

  2. adding some debug in proxy.rb
    def response_doc_lit(body, mapping_registry)
    puts "in proxy mapping =3D #{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 t=
    ypes
    in proxy mapping =3D #<SOAP::Mapping::WSDLLiteralRegistry:0x6eea34
    @excn_handler_obj2soap=3Dnil,
    @schema_element_cache=3D{GetAllAdWordsCampaigns=3D>[{"dummy"=3D>"SOAP::SOAP=
    Int"},
    []]}, @schema_attribute_cache=3D{GetAllAdWordsCampaigns=3D>nil},
    @definedtypes=3D#<XSD::NamedElements:0x2a56fc
    @cache=3D{#<XSD::QName:0x3706ca {}dummy>=3D>nil, #<XSD::QName:0x3766b0
    {https://adwords.google.com/api/adwords/v2}getAllAdWordsCampaigns>=3D>nil},
    @elements=3D[]>, @definedelements=3D#<XSD::NamedElements:0x2a56fc
    @cache=3D{#<XSD::QName:0x3706ca {}dummy>=3D>nil, #<XSD::QName:0x3766b0
    {https://adwords.google.com/api/adwords/v2}getAllAdWordsCampaigns>=3D>nil},
    @elements=3D[]>, @excn_handler_soap2obj=3Dnil>

    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 =3D=3D 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 <> wrote:
    > The Google Adwords sample that Nahi included in the samples at
    > http://dev.ctor.org/soap4r/file/trunk/sample/wsdl/googleAdwords/client.rb
    > does not work.
    >=20
    > 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
    >=20
    > require 'soap/wsdlDriver'
    > require 'soap/header/simplehandler'
    >=20
    > #wsdl =3D 'https://adwords.google.com/api/adwords/v2/CampaignService?WSDL=

    '
    > wsdl =3D 'CampaignService.wsdl'
    >=20
    > class HeaderHandler < SOAP::Header::SimpleHandler
    > def initialize(tag, value)
    > super(XSD::QName.new(nil, tag))
    > @tag =3D tag
    > @value =3D value
    > end
    >=20
    > #the initial handler from the sample was wrong, it generated 2 level of t=

    ags
    > def on_simple_outbound
    > @value
    > end
    > end
    >=20
    > #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/adwords/v2/CampaignService?WSDL"
    > --classdef --force
    > require 'default'
    >=20
    > # I don't have an account of AdWords so the following code is not tested.
    > # Please tell me () if you will get good/bad result in
    > # communicating with AdWords Server...
    > drv =3D 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 =3D STDOUT
    > #the file based logger works
    > drv.wiredump_file_base =3D "log"
    > drv.headerhandler << HeaderHandler.new('email', '')
    > 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 =3D drv.call("getAllAdWordsCampaigns", GetAllAdWordsCampaigns.ne=

    w(123))
    > print camplist
    > ---
    >=20
    > 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.
    >=20
    > 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.
    >=20
    > 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/adwords/v2}getAllAdWordsCampaignsResponse=
    >
    >=20
    > the trace in soap2obj is a print node.inspect
    >=20
    > here is the response log
    > <soapenv:Envelope
    > xmlns:soapenv=3D"http://schemas.xmlsoap.org/soap/envelope/"
    > xmlns:xsd=3D"http://www.w3.org/2001/XMLSchema"
    > xmlns:xsi=3D"http://www.w3.org/2001/XMLSchema-instance"><soapenv:Header><=

    responseTime
    > soapenv:actor=3D"http://schemas.xmlsoap.org/soap/actor/next"
    > soapenv:mustUnderstand=3D"0"
    > xmlns=3D"https://adwords.google.com/api/adwords/v2">23</responseTime><ope=

    rations
    > soapenv:actor=3D"http://schemas.xmlsoap.org/soap/actor/next"
    > soapenv:mustUnderstand=3D"0"
    > xmlns=3D"https://adwords.google.com/api/adwords/v2">3</operations></soape=

    nv:Header>
    > <soapenv:Body>
    > <getAllAdWordsCampaignsResponse
    > xmlns=3D"https://adwords.google.com/api/adwords/v2">
    > <getAllAdWordsCampaignsReturn><id>6000213</id><name>Campaign
    > #1</name><status>Active</status><startDate>2005-04-16T21:27:50.000Z</star=

    tDate><endDate>2011-01-01T07:59:59.000Z</endDate><dailyBudget>1000000</dail=
    yBudget><optInSearchNetwork>true</optInSearchNetwork><optInContentNetwork>t=
    rue</optInContentNetwork><languageTargeting><languages>en</languages></lang=
    uageTargeting><geoTargeting
    > xsi:nil=3D"true"/></getAllAdWordsCampaignsReturn>
    > ...
    > </getAllAdWordsCampaignsResponse></soapenv:Body></soapenv:Envelope>
    >=20
    > It seems to barf on <getAllAdWordsCampaignsResponse
    > xmlns=3D"https://adwords.google.com/api/adwords/v2">
    >=20
    > Here is the rb file generated by wsdl2ruby
    > require 'xsd/qname'
    >=20
    > # {https://adwords.google.com/api/adwords/v2}getCampaign
    > class GetCampaign
    > @@schema_type =3D "getCampaign"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["id", "SOAP::SOAPInt"]]
    >=20
    > attr_accessor :id
    >=20
    > def initialize(id =3D nil)
    > @id =3D id
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}getCampaignResponse
    > class GetCampaignResponse
    > @@schema_type =3D "getCampaignResponse"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["getCampaignReturn", "Campaign"]]
    >=20
    > attr_accessor :getCampaignReturn
    >=20
    > def initialize(getCampaignReturn =3D nil)
    > @getCampaignReturn =3D getCampaignReturn
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}getCampaignList
    > class GetCampaignList
    > @@schema_type =3D "getCampaignList"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["ids", "SOAP::SOAPInt[]"]]
    >=20
    > attr_accessor :ids
    >=20
    > def initialize(ids =3D [])
    > @ids =3D ids
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}getCampaignListResponse
    > class GetCampaignListResponse
    > @@schema_type =3D "getCampaignListResponse"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["getCampaignListReturn", "Campaign[]"]]
    >=20
    > attr_accessor :getCampaignListReturn
    >=20
    > def initialize(getCampaignListReturn =3D [])
    > @getCampaignListReturn =3D getCampaignListReturn
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}getAllAdWordsCampaigns
    > class GetAllAdWordsCampaigns
    > @@schema_type =3D "getAllAdWordsCampaigns"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["dummy", "SOAP::SOAPInt"]]
    >=20
    > attr_accessor :dummy
    >=20
    > def initialize(dummy =3D nil)
    > @dummy =3D dummy
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}getAllAdWordsCampaignsRespon=

    se
    > class GetAllAdWordsCampaignsResponse
    > @@schema_type =3D "getAllAdWordsCampaignsResponse"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["getAllAdWordsCampaignsReturn", "Campaign[]"]]
    >=20
    > attr_accessor :getAllAdWordsCampaignsReturn
    >=20
    > def initialize(getAllAdWordsCampaignsReturn =3D [])
    > @getAllAdWordsCampaignsReturn =3D getAllAdWordsCampaignsReturn
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}addCampaign
    > class AddCampaign
    > @@schema_type =3D "addCampaign"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["campaign", "Campaign"]]
    >=20
    > attr_accessor :campaign
    >=20
    > def initialize(campaign =3D nil)
    > @campaign =3D campaign
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}addCampaignResponse
    > class AddCampaignResponse
    > @@schema_type =3D "addCampaignResponse"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["addCampaignReturn", "Campaign"]]
    >=20
    > attr_accessor :addCampaignReturn
    >=20
    > def initialize(addCampaignReturn =3D nil)
    > @addCampaignReturn =3D addCampaignReturn
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}addCampaignList
    > class AddCampaignList
    > @@schema_type =3D "addCampaignList"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["campaigns", "Campaign[]"]]
    >=20
    > attr_accessor :campaigns
    >=20
    > def initialize(campaigns =3D [])
    > @campaigns =3D campaigns
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}addCampaignListResponse
    > class AddCampaignListResponse
    > @@schema_type =3D "addCampaignListResponse"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["addCampaignListReturn", "Campaign[]"]]
    >=20
    > attr_accessor :addCampaignListReturn
    >=20
    > def initialize(addCampaignListReturn =3D [])
    > @addCampaignListReturn =3D addCampaignListReturn
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}updateCampaign
    > class UpdateCampaign
    > @@schema_type =3D "updateCampaign"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["campaign", "Campaign"]]
    >=20
    > attr_accessor :campaign
    >=20
    > def initialize(campaign =3D nil)
    > @campaign =3D campaign
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}updateCampaignResponse
    > class UpdateCampaignResponse
    > @@schema_type =3D "updateCampaignResponse"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D []
    >=20
    > def initialize
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}updateCampaignList
    > class UpdateCampaignList
    > @@schema_type =3D "updateCampaignList"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["campaigns", "Campaign[]"]]
    >=20
    > attr_accessor :campaigns
    >=20
    > def initialize(campaigns =3D [])
    > @campaigns =3D campaigns
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}updateCampaignListResponse
    > class UpdateCampaignListResponse
    > @@schema_type =3D "updateCampaignListResponse"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D []
    >=20
    > def initialize
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}getOptimizeAdServing
    > class GetOptimizeAdServing
    > @@schema_type =3D "getOptimizeAdServing"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["campaignId", "SOAP::SOAPInt"]]
    >=20
    > attr_accessor :campaignId
    >=20
    > def initialize(campaignId =3D nil)
    > @campaignId =3D campaignId
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}getOptimizeAdServingResponse
    > class GetOptimizeAdServingResponse
    > @@schema_type =3D "getOptimizeAdServingResponse"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["getOptimizeAdServingReturn", "SOAP::SOAPBoolean=

    "]]
    >=20
    > attr_accessor :getOptimizeAdServingReturn
    >=20
    > def initialize(getOptimizeAdServingReturn =3D nil)
    > @getOptimizeAdServingReturn =3D getOptimizeAdServingReturn
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}setOptimizeAdServing
    > class SetOptimizeAdServing
    > @@schema_type =3D "setOptimizeAdServing"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["campaignId", "SOAP::SOAPInt"], ["enable",
    > "SOAP::SOAPBoolean"]]
    >=20
    > attr_accessor :campaignId
    > attr_accessor :enable
    >=20
    > def initialize(campaignId =3D nil, enable =3D nil)
    > @campaignId =3D campaignId
    > @enable =3D enable
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}setOptimizeAdServingResponse
    > class SetOptimizeAdServingResponse
    > @@schema_type =3D "setOptimizeAdServingResponse"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D []
    >=20
    > def initialize
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}getCampaignStats
    > class GetCampaignStats
    > @@schema_type =3D "getCampaignStats"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["campaignIds", "SOAP::SOAPInt[]"], ["start",
    > "SOAP::SOAPDateTime"], ["v_end", ["SOAP::SOAPDateTime",
    > XSD::QName.new(nil, "end")]]]
    >=20
    > attr_accessor :campaignIds
    > attr_accessor :start
    >=20
    > def end
    > @v_end
    > end
    >=20
    > def end=3D(value)
    > @v_end =3D value
    > end
    >=20
    > def initialize(campaignIds =3D [], start =3D nil, v_end =3D nil)
    > @campaignIds =3D campaignIds
    > @start =3D start
    > @v_end =3D v_end
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}getCampaignStatsResponse
    > class GetCampaignStatsResponse
    > @@schema_type =3D "getCampaignStatsResponse"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["getCampaignStatsReturn", "StatsRecord[]"]]
    >=20
    > attr_accessor :getCampaignStatsReturn
    >=20
    > def initialize(getCampaignStatsReturn =3D [])
    > @getCampaignStatsReturn =3D getCampaignStatsReturn
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}Keyword
    > class Keyword
    > @@schema_type =3D "Keyword"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["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"]]
    >=20
    > 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
    >=20
    > def initialize(type =3D nil, maxCpc =3D nil, adGroupId =3D nil, languag=

    e =3D
    > nil, status =3D nil, negative =3D nil, destinationUrl =3D nil, text =3D n=

    il,
    > id =3D nil, exemptionRequest =3D nil)
    > @type =3D type
    > @maxCpc =3D maxCpc
    > @adGroupId =3D adGroupId
    > @language =3D language
    > @status =3D status
    > @negative =3D negative
    > @destinationUrl =3D destinationUrl
    > @text =3D text
    > @id =3D id
    > @exemptionRequest =3D exemptionRequest
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}LanguageTarget
    > class LanguageTarget < ::Array
    > @@schema_type =3D "string"
    > @@schema_ns =3D "http://www.w3.org/2001/XMLSchema"
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}GeoTarget
    > class GeoTarget
    > @@schema_type =3D "GeoTarget"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["countries", "SOAP::SOAPString[]"], ["regions",
    > "SOAP::SOAPString[]"], ["metros", "SOAP::SOAPString[]"], ["cities",
    > "SOAP::SOAPString[]"]]
    >=20
    > attr_accessor :countries
    > attr_accessor :regions
    > attr_accessor :metros
    > attr_accessor :cities
    >=20
    > def initialize(countries =3D [], regions =3D [], metros =3D [], cities =

    =3D [])
    > @countries =3D countries
    > @regions =3D regions
    > @metros =3D metros
    > @cities =3D cities
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}Campaign
    > class Campaign
    > @@schema_type =3D "Campaign"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["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"]]
    >=20
    > attr_accessor :id
    > attr_accessor :name
    > attr_accessor :status
    > attr_accessor :startDate
    > attr_accessor :endDate
    > attr_accessor :dailyBudget
    > attr_accessor :eek:ptInSearchNetwork
    > attr_accessor :eek:ptInContentNetwork
    > attr_accessor :campaignNegativeKeywords
    > attr_accessor :languageTargeting
    > attr_accessor :geoTargeting
    >=20
    > def initialize(id =3D nil, name =3D nil, status =3D nil, startDate =3D =

    nil,
    > endDate =3D nil, dailyBudget =3D nil, optInSearchNetwork =3D nil,
    > optInContentNetwork =3D nil, campaignNegativeKeywords =3D [],
    > languageTargeting =3D nil, geoTargeting =3D nil)
    > @id =3D id
    > @name =3D name
    > @status =3D status
    > @startDate =3D startDate
    > @endDate =3D endDate
    > @dailyBudget =3D dailyBudget
    > @optInSearchNetwork =3D optInSearchNetwork
    > @optInContentNetwork =3D optInContentNetwork
    > @campaignNegativeKeywords =3D campaignNegativeKeywords
    > @languageTargeting =3D languageTargeting
    > @geoTargeting =3D geoTargeting
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}ApiException
    > class ApiException
    > @@schema_type =3D "ApiException"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["code", "SOAP::SOAPInt"], ["internal",
    > "SOAP::SOAPBoolean"], ["message", "SOAP::SOAPString"], ["trigger",
    > "SOAP::SOAPString"], ["violations", "SOAP::SOAPString"]]
    >=20
    > attr_accessor :code
    > attr_accessor :internal
    > attr_accessor :message
    > attr_accessor :trigger
    > attr_accessor :violations
    >=20
    > def initialize(code =3D nil, internal =3D nil, message =3D nil, trigger=

    =3D
    > nil, violations =3D nil)
    > @code =3D code
    > @internal =3D internal
    > @message =3D message
    > @trigger =3D trigger
    > @violations =3D violations
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}StatsRecord
    > class StatsRecord
    > @@schema_type =3D "StatsRecord"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["averagePosition", "SOAP::SOAPDouble"],
    > ["clicks", "SOAP::SOAPLong"], ["conversionRate", "SOAP::SOAPDouble"],
    > ["conversions", "SOAP::SOAPLong"], ["cost", "SOAP::SOAPLong"], ["id",
    > "SOAP::SOAPLong"], ["impressions", "SOAP::SOAPLong"]]
    >=20
    > attr_accessor :averagePosition
    > attr_accessor :clicks
    > attr_accessor :conversionRate
    > attr_accessor :conversions
    > attr_accessor :cost
    > attr_accessor :id
    > attr_accessor :impressions
    >=20
    > def initialize(averagePosition =3D nil, clicks =3D nil, conversionRate =

    =3D
    > nil, conversions =3D nil, cost =3D nil, id =3D nil, impressions =3D nil)
    > @averagePosition =3D averagePosition
    > @clicks =3D clicks
    > @conversionRate =3D conversionRate
    > @conversions =3D conversions
    > @cost =3D cost
    > @id =3D id
    > @impressions =3D impressions
    > end
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}KeywordStatus
    > module KeywordStatus
    > Deleted =3D "Deleted"
    > Disabled =3D "Disabled"
    > Disapproved =3D "Disapproved"
    > InTrial =3D "InTrial"
    > Normal =3D "Normal"
    > OnHold =3D "OnHold"
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}KeywordType
    > module KeywordType
    > Broad =3D "Broad"
    > Exact =3D "Exact"
    > Phrase =3D "Phrase"
    > end
    >=20
    > # {https://adwords.google.com/api/adwords/v2}CampaignStatus
    > module CampaignStatus
    > Active =3D "Active"
    > Deleted =3D "Deleted"
    > Ended =3D "Ended"
    > Paused =3D "Paused"
    > Pending =3D "Pending"
    > Suspended =3D "Suspended"
    > end
    >=20
    > The error happens in soap/mapping/wsdlliteralregistry.rb
    >=20
    > # node should be a SOAPElement
    > def soap2obj(node, obj_class =3D 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
    >=20
    > 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/adwords/v2}getAllAdWordsCampaignsResponse=
    >
    >=20
    > # {https://adwords.google.com/api/adwords/v2}getAllAdWordsCampaignsRespon=

    se
    > class GetAllAdWordsCampaignsResponse
    > @@schema_type =3D "getAllAdWordsCampaignsResponse"
    > @@schema_ns =3D "https://adwords.google.com/api/adwords/v2"
    > @@schema_element =3D [["getAllAdWordsCampaignsReturn", "Campaign[]"]]
    >=20
    > 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?
    >=20
    > 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
    >=20
    > Now I understand where the mapping is defined.
    > Still the new program yields the same error
    >=20
    > ---
    > #!/usr/local/bin/ruby
    >=20
    > require 'soap/wsdlDriver'
    > require 'soap/header/simplehandler'
    >=20
    > wsdl =3D 'https://adwords.google.com/api/adwords/v2/CampaignService?WSDL'
    >=20
    > class HeaderHandler < SOAP::Header::SimpleHandler
    > def initialize(tag, value)
    > super(XSD::QName.new(nil, tag))
    > @tag =3D tag
    > @value =3D value
    > end
    >=20
    > #the initial handler from the sample was wrong, it generated 2 level of t=

    ags
    > def on_simple_outbound
    > @value
    > end
    > end
    >=20
    > #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/adwords/v2/CampaignService?WSDL"
    > --classdef --force
    > #require 'default'
    >=20
    > # I don't have an account of AdWords so the following code is not tested.
    > # Please tell me () if you will get good/bad result in
    > # communicating with AdWords Server...
    > #drv =3D SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver
    >=20
    > require 'defaultDriver.rb'
    > require 'yaml'
    >=20
    > prefs =3D YAML::load( File.open('adwords.yaml', 'r'))
    > headers =3D prefs['headers']
    >=20
    > drv =3D CampaignService.new()
    >=20
    > #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 =3D STDOUT
    > #the file based logger works
    > drv.wiredump_file_base =3D "log"
    >=20
    > headers.each {|key, value| drv.headerhandler << HeaderHandler.new(key, va=

    lue)}
    >=20
    > puts drv.getAllAdWordsCampaigns(GetAllAdWordsCampaigns.new(123))
    > ---
    >=20
    > /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/adwords/v2}getAllAdWordsCampaignsResponse=
    >
    >=20
    > It is as if the mapping defined in CampaignService is not used.
    >=20
    > Thanks in advance for any hints.
    >=20
    > P@
    >
     
    Patrick Chanezon, Jun 23, 2005
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    4
    Views:
    538
  2. SirLook

    SirLook Google AdWords Miracle

    SirLook, Oct 20, 2006, in forum: HTML
    Replies:
    0
    Views:
    391
    SirLook
    Oct 20, 2006
  3. tapaas
    Replies:
    0
    Views:
    296
    tapaas
    Oct 24, 2010
  4. tapaas
    Replies:
    0
    Views:
    233
    tapaas
    Oct 24, 2010
  5. Chris Roos
    Replies:
    0
    Views:
    105
    Chris Roos
    Sep 13, 2006
Loading...

Share This Page