mm_json_client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +4 -0
  6. data/Guardfile +22 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +151 -0
  9. data/Rakefile +33 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +7 -0
  12. data/examples/claim_next_free_ip.rb +73 -0
  13. data/examples/register_dns.rb +37 -0
  14. data/examples/release_ip.rb +59 -0
  15. data/examples/unregister_dns.rb +44 -0
  16. data/fixtures/vcr_cassettes/MmJsonClient_GenericType/basic_server_interaction/allows_a_user_to_log_in_and_out.yml +74 -0
  17. data/fixtures/vcr_cassettes/MmJsonClient_GenericType/basic_server_interaction/filters_a_list_of_users.yml +110 -0
  18. data/fixtures/vcr_cassettes/MmJsonClient_GenericType/basic_server_interaction/gets_a_list_of_users.yml +111 -0
  19. data/fixtures/vcr_cassettes/MmJsonClient_GenericType/basic_server_interaction/gets_a_user_by_reference.yml +110 -0
  20. data/fixtures/vcr_cassettes/MmJsonClient_GenericType/basic_server_interaction/responds_with_a_server_error_on_bad_auth.yml +39 -0
  21. data/fixtures/vcr_cassettes/MmJsonClient_GenericType/multiple_proxy_servers/connects_to_another_proxy_when_one_is_disabled.yml +72 -0
  22. data/fixtures/vcr_cassettes/MmJsonClient_GenericType/proxy_options/allows_a_separate_proxy_to_be_defined.yml +75 -0
  23. data/fixtures/vcr_cassettes/MmJsonClient_GenericType/ssl_options/allows_ignoring_bad_certificates.yml +74 -0
  24. data/generators/enum_def_generator.rb +22 -0
  25. data/generators/method_def_generator.rb +20 -0
  26. data/generators/type_def_generator.rb +50 -0
  27. data/generators/wasabi_extension.rb +45 -0
  28. data/lib/core_ext/hash_extension.rb +43 -0
  29. data/lib/core_ext/string_extension.rb +60 -0
  30. data/lib/core_ext/symbol_extension.rb +24 -0
  31. data/lib/mm_json_client.rb +64 -0
  32. data/lib/mm_json_client/api_definitions/enums.json +1 -0
  33. data/lib/mm_json_client/api_definitions/methods.json +1 -0
  34. data/lib/mm_json_client/api_definitions/types.json +1 -0
  35. data/lib/mm_json_client/client.rb +148 -0
  36. data/lib/mm_json_client/enums/enum_factory.rb +24 -0
  37. data/lib/mm_json_client/enums/generic_enum.rb +12 -0
  38. data/lib/mm_json_client/exceptions.rb +23 -0
  39. data/lib/mm_json_client/generic_type.rb +37 -0
  40. data/lib/mm_json_client/http_client/client.rb +54 -0
  41. data/lib/mm_json_client/json_rpc_http/client.rb +40 -0
  42. data/lib/mm_json_client/json_rpc_http/error.rb +18 -0
  43. data/lib/mm_json_client/json_rpc_http/exceptions.rb +10 -0
  44. data/lib/mm_json_client/json_rpc_http/response.rb +31 -0
  45. data/lib/mm_json_client/response_code.rb +6 -0
  46. data/lib/mm_json_client/type_factory.rb +83 -0
  47. data/lib/mm_json_client/version.rb +3 -0
  48. data/mm_json_client.gemspec +38 -0
  49. metadata +231 -0
@@ -0,0 +1,39 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://test-ipam.local/_mmwebext/mmwebext.dll?Soap
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"jsonrpc":"2.0","method":"Login","params":{"loginName":"testuser","password":"badpadd","server":"test-ipam.local"}}'
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - application/json
14
+ User-Agent:
15
+ - Ruby
16
+ Content-Type:
17
+ - application/json
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Content-Length:
24
+ - '100'
25
+ Content-Type:
26
+ - application/json; charset=utf-8
27
+ Server:
28
+ - Microsoft-IIS/8.5
29
+ X-Powered-By:
30
+ - ASP.NET
31
+ Date:
32
+ - Mon, 11 Jul 2016 17:56:42 GMT
33
+ body:
34
+ encoding: UTF-8
35
+ string: '{"jsonrpc": "2.0", "error": {"code": 16394, "message": "Invalid username
36
+ or password."}, "id": null}'
37
+ http_version:
38
+ recorded_at: Mon, 11 Jul 2016 17:56:45 GMT
39
+ recorded_with: VCR 3.0.3
@@ -0,0 +1,72 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://test-ipam02.local/_mmwebext/mmwebext.dll?Soap
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"jsonrpc":"2.0","method":"Login","params":{"loginName":"testuser","password":"testpass","server":"localhost"}}'
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - application/json
14
+ User-Agent:
15
+ - Ruby
16
+ Content-Type:
17
+ - application/json
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Content-Length:
24
+ - '209'
25
+ Content-Type:
26
+ - application/json; charset=utf-8
27
+ Server:
28
+ - Microsoft-IIS/8.5
29
+ Date:
30
+ - Wed, 13 Jul 2016 18:28:45 GMT
31
+ body:
32
+ encoding: UTF-8
33
+ string: '{"jsonrpc": "2.0", "error": {"code": 1037, "message": "Incoming requests
34
+ have been disabled on this server. Please select a server that is in a mode
35
+ that accepts incoming requests and try again."}, "id": null}'
36
+ http_version:
37
+ recorded_at: Wed, 13 Jul 2016 18:28:28 GMT
38
+ - request:
39
+ method: post
40
+ uri: http://test-ipam01.local/_mmwebext/mmwebext.dll?Soap
41
+ body:
42
+ encoding: UTF-8
43
+ string: '{"jsonrpc":"2.0","method":"Login","params":{"loginName":"testuser","password":"testpass","server":"localhost"}}'
44
+ headers:
45
+ Accept-Encoding:
46
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
47
+ Accept:
48
+ - application/json
49
+ User-Agent:
50
+ - Ruby
51
+ Content-Type:
52
+ - application/json
53
+ response:
54
+ status:
55
+ code: 200
56
+ message: OK
57
+ headers:
58
+ Content-Length:
59
+ - '76'
60
+ Content-Type:
61
+ - application/json; charset=utf-8
62
+ Server:
63
+ - Microsoft-IIS/8.5
64
+ Date:
65
+ - Wed, 13 Jul 2016 18:28:50 GMT
66
+ body:
67
+ encoding: UTF-8
68
+ string: '{"jsonrpc": "2.0", "result": {"session":"RV7qXnC0fbZBNrgjIhQh"}, "id":
69
+ null}'
70
+ http_version:
71
+ recorded_at: Wed, 13 Jul 2016 18:28:34 GMT
72
+ recorded_with: VCR 3.0.3
@@ -0,0 +1,75 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://test-ipam.local/_mmwebext/mmwebext.dll?Soap
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"jsonrpc":"2.0","method":"Login","params":{"loginName":"testuser","password":"testpass","server":"localhost"}}'
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - application/json
14
+ User-Agent:
15
+ - Ruby
16
+ Content-Type:
17
+ - application/json
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Content-Length:
24
+ - '76'
25
+ Content-Type:
26
+ - application/json; charset=utf-8
27
+ Server:
28
+ - Microsoft-IIS/8.5
29
+ X-Powered-By:
30
+ - ASP.NET
31
+ Date:
32
+ - Mon, 11 Jul 2016 17:57:38 GMT
33
+ body:
34
+ encoding: UTF-8
35
+ string: '{"jsonrpc": "2.0", "result": {"session":"4bnH7Tn73YMX5DgiP6oU"}, "id":
36
+ null}'
37
+ http_version:
38
+ recorded_at: Mon, 11 Jul 2016 17:57:41 GMT
39
+ - request:
40
+ method: post
41
+ uri: http://test-ipam.local/_mmwebext/mmwebext.dll?Soap
42
+ body:
43
+ encoding: UTF-8
44
+ string: '{"jsonrpc":"2.0","method":"Login","params":{"loginName":"testuser","password":"testpass","server":"localhost"}}'
45
+ headers:
46
+ Accept-Encoding:
47
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
48
+ Accept:
49
+ - application/json
50
+ User-Agent:
51
+ - Ruby
52
+ Content-Type:
53
+ - application/json
54
+ response:
55
+ status:
56
+ code: 200
57
+ message: OK
58
+ headers:
59
+ Content-Length:
60
+ - '76'
61
+ Content-Type:
62
+ - application/json; charset=utf-8
63
+ Server:
64
+ - Microsoft-IIS/8.5
65
+ X-Powered-By:
66
+ - ASP.NET
67
+ Date:
68
+ - Wed, 13 Jul 2016 13:05:19 GMT
69
+ body:
70
+ encoding: UTF-8
71
+ string: '{"jsonrpc": "2.0", "result": {"session":"kTq5p3frEk8eb3mAjHMC"}, "id":
72
+ null}'
73
+ http_version:
74
+ recorded_at: Wed, 13 Jul 2016 13:05:27 GMT
75
+ recorded_with: VCR 3.0.3
@@ -0,0 +1,74 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://test-ipam.local/_mmwebext/mmwebext.dll?Soap
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"jsonrpc":"2.0","method":"Login","params":{"loginName":"testuser","password":"testpass","server":"test-ipam.local"}}'
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - application/json
14
+ User-Agent:
15
+ - Ruby
16
+ Content-Type:
17
+ - application/json
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Content-Length:
24
+ - '76'
25
+ Content-Type:
26
+ - application/json; charset=utf-8
27
+ Server:
28
+ - Microsoft-IIS/8.5
29
+ X-Powered-By:
30
+ - ASP.NET
31
+ Date:
32
+ - Mon, 11 Jul 2016 18:03:12 GMT
33
+ body:
34
+ encoding: UTF-8
35
+ string: '{"jsonrpc": "2.0", "result": {"session":"brtghA7dQ0D6jBRqQS8h"}, "id":
36
+ null}'
37
+ http_version:
38
+ recorded_at: Mon, 11 Jul 2016 18:03:14 GMT
39
+ - request:
40
+ method: post
41
+ uri: https://test-ipam.local/_mmwebext/mmwebext.dll?Soap
42
+ body:
43
+ encoding: UTF-8
44
+ string: '{"jsonrpc":"2.0","method":"Logout","params":{"session":"brtghA7dQ0D6jBRqQS8h"}}'
45
+ headers:
46
+ Accept-Encoding:
47
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
48
+ Accept:
49
+ - application/json
50
+ User-Agent:
51
+ - Ruby
52
+ Content-Type:
53
+ - application/json
54
+ response:
55
+ status:
56
+ code: 200
57
+ message: OK
58
+ headers:
59
+ Content-Length:
60
+ - '44'
61
+ Content-Type:
62
+ - application/json; charset=utf-8
63
+ Server:
64
+ - Microsoft-IIS/8.5
65
+ X-Powered-By:
66
+ - ASP.NET
67
+ Date:
68
+ - Mon, 11 Jul 2016 18:03:17 GMT
69
+ body:
70
+ encoding: UTF-8
71
+ string: '{"jsonrpc": "2.0", "result": "", "id": null}'
72
+ http_version:
73
+ recorded_at: Mon, 11 Jul 2016 18:03:20 GMT
74
+ recorded_with: VCR 3.0.3
@@ -0,0 +1,22 @@
1
+ require 'erb'
2
+ require 'json'
3
+ require 'wasabi'
4
+ require_relative 'wasabi_extension'
5
+
6
+ module MmJsonClient
7
+ module Generators
8
+ # Read in a WSDL and output an API definition file for enumerations.
9
+ class EnumDefGenerator
10
+ def generate(in_file, out_file)
11
+ enumerations = {}
12
+ doc = Wasabi.document(File.read(in_file))
13
+ doc.parser.parse_enumerations
14
+ doc.parser.enumerations.each do |enumeration, data|
15
+ enumerations[enumeration] = data['values']
16
+ end
17
+
18
+ File.write(out_file, enumerations.to_json)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ require 'erb'
2
+ require 'json'
3
+ require 'wasabi'
4
+
5
+ module MmJsonClient
6
+ module Generators
7
+ # Read in a WSDL and output an API definition file for methods.
8
+ class MethodDefGenerator
9
+ def generate(in_file, out_file)
10
+ methods = {}
11
+ doc = Wasabi.document(File.read(in_file))
12
+ doc.operations.each do |_method, definition|
13
+ methods[definition[:input]] = definition[:output]
14
+ end
15
+
16
+ File.write(out_file, methods.to_json)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,50 @@
1
+ require 'erb'
2
+ require 'json'
3
+ require 'wasabi'
4
+
5
+ module MmJsonClient
6
+ module Generators
7
+ # Read in a WSDL and output an API definition file for complex types.
8
+ class TypeDefGenerator
9
+ def generate(in_file, out_file)
10
+ types = {}
11
+ doc = Wasabi.document(File.read(in_file))
12
+ doc.parser.types.each do |type, data|
13
+ types[type] = {}
14
+ if array_type?(type, data)
15
+ ns_type = array_type(data)
16
+ types[type] = [type_from_ns_type(ns_type)]
17
+ else
18
+ type_fields(data).each do |element, definition|
19
+ types[type][element] = type_from_ns_type(definition[:type])
20
+ end
21
+ end
22
+ end
23
+
24
+ File.write(out_file, types.to_json)
25
+ end
26
+
27
+ private
28
+
29
+ def array_type(data)
30
+ type_fields(data).first[1][:type]
31
+ end
32
+
33
+ def type_fields(data)
34
+ data.select { |x| x.class == String }
35
+ end
36
+
37
+ def type_from_ns_type(ns_type)
38
+ ns_type.split(':').last
39
+ end
40
+
41
+ # I would prefer not to do this quite as hackily, but there are
42
+ # other elements in the WSDL that look like have maxOccurs = unbounded,
43
+ # but are not actually array parameters.
44
+ def array_type?(type, _data)
45
+ return true if type =~ /^ArrayOf/
46
+ false
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,45 @@
1
+ module Wasabi
2
+ # Extend the parser to find M&M API enumerations.
3
+ class Parser
4
+ attr_accessor :enumerations
5
+
6
+ def parse_enumerations
7
+ @enumerations = {}
8
+ schemas.each do |schema|
9
+ schema_namespace = schema['targetNamespace']
10
+
11
+ schema.element_children.each do |node|
12
+ namespace = schema_namespace || @namespace
13
+
14
+ case node.name
15
+ when 'element'
16
+ simple_type = node.at_xpath('./xs:simpleType', 'xs' => XSD)
17
+ if simple_type && enumeration?(simple_type)
18
+ process_enumeration namespace, complex_type, node['name'].to_s
19
+ end
20
+ when 'simpleType'
21
+ if enumeration?(node)
22
+ process_enumeration namespace, node, node['name'].to_s
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def process_enumeration(namespace, enum, name)
30
+ @enumerations[name] = { namespace: namespace }
31
+ @enumerations[name]['values'] = []
32
+ enum.xpath('./xs:restriction/xs:enumeration', 'xs' => XSD).each do |value|
33
+ @enumerations[name]['values'] << value['value']
34
+ end
35
+ end
36
+
37
+ def enumeration?(node)
38
+ if node.at_xpath('./xs:restriction/xs:enumeration', 'xs' => XSD)
39
+ true
40
+ else
41
+ false
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,43 @@
1
+ require 'core_ext/string_extension.rb'
2
+
3
+ # Extend hash with helpers specificic to this gem.
4
+ class Hash
5
+ # Convert the keys of hashes and arrays of hashes using mm_underscore
6
+ def mm_underscore_keys
7
+ keys_to_mm_underscore(self)
8
+ end
9
+
10
+ # Convert the keys of hashes and arrays of hashes using mm_camelize
11
+ def mm_camelize_keys
12
+ keys_to_mm_camel(self)
13
+ end
14
+
15
+ def mm_values_to_h
16
+ mm_values_to_hashes(self)
17
+ end
18
+
19
+ private
20
+
21
+ # Convert the keys of hashes and arrays of hashes to mm_underscore
22
+ def keys_to_mm_underscore(value)
23
+ case value
24
+ when Array
25
+ value.map { |v| keys_to_mm_underscore(v) }
26
+ when Hash
27
+ Hash[value.map { |k, v| [k.mm_underscore, keys_to_mm_underscore(v)] }]
28
+ else
29
+ value
30
+ end
31
+ end
32
+
33
+ def keys_to_mm_camel(value)
34
+ case value
35
+ when Array
36
+ value.map { |v| keys_to_mm_camel(v) }
37
+ when Hash
38
+ Hash[value.map { |k, v| [k.mm_camelize, keys_to_mm_camel(v)] }]
39
+ else
40
+ value
41
+ end
42
+ end
43
+ end