1 | require 'faraday' |
||
2 | require 'versionone_sdk/update' |
||
3 | require 'versionone_sdk/parser_xml_assets' |
||
4 | |||
5 | module VersiononeSdk |
||
6 | class Client |
||
7 | DEFAULT_PROTOCOL = 'https' |
||
8 | DEFAULT_HOSTNAME = 'localhost' |
||
9 | DEFAULT_PORT = 443 |
||
10 | |||
11 | attr_accessor :oFaraday |
||
12 | attr_accessor :sInstance |
||
13 | attr_accessor :dTypePrefix |
||
14 | |||
15 | def initialize(opts = {}) |
||
16 | @sProtocol = opts[:protocol] || DEFAULT_PROTOCOL |
||
17 | @sHostname = opts[:hostname] || DEFAULT_HOSTNAME |
||
18 | @iPort = opts.key?(:port) && opts[:port] \ |
||
19 | ? opts[:port].to_i : DEFAULT_PORT |
||
20 | sUsername = opts[:username] || '' |
||
21 | sPassword = opts[:password] || '' |
||
22 | # VersionOne provides a mechanism for generating an access token |
||
23 | sAccessToken = opts[:access_token] || '' |
||
24 | @sInstance = opts[:instance] || '' |
||
25 | @dTypePrefix = opts[:type_prefixes] || {'B' => 'Story', 'E' => 'Epic', 'D' => 'Defect'} |
||
26 | @sUrl = buildUrl(@sProtocol, @sHostname, @iPort) |
||
27 | @oFaraday = Faraday::Connection.new url: @sUrl |
||
28 | @oFaraday.ssl.verify = opts[:ssl_verify].to_s.match(/false/i) \ |
||
29 | ? false : true |
||
30 | if sAccessToken.empty? |
||
31 | @oFaraday.basic_auth(sUsername, sPassword) |
||
32 | else |
||
33 | # could also patch Faraday to have a method similar to basic_auth |
||
34 | @oFaraday.headers['Authorization'] = "Bearer #{sAccessToken}" |
||
35 | end |
||
36 | @oUpdate = VersiononeSdk::Update.new self |
||
37 | end |
||
38 | |||
39 | def getAsset(xAssetId1, xAssetId2 = nil) |
||
40 | xAssetId1.strip! |
||
41 | |||
42 | if xAssetId1 =~ /^([^:]+):([0-9]+)$/ |
||
43 | sAssetType = $1 |
||
44 | sAssetOid = $2.to_i |
||
45 | return self.getAssetForTypeAndOid(sAssetType, sAssetOid) |
||
46 | |||
47 | elsif xAssetId1 =~ /^([a-zA-Z])-[0-9]+$/ |
||
48 | sAssetTypeAbbr = $1.upcase |
||
49 | sAssetType = @dTypePrefix.key?(sAssetTypeAbbr) \ |
||
50 | ? @dTypePrefix[ sAssetTypeAbbr ] : '' |
||
51 | xAssetId1.upcase! |
||
52 | return self.getAssetForTypeAndNumber(sAssetType, xAssetId1) |
||
53 | |||
54 | elsif !xAssetId2.nil? |
||
55 | if xAssetId2.is_a?(String) && xAssetId2 =~ /^[0-9]+$/ |
||
56 | xAssetId2 = xAssetId2.to_i |
||
57 | end |
||
58 | |||
59 | if xAssetId2.is_a?(Integer) |
||
60 | |||
61 | if xAssetId1 =~ /^[a-zA-Z]$/ |
||
62 | xAssetId1.upcase! |
||
63 | sAssetTypeAbbr = xAssetId1 |
||
64 | sAssetType = @dTypePrefix.key?(sAssetTypeAbbr) \ |
||
65 | ? @dTypePrefix[ sAssetTypeAbbr ] : '' |
||
66 | sAssetNumber = xAssetId1 + '-' + xAssetId2.to_s |
||
67 | sAssetNumber.upcase! |
||
68 | return self.getAssetForTypeAndNumber(sAssetType, sAssetNumber) |
||
69 | elsif xAssetId1 =~ /^[a-zA-Z].+$/ |
||
70 | return self.getAssetForTypeAndOid(xAssetId1, xAssetId2) |
||
71 | end |
||
72 | end |
||
73 | end |
||
74 | |||
75 | raise RuntimeError, "E_UNKNOWN_ASSET_ID [#{xAssetId1}][#{xAssetId2.to_s}]" |
||
76 | end |
||
77 | View Code Duplication | ||
0 ignored issues
–
show
Duplication
introduced
by
![]() |
|||
78 | def getAssetForTypeAndOid(sAssetType = nil, sAssetOid = nil) |
||
79 | sUrl = self.getUrlForAssets( sAssetType, sAssetOid ) |
||
80 | oRes = @oFaraday.get sUrl |
||
81 | oParser = VersiononeSdk::ParserXmlAssets.new({url: @sUrl}) |
||
82 | return oParser.getDocForAssetXml( oRes.body ) |
||
83 | end |
||
84 | View Code Duplication | ||
0 ignored issues
–
show
|
|||
85 | def getAssetForTypeAndNumber(sAssetType = nil, sAssetNumber = nil) |
||
86 | sUrl = self.getUrlForAssetTypeAndNumber( sAssetType, sAssetNumber ) |
||
87 | oRes = @oFaraday.get sUrl |
||
88 | oParser = VersiononeSdk::ParserXmlAssets.new({url: @sUrl}) |
||
89 | aDocs = oParser.getDocsForAssetsXml( oRes.body ) |
||
90 | return aDocs[0] |
||
91 | end |
||
92 | |||
93 | def getAssets(sAssetType = nil, xIds = nil) |
||
94 | oRes = self.getAssetsXml(sAssetType,xIds) |
||
95 | oParser = VersiononeSdk::ParserXmlAssets.new({url: @sUrl}) |
||
96 | return oParser.getDocsForAssetsXml( oRes.body ) |
||
97 | end |
||
98 | View Code Duplication | ||
0 ignored issues
–
show
|
|||
99 | def getAssetsXml(sAssetType = nil, xIds = nil) |
||
100 | sUrl = self.getUrlForAssets(sAssetType) |
||
101 | return @oFaraday.get sUrl |
||
102 | end |
||
103 | |||
104 | def getUrlForAssetTypeAndNumber(sAssetType = nil, sAssetNumber = nil) |
||
105 | aUrl = [ @sUrl, @sInstance, 'rest-1.v1/Data',sAssetType + %Q!?where=Number="#{sAssetNumber}"!] |
||
106 | return aUrl.join('/') |
||
107 | end |
||
108 | |||
109 | def getUrlForAssets(sAssetType = nil, sAssetOid = nil) |
||
110 | aUrl = [@sUrl, @sInstance, 'rest-1.v1/Data',sAssetType] |
||
111 | if sAssetOid.is_a?(Integer) |
||
112 | aUrl.push sAssetOid |
||
113 | elsif sAssetOid.kind_of?(String) && sAssetOid =~ /^[0-9]+$/ |
||
114 | aUrl.push sAssetOid |
||
115 | end |
||
116 | return aUrl.join('/') |
||
117 | end |
||
118 | |||
119 | def updateAsset(sAssetType=nil,sAssetOid=nil,sName=nil,xxValues=nil,yTagType=nil) |
||
120 | return @oUpdate.updateAsset(sAssetType, sAssetOid, sName, xxValues, yTagType) |
||
121 | end |
||
122 | |||
123 | private |
||
124 | |||
125 | def buildUrl(sProtocol = DEFAULT_PROTOCOL, sHostname = DEFAULT_HOSTNAME, iPort = DEFAULT_PORT) |
||
126 | if sHostname.nil? |
||
127 | sHostname = 'localhost' |
||
128 | View Code Duplication | elsif sHostname.is_a?(String) |
|
0 ignored issues
–
show
|
|||
129 | sHostname.strip! |
||
130 | if sHostname.length < 1 |
||
131 | View Code Duplication | sHostname = 'localhost' |
|
0 ignored issues
–
show
|
|||
132 | end |
||
133 | else |
||
134 | raise ArgumentError, 'E_HOSTNAME_IS_NOT_A_STRING' |
||
135 | end |
||
136 | if iPort.nil? |
||
137 | iPort = 80 |
||
138 | elsif iPort.is_a?(String) && iPort =~ /^[0-9]+$/ |
||
139 | iPort = iPort.to_i |
||
140 | View Code Duplication | elsif ! iPort.kind_of?(Integer) |
|
0 ignored issues
–
show
|
|||
141 | raise ArgumentError, 'E_PORT_IS_NOT_AN_INTEGER' |
||
142 | end |
||
143 | sBaseUrl = "#{sProtocol}://#{sHostname}" |
||
144 | sBaseUrl.sub!(/\/+\s*$/,'') |
||
145 | sBaseUrl += ':' + iPort.to_s if iPort != 80 |
||
146 | return sBaseUrl |
||
147 | end |
||
148 | end |
||
149 | end |
||
150 |