Module: NSConnector::Restlet

Defined in:
lib/ns_connector/restlet.rb

Overview

Connects to the RESTlet configured in NetSuite to make generic requests. Example usage: NSConnector::Restlet.execute!( :action => ‘retrieve’, :type_id => type_id, :data => => Integer(id) )

> parsed json results

Constant Summary collapse

RuntimeError =
Class.new(Exception)
ArgumentError =
Class.new(Exception)

Class Method Summary collapse

Class Method Details

.auth_headerObject

Generate a NetSuite specific Authorization header.

From the NetSuite documentation:

NLAuth passes in the following login credentials: nlauth_account:: NetSuite company ID (required) nlauth_email:: NetSuite user name (required) nclauth_signature:: NetSuite password (required)

nlauth_role

internal ID of the role used to log in to

NetSuite (optional) The Authorization header should be formatted as: NLAuth<space><comma-separated parameters>

For example: Authorization: NLAuth nlauth_account=123456, \ [email protected], nlauth_signature=xxxxxxxx, \ nlauth_role=41

Returns

String with the contents of the header



119
120
121
122
123
124
125
126
127
# File 'lib/ns_connector/restlet.rb', line 119

def self.auth_header
	c = NSConnector::Config
	c.check_valid!

	"NLAuth nlauth_account=#{c[:account_id]},"     \
	"nlauth_email=#{c[:email]},"                   \
	"nlauth_role=#{c[:role]},"                     \
	"nlauth_signature=#{URI.escape(c[:password])}"
end

.execute!(options) ⇒ Object

Build a HTTP request to connect to NetSuite RESTlets, then request our magic restlet that can do everything useful.

Returns

The parsed JSON response, i.e. JSON.parse(response.body)



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/ns_connector/restlet.rb', line 23

def self.execute! options
	NSConnector::Config.check_valid!

	# Build our request up, a bit ugly
	uri = URI(NSConnector::Config[:restlet_url])

	unless uri.scheme then
		raise NSConnector::Restlet::ArgumentError,
			'Configuration value restlet_url must at '\
			'least contain a scheme (i.e. http://)'
	end

	http = Net::HTTP.new(uri.host, uri.port)

	if NSConnector::Config[:debug] then
		http.set_debug_output $stderr 
	end

	http.use_ssl = (uri.scheme == 'https')

	request = Net::HTTP::Post.new("#{uri.path}?#{uri.query}")

	request['Content-Type'] = 'application/json'
	request['Authorization'] = NSConnector::Restlet.auth_header
	request['User-Agent'] = NSConnector::Config[:user_agent] if NSConnector::Config[:user_agent]

	begin
		options[:code] = restlet_code
		request.body = JSON.dump(options)
	rescue JSON::GeneratorError => current
		exception = NSConnector::Restlet::ArgumentError.new(
			"Failed to convert options (#{options}) " \
			"into JSON: #{current.message}"
		)

		exception.set_backtrace(current.backtrace)
		raise exception
	end

	response = http.request(request)

	# Netsuite seems to use HTTP 400 (bad requests) for all runtime
	# errors.  Hah.
	if response.kind_of? Net::HTTPBadRequest then
		# So let's try and raise this exception as something
		# nicer.
		NSConnector::Errors.try_handle_response!(response)
	end

	unless response.kind_of? Net::HTTPSuccess then
		raise NSConnector::Restlet::RuntimeError.new(
			'Restlet execution failed, expected a '\
			'HTTP 2xx response, got a HTTP '\
			"#{response.code}: #{response.body}" 
		)
	end

	if response.body.nil? then
		raise NSConnector::Restlet::RuntimeError.new(
			"Recieved a blank response from RESTlet"
		)
	end

	begin
		return JSON.parse(response.body)
	rescue JSON::ParserError => current
		exception = NSConnector::Restlet::RuntimeError.new(
			'Failed to parse response ' \
			'from Restlet as JSON '\
			"(#{response.body}): " \
			"#{current.message}"
		)
		exception.set_backtrace(current.backtrace)
		raise exception
	end
end

.restlet_codeObject

Retrieve restlet code from support/restlet.js

Returns

String



131
132
133
134
135
136
137
# File 'lib/ns_connector/restlet.rb', line 131

def self.restlet_code
	restlet_location = File.join(
		File.dirname(__FILE__),
		'..', '..', 'support', 'restlet.js'
	)
	File.read(restlet_location)
end