| 
									
										
										
										
											2015-10-22 12:39:22 +03:00
										 |  |  | #require "providers/provider_factory" | 
					
						
							| 
									
										
										
										
											2015-07-16 17:18:55 +03:00
										 |  |  | require "exceptions/invalid_record" | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | require "json" | 
					
						
							| 
									
										
										
										
											2015-07-20 18:59:26 +03:00
										 |  |  | require 'db/validators/all' | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  | module Devops | 
					
						
							|  |  |  |   module Model | 
					
						
							|  |  |  |     class MongoModel | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-26 12:04:01 +03:00
										 |  |  |       attr_accessor :created_at | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       # multi_json sends argument to 'to_json' method | 
					
						
							|  |  |  |       def to_json arg=nil | 
					
						
							|  |  |  |         JSON.pretty_generate self.to_hash | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       def to_hash | 
					
						
							|  |  |  |         h = to_hash_without_id | 
					
						
							|  |  |  |         h["id"] = self.id | 
					
						
							|  |  |  |         h | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       def to_mongo_hash | 
					
						
							|  |  |  |         h = to_hash_without_id | 
					
						
							|  |  |  |         h["_id"] = self.id | 
					
						
							|  |  |  |         h | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       def is_empty? val | 
					
						
							|  |  |  |         val.nil? or val.strip.empty? | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       def check_string! val | 
					
						
							|  |  |  |         raise ArgumentError unless val.is_a?(String) | 
					
						
							|  |  |  |         val.strip! | 
					
						
							|  |  |  |         raise ArgumentError if val.empty? | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       def check_array! val, type, empty=false | 
					
						
							|  |  |  |         raise ArgumentError unless val.is_a?(Array) | 
					
						
							|  |  |  |         raise ArgumentError if !empty and val.empty? | 
					
						
							|  |  |  |         val.each do |v| | 
					
						
							|  |  |  |           raise ArgumentError unless v.is_a?(type) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       def check_name_value val | 
					
						
							|  |  |  |         raise ArgumentError.new "Invalid name, it should contains 0-9, a-z, A-Z, _, - symbols only" if val.match(/^[0-9a-zA-Z_\-]+$/).nil? | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       def check_provider provider=self.provider | 
					
						
							|  |  |  |         unless ::Provider::ProviderFactory.providers.include?(provider) | 
					
						
							|  |  |  |           raise InvalidRecord.new "Invalid provider '#{provider}'" | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       def validate! | 
					
						
							|  |  |  |         begin | 
					
						
							| 
									
										
										
										
											2015-08-13 15:49:37 +03:00
										 |  |  |           # TODO: we should validate type in request parser | 
					
						
							| 
									
										
										
										
											2015-10-06 13:50:26 +03:00
										 |  |  | #          self.validate_fields_types | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |           self.class.validate_model(self) | 
					
						
							| 
									
										
										
										
											2015-11-03 11:46:54 +03:00
										 |  |  |           validate_fields! | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |           true | 
					
						
							|  |  |  |         rescue InvalidRecord => e | 
					
						
							|  |  |  |           error_message = self.build_error_message(e.message) | 
					
						
							|  |  |  |           raise InvalidRecord.new(error_message) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2015-02-12 13:01:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 17:33:25 +03:00
										 |  |  |       def validate_fields! | 
					
						
							|  |  |  |         result = [] | 
					
						
							| 
									
										
										
										
											2015-11-19 14:09:38 +03:00
										 |  |  |         orders = self.class.field_validators.keys.sort | 
					
						
							|  |  |  |         orders.each do |order| | 
					
						
							|  |  |  |           self.class.field_validators[order].each do |elem| | 
					
						
							|  |  |  |             field = elem[:field] | 
					
						
							|  |  |  |             validation_method = elem[:method] | 
					
						
							|  |  |  |             begin | 
					
						
							|  |  |  |               self.send(validation_method) | 
					
						
							|  |  |  |             rescue InvalidRecord => e | 
					
						
							|  |  |  |               result << {key: field, message: e.message} | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |           unless result.empty? | 
					
						
							|  |  |  |             raise InvalidRecord.new(error_data: result) | 
					
						
							| 
									
										
										
										
											2015-11-02 17:33:25 +03:00
										 |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         true | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-03 11:46:54 +03:00
										 |  |  |       def valid? | 
					
						
							|  |  |  |         validate! | 
					
						
							|  |  |  |         true | 
					
						
							|  |  |  |       rescue InvalidRecord | 
					
						
							|  |  |  |         false | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       def build_error_message(message) | 
					
						
							|  |  |  |         # overrided in descendants | 
					
						
							|  |  |  |         message | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2015-02-12 13:01:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       # types - Hash | 
					
						
							|  |  |  |       #   key - param name | 
					
						
							|  |  |  |       #   value - Hash | 
					
						
							|  |  |  |       #     :type - param type | 
					
						
							|  |  |  |       #     :empty - can param be empty? (false) | 
					
						
							|  |  |  |       #     :nil - can param be nil? (false) | 
					
						
							|  |  |  |       #     :value_type - type of array element (String) | 
					
						
							| 
									
										
										
										
											2015-10-26 12:04:01 +03:00
										 |  |  |       # TODO: @deprecated | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       def self.types types | 
					
						
							|  |  |  |         define_method :validate_fields_types do | 
					
						
							|  |  |  |           t = types.keys | 
					
						
							|  |  |  |           e = types.keys | 
					
						
							|  |  |  |           n = types.keys | 
					
						
							|  |  |  |           types.each do |name, value| | 
					
						
							|  |  |  |             if value[:nil] | 
					
						
							|  |  |  |               n.delete(name) | 
					
						
							|  |  |  |               if self.send(name).nil? | 
					
						
							|  |  |  |                 e.delete(name) | 
					
						
							|  |  |  |                 t.delete(name) | 
					
						
							|  |  |  |                 next | 
					
						
							|  |  |  |               end | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |               n.delete(name) unless self.send(name).nil? | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |             if self.send(name).is_a? value[:type] | 
					
						
							|  |  |  |               t.delete(name) | 
					
						
							|  |  |  |               self.send(name).strip! if value[:type] == String | 
					
						
							|  |  |  |               if value[:type] == Array | 
					
						
							|  |  |  |                 unless value[:value_type] == false | 
					
						
							|  |  |  |                   type = value[:value_type] || String | 
					
						
							|  |  |  |                   self.send(name).each do |e| | 
					
						
							|  |  |  |                     unless e.is_a?(type) | 
					
						
							|  |  |  |                       t.push(name) | 
					
						
							|  |  |  |                       break | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                   end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  |                 end | 
					
						
							|  |  |  |               end | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |               e.delete(name) if value[:empty] or !self.send(name).empty? | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |           raise InvalidRecord.new "Parameter(s) '#{n.join("', '")}' can not be undefined" unless n.empty? | 
					
						
							|  |  |  |           raise InvalidRecord.new "Parameter(s) '#{t.join("', '")}' have invalid type(s)" unless t.empty? | 
					
						
							|  |  |  |           raise InvalidRecord.new "Parameter(s) '#{e.join("', '")}' can not be empty" unless e.empty? | 
					
						
							|  |  |  |           if types.has_key? :provider | 
					
						
							|  |  |  |             self.send("check_provider") | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |           true | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-13 15:49:37 +03:00
										 |  |  |       @validators = [] | 
					
						
							| 
									
										
										
										
											2015-11-02 17:33:25 +03:00
										 |  |  |       @field_validators = {} | 
					
						
							| 
									
										
										
										
											2015-08-13 15:49:37 +03:00
										 |  |  |       class << self | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-13 15:49:37 +03:00
										 |  |  |         attr_accessor :validators | 
					
						
							| 
									
										
										
										
											2015-11-19 14:09:38 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # hash: | 
					
						
							|  |  |  |         #   key - (integer) validators order | 
					
						
							|  |  |  |         #   value - (hash) validator params: | 
					
						
							|  |  |  |         #     field: (string) field name | 
					
						
							|  |  |  |         #     method: (string) field validator method | 
					
						
							| 
									
										
										
										
											2015-11-02 17:33:25 +03:00
										 |  |  |         attr_accessor :field_validators | 
					
						
							| 
									
										
										
										
											2015-08-13 15:49:37 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def inherited(subclass) | 
					
						
							|  |  |  |           subclass.validators = [] | 
					
						
							|  |  |  |           subclass.validators += self.validators | 
					
						
							| 
									
										
										
										
											2015-11-02 17:33:25 +03:00
										 |  |  |           subclass.field_validators = self.field_validators.clone | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2015-02-12 13:01:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-13 15:49:37 +03:00
										 |  |  |         # all exceptions are handled in @validate! method | 
					
						
							|  |  |  |         def validate_model(model) | 
					
						
							|  |  |  |           validators.each do |validator| | 
					
						
							|  |  |  |             validator.new(model).validate! | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2015-02-12 13:01:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-03 11:46:54 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-06 13:50:26 +03:00
										 |  |  |         # validate field value | 
					
						
							|  |  |  |         # if method validate! returns false, then stop validation without error | 
					
						
							| 
									
										
										
										
											2015-11-19 14:09:38 +03:00
										 |  |  |         # | 
					
						
							|  |  |  |         # field - (string) field name to validate | 
					
						
							|  |  |  |         # validators - (array) validators list | 
					
						
							|  |  |  |         # options - (hash) options for validator | 
					
						
							|  |  |  |         #   order: integer - run validator in order with index order: | 
					
						
							|  |  |  |         def set_field_validators field, validators, options={} | 
					
						
							|  |  |  |           attr_accessor field | 
					
						
							| 
									
										
										
										
											2015-11-02 17:33:25 +03:00
										 |  |  |           method_name = "validate_" + field.to_s + "!" | 
					
						
							|  |  |  |           define_method(method_name) do | 
					
						
							| 
									
										
										
										
											2015-10-06 13:50:26 +03:00
										 |  |  |             validators.each do |validator| | 
					
						
							| 
									
										
										
										
											2015-11-19 14:09:38 +03:00
										 |  |  |               break unless validator.new(self, field).validate! | 
					
						
							| 
									
										
										
										
											2015-10-06 13:50:26 +03:00
										 |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2015-11-19 14:09:38 +03:00
										 |  |  |           order = options[:order] || 0
 | 
					
						
							|  |  |  |           obj = { | 
					
						
							|  |  |  |             field: field, | 
					
						
							|  |  |  |             method: method_name | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           unless self.field_validators[order] | 
					
						
							|  |  |  |             self.field_validators[order] = [obj] | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             self.field_validators[order] << obj | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2015-10-06 13:50:26 +03:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-13 15:49:37 +03:00
										 |  |  |         # private class methods | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |         private | 
					
						
							| 
									
										
										
										
											2015-02-12 13:01:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |         def set_validators(*validators_to_add) | 
					
						
							| 
									
										
										
										
											2015-08-13 15:49:37 +03:00
										 |  |  |           self.validators += validators_to_add | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2015-02-12 13:01:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |         def unset_validators(*validators_to_remove) | 
					
						
							|  |  |  |           self.validators -= validators_to_remove | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2015-02-12 13:01:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2015-02-12 13:01:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  |   end | 
					
						
							|  |  |  | end |