Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting wsdl_domain as Savon endpoint. #445

Closed

Conversation

mauricioarellano
Copy link

Netsuite made a change for some accounts causing Soap errors like:

In this account, you must use account-specific domains with this SOAP web services endpoint. You can use the SOAP getDataCenterUrls operation to obtain the correct domain. Or, go to Setup > Company > Company Information in the NetSuite UI. Your domains are listed on the Company URLs tab.

For that reason was needed to fork the Netsuite gem in order to set the custom endpoint configured as wsdl_domain property in Netsuite.configure block.

@mawaldne
Copy link

mawaldne commented Feb 28, 2020

Hi @mauricioarellano

We're running into the same issue, but unfortunately this fix didn't help.

I tried setting the wsdl_domain value in the netsuite config to our account specific domain. But I get this error:

DEBUG -- : HTTPI /peer GET request to ########.suitetalk.api.netsuite.com (net_http)
Error Invalid URL: ########.suitetalk.api.netsuite.com

Im still trying to debug and see what the issue might be.

@mawaldne
Copy link

I ended up having to do this to fix my problem:

#439

@mauricioarellano
Copy link
Author

Hi @mawaldne, I see that you weren't setting the protocol in the wsdl_domain nor Savon client's endpoint. Your approach is good, will try it on my integration.

Thanks for sharing your solution.

@mawaldne
Copy link

mawaldne commented Feb 28, 2020

@mauricioarellano No problem!

Instead of forking the netsuite project, I ended up doing what @q3aiml suggested in #439. I put the following at the end of my config/initializers/netsuite.rb file:

NetSuite.configure do
.... my existing netsuite configs ...
  api_version      '2017_2'
  # account specific domain
  wsdl_domain   "########.suitetalk.api.netsuite.com"
end

module NetSuite
  module Configuration
    extend self

    alias :old_connection :connection
  
    def connection(params={}, credentials={})
      client = old_connection(params, credentials)
      client.wsdl.endpoint = client.wsdl.endpoint.to_s.sub('//webservices.na0.netsuite.com/', "//#{wsdl_domain}/")
      client
    end
  end
end

We're using the api_version '2017_2', so in my case the wsdl file thats being return from netsuite contains webservices.na0.netsuite.com in the urls. So I had to replace that with my account specific url. Other api versions return webservices.netsuite.com I think.

I'm not sure if this is something netsuite needs to fix on their end as well? If we're requesting the wsdl file from them, why doesn't it contains that account specific domains? I've opened up a help ticket with netsuite about it.

@mauricioarellano
Copy link
Author

I had a call with Netsuite support this week and they shared a postman collection with a request hitting an account-based URL. They told me that I need to hit that URL from my account.

I tried to monkey patch my code but didn't take my changes, so I had to fork the gem to see if works in that way and it did.

@mawaldne
Copy link

mawaldne commented Mar 4, 2020

Just leaving another note here for anyone else that is having this issue. Netsuite seemed to have changed the wsdls AGAIN today. The 2017_2 api version now has a new url. It use to be webservices.na0.netsuite.com
but now it's webservices.netsuite.com. Below is my final fix. I just added it into my config/initializers/netsuite.rb:

NetSuite.configure do
.... my existing netsuite configs ...
  api_version      '2017_2'
  # account specific domain
  wsdl_domain   "########.suitetalk.api.netsuite.com"
end

module NetSuite
  module Configuration
    extend self

    alias :old_connection :connection
  
    def connection(params={}, credentials={})
      client = old_connection(params, credentials)
      client.wsdl.endpoint = client.wsdl.endpoint.to_s.sub('//webservices.na0.netsuite.com/', "//#{wsdl_domain}/")
      client.wsdl.endpoint = client.wsdl.endpoint.to_s.sub('//webservices.netsuite.com/', "//#{wsdl_domain}/")
      client
    end
  end
end

@iloveitaly
Copy link
Member

Hey All! I'm hoping to take a look at this, and other related PRs, soon. In the meantime I'd recommend setting the WSDL dynamically so NS updates don't break your integration:

def netsuite_data_center_urls(account_id)

In the meantime, while this isn't built into the gem, I'd recommend doing something like this:

data_center_urls = NetSuite::Utilities.netsuite_data_center_urls(netsuite_account)
wsdl_domain = data_center_urls[:system_domain]

ns_api_version = '2018_2'
NetSuite::Configuration.wsdl = "#{wsdl_domain}/wsdl/v#{ns_api_version}_0/netsuite.wsdl"

@blained
Copy link

blained commented Mar 8, 2020

@iloveitaly Do you have a rough timeline of when you will look at this and take a change? We would rather see the change here than have to fork the gem. We need this soon.

@mauricioarellano

@iloveitaly
Copy link
Member

@blained I don't! Like most open source projects, this is a volunteer effort, so I can't commit to any specific timelines.

@sonxurxo
Copy link

sonxurxo commented Jul 8, 2020

We had to modify @iloveitaly 's solution a bit, to use webservices_domain instead of system_domain. Like this:

data_center_urls = NetSuite::Utilities.netsuite_data_center_urls(netsuite_account)
wsdl_domain = data_center_urls[:webservices_domain]

ns_api_version = '2018_2'
NetSuite::Configuration.wsdl = "#{wsdl_domain}/wsdl/v#{ns_api_version}_0/netsuite.wsdl"

@darrend
Copy link

darrend commented Feb 16, 2021

To get going with 2020_2 (2020.2, are these twice a year like clockwork? do we need to keep up with them?) I had to refine the hacks above a bit. The urls mentioned in the wsdl returned by Netsuite changed again from webservices.na0.netsuite.com to webservices.netsuite.com so I tweaked the code in #445 (comment) to use a more generic regex replacement. In addition, Savon doesn't expose (or no longer in the version included by this gem) wsdl so I had to crack it open and expose the attribute; this fixes the undefined method wsdl'` error.

Below is for a totally made up 0000000_SB1 sandbox account. Replace it with your real account of course.

NetSuite.configure do
  reset!
  api_version      '2020_2'
  account          "0000000_SB1" 
  consumer_key     "xxxxx"
  consumer_secret  "xxxxx"
  token_id         "xxxxx"
  token_secret     "xxxxx"
  # pull the following from `NetSuite::Utilities.data_center_url('0000000_SB1')` every time? once year? never? always?
  wsdl_domain     "0000000-sb1.suitetalk.api.netsuite.com"
end

module NetSuite
  module Configuration
    extend self

    alias :old_connection :connection

    def connection(params={}, credentials={})
      client = old_connection(params, credentials)
      wsdl = client.wsdl_netsuite_endpoint_hack
      # from "https://webservices.netsuite.com/services/NetSuitePort_2020_2" to "https://#{wsdl_domain}/services/NetSuitePort_2020_2"
      wsdl.endpoint = wsdl.endpoint.to_s.gsub(%r[//[^/]*/], "//#{wsdl_domain}/") #
      client
    end
  end
end

# above hack fails with undefined method `wsdl' for #<Savon::Client:0x00007fa07cb5c2e0> otherwise
module Savon
  class Client
    def wsdl_netsuite_endpoint_hack
      return self.wsdl if self.respond_to?(:wsdl)
      @wsdl
    end
  end
end

@iloveitaly
Copy link
Member

This is fixed with #473 and the readme docs have been updated. Going to close this out.

@iloveitaly iloveitaly closed this Jul 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants