Class: EPIC::Handle
Defined Under Namespace
Constant Summary
Constant Summary
Constants inherited from Resource
Resource::GLOBAL_LOCK_HASH, Resource::GLOBAL_LOCK_MUTEX
Instance Attribute Summary (collapse)
- - (String) handle readonly
-
- (String) handle_encoded
readonly
The URI-encoded handle as it was received by the server.
-
- (String) prefix
readonly
The prefix of this Handle.
-
- (String) suffix
readonly
The suffix of this Handle.
- - (Array<HandleValue>) values readonly
Attributes included from Rackful::Resource
Class Method Summary (collapse)
-
+ (Array<HandleValue>) enforce_admin_record(values, user_name)
Adds an HS_ADMIN value to a set of values if there isn’t yet.
-
+ (Array<HandleValue>) enforce_proper_indexes(values)
Make sure each value has a proper, unique index.
Instance Method Summary (collapse)
- - (void) destroy(request, response)
-
- (void) do_PUT(request, response)
Handles an HTTP/1.1 PUT request.
- - (Boolean) empty?
- - (String) get_etag
- - (Time) get_last_modified
-
- (Handle) initialize(path, handle_values = nil)
constructor
A new instance of Handle.
- - (Array< Hash >) to_rackful
Methods inherited from Resource
Methods included from Rackful::Resource
#default_headers, #do_METHOD, #http_DELETE, #http_GET, #http_HEAD, #http_OPTIONS, #http_PUT, #http_method, #http_methods, included, #requested?, #serializer, #title, #to_struct
Constructor Details
- (Handle) initialize(path, handle_values = nil)
A new instance of Handle
54 55 56 57 58 59 60 61 62 63 |
# File 'src/epic_handle.rb', line 54 def initialize path, handle_values = nil super path raise "Unexpected path: #{path}" \ unless matches = %r{([^/]+)/([^/]+)\z}.match(path) @suffix = matches[2].to_path.unescape @prefix = matches[1].to_path.unescape @handle = @prefix + '/' + @suffix @handle_encoded = matches[0] self.values handle_values if handle_values end |
Instance Attribute Details
- (String) handle (readonly)
47 48 49 |
# File 'src/epic_handle.rb', line 47 def handle @handle end |
- (String) handle_encoded (readonly)
The URI-encoded handle as it was received by the server.
51 52 53 |
# File 'src/epic_handle.rb', line 51 def handle_encoded @handle_encoded end |
- (String) prefix (readonly)
The prefix of this Handle
39 40 41 |
# File 'src/epic_handle.rb', line 39 def prefix @prefix end |
- (String) suffix (readonly)
The suffix of this Handle
43 44 45 |
# File 'src/epic_handle.rb', line 43 def suffix @suffix end |
- (Array<HandleValue>) values (readonly)
70 71 72 73 74 |
# File 'src/epic_handle.rb', line 70 def values dbrows = nil @values ||= ( dbrows || DB.instance.all_handle_values(self.handle) ).collect { |row| HandleValue.new row } end |
Class Method Details
+ (Array<HandleValue>) enforce_admin_record(values, user_name)
I found a Java method GenericHSAdapter#createAdminValue that does exactly what we need! Use that instead! --PvB
Adds an HS_ADMIN value to a set of values if there isn’t yet.
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'src/epic_handle.rb', line 195 def self.enforce_admin_record values, user_name unless values.any? { |v| 'HS_ADMIN' === v.type } idx = 100 idx += 1 while values.any? { |v| idx === v.idx } # In the JAVA code for the standard CNRI adminTool, the following code can # be found in private method +MainWindow::getDefaultAdminRecord()+: # # adminInfo.perms[AdminRecord.DELETE_HANDLE] = true; # adminInfo.perms[AdminRecord.ADD_VALUE] = true; # adminInfo.perms[AdminRecord.REMOVE_VALUE] = true; # adminInfo.perms[AdminRecord.MODIFY_VALUE] = true; # adminInfo.perms[AdminRecord.READ_VALUE] = true; # adminInfo.perms[AdminRecord.ADD_ADMIN] = true; # adminInfo.perms[AdminRecord.REMOVE_ADMIN] = true; # adminInfo.perms[AdminRecord.MODIFY_ADMIN] = true; # adminInfo.perms[AdminRecord.ADD_HANDLE] = true; # adminInfo.perms[AdminRecord.LIST_HANDLES] = false; # adminInfo.perms[AdminRecord.ADD_NAMING_AUTH] = false; # adminInfo.perms[AdminRecord.DELETE_NAMING_AUTH] = false; # return makeValueWithParams(100, Common.STD_TYPE_HSADMIN, # Encoder.encodeAdminRecord(adminInfo)); user_info = EPIC::USERS[user_name] admin_record = HandleValue.new admin_record.idx = idx admin_record.type = 'HS_ADMIN' admin_record.parsed_data = { :adminId => user_info[:handle], :adminIdIndex => user_info[:index], :perms => { :add_handle => true, :delete_handle => true, :add_naming_auth => false, :delete_naming_auth => false, :modify_value => true, :remove_value => true, :add_value => true, :read_value => true, :modify_admin => true, :remove_admin => true, :add_admin => true, :list_handles => false } } values << admin_record end values end |
+ (Array<HandleValue>) enforce_proper_indexes(values)
Make sure each value has a proper, unique index.
Clients may upload a set of handle values without indexes. If that happens, #do_PUT gives these handles the default index. This method makes sure each handle value is properly indexed.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'src/epic_handle.rb', line 168 def self.enforce_proper_indexes values all_indexes = [] values.each do |value| next if HS::EMPTY_HANDLE_VALUE.getIndex == value.idx raise( Rackful::HTTP400BadRequest, "Multiple values with index #{value.idx}" ) \ if all_indexes.member? value.idx all_indexes << value.idx end current_index = 1 values.each do |value| next unless HS::EMPTY_HANDLE_VALUE.getIndex == value.idx current_index = current_index + 1 while all_indexes.member? current_index value.idx = current_index all_indexes << current_index end values end |
Instance Method Details
- (void) destroy(request, response)
154 155 156 157 158 |
# File 'src/epic_handle.rb', line 154 def destroy request, response HS.delete_handle self.handle, request.env['REMOTE_USER'] @values = nil response.status = status_code(:no_content) end |
- (void) do_PUT(request, response)
Handles an HTTP/1.1 PUT request.
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'src/epic_handle.rb', line 82 def do_PUT request, response begin handle_values_in = Rackful::JSON.parse( request.body ) rescue raise Rackful::HTTP400BadRequest, $!.to_s end # begin raise Rackful::HTTP400BadRequest, 'Array expected' \ unless handle_values_in.kind_of? Array new_values = handle_values_in.collect do |handle_value_in| handle_value = HandleValue.new handle_value.idx = handle_value_in[:idx].to_i \ if handle_value_in.key? :idx handle_value.type = handle_value_in[:type].to_s \ if handle_value_in.key? :type handle_value.data = Base64.decode64( handle_value_in[:data].to_s ) \ if handle_value_in.key? :data if handle_value_in.key?( :data ) && handle_value_in.key?( :parsed_data ) data = handle_value.data parsed_data = handle_value.parsed_data handle_value.parsed_data = handle_value_in[:parsed_data] unless data == handle_value.data || parsed_data == handle_value.parsed_data raise Rackful::HTTP400, 'Handle Value contains both <tt>data</tt> and <tt>parsed_data</tt>, and their contents are not semantically equal.' end # unless elsif handle_value_in.key?( :parsed_data ) handle_value.parsed_data = handle_value_in[:parsed_data] end # if handle_value.ttl_type = handle_value_in[:ttl_type].to_i \ if handle_value_in.key? :ttl_type handle_value.ttl = handle_value_in[:ttl].to_i \ if handle_value_in.key? :ttl handle_value.refs = handle_value_in[:refs] \ if handle_value_in[:refs].kind_of?( Array ) && handle_value_in[:refs].all? do |ref| ref.kind_of?( Hash ) && ref[:idx].kind_of?( Integer ) && ref[:handle].kind_of?( String ) end handle_value.admin_read = !!handle_value_in[:admin_read] \ if handle_value_in.key? :admin_read handle_value.admin_write = !!handle_value_in[:admin_write] \ if handle_value_in.key? :admin_write handle_value.pub_read = !!handle_value_in[:pub_read] \ if handle_value_in.key? :pub_read handle_value.pub_write = !!handle_value_in[:pub_write] \ if handle_value_in.key? :pub_write handle_value end # values = handle_values_in.collect do self.class.enforce_proper_indexes new_values self.class.enforce_admin_record new_values, request.env['REMOTE_USER'] self.lock begin @values = nil if self.empty? HS.create_handle(self.handle, new_values, request.env['REMOTE_USER']) @values = nil raise Rackful::HTTP201Created, self.path else HS.update_handle(self.handle, self.values, new_values, request.env['REMOTE_USER']) @values = nil response.status = status_code(:no_content) end ensure self.unlock end end |
- (Boolean) empty?
269 270 271 |
# File 'src/epic_handle.rb', line 269 def empty? self.values.empty? end |
- (String) get_etag
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'src/epic_handle.rb', line 291 def get_etag retval = self.values.sort_by do |value| value.idx end.reduce(Digest::MD5.new) do |digest, value| digest << value.idx.inspect << value.type.inspect << value.data.inspect << value.refs.inspect << value.ttl.inspect << value.ttl_type.inspect << value.admin_read.inspect << value.admin_write.inspect << value.pub_read.inspect << value.pub_write.inspect end.to_s retval = [ retval ].pack('H*') '"' + Base64.strict_encode64(retval)[0..-3] + '"' end |
- (Time) get_last_modified
276 277 278 279 280 281 282 283 284 285 286 |
# File 'src/epic_handle.rb', line 276 def get_last_modified [ Time.at( self.values.reduce(0) do |memo, value| value. > memo ? value. : memo end ), false # to indicate that this is _not_ a strong validator. ] end |
- (Array< Hash >) to_rackful
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'src/epic_handle.rb', line 245 def to_rackful self.values.sort_by { |v| v.idx }.collect { |v| { :idx => v.idx, :type => v.type, :parsed_data => v.parsed_data, :data => v.data, :timestamp => Time.at(v.), :ttl_type => v.ttl_type, :ttl => ( 0 == v.ttl_type ? v.ttl : Time.at( v.ttl ) ), :refs => v.refs.collect { |ref| ref[:idx].to_s + ':' + ref[:handle] }, :privs => ( v.admin_read ? 'r' : '-' ) + ( v.admin_write ? 'w' : '-' ) + ( v.pub_read ? 'r' : '-' ) + ( v.pub_write ? 'w' : '-' ) } } end |