mm_json_client 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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