Module: Maestrano::Connector::Rails::Concerns::Entity

Extended by:
ActiveSupport::Concern
Included in:
Entity
Defined in:
app/models/maestrano/connector/rails/concerns/entity.rb

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

@@external_name =
Maestrano::Connector::Rails::External.external_name

Instance Method Summary collapse

Instance Method Details

#connec_entity_nameObject

Entity name in Connec!



239
240
241
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 239

def connec_entity_name
  raise "Not implemented"
end

#consolidate_and_map_data(connec_entities, external_entities, organization, opts = {}) ⇒ Object


General methods

  • Discards entities that do not need to be pushed because they have not been updated since their last push

  • Discards entities from one of the two source in case of conflict

  • Maps not discarded entities and associates them with their idmap, or create one if there isn’t any



186
187
188
189
190
191
192
193
194
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
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 186

def consolidate_and_map_data(connec_entities, external_entities, organization, opts={})
  external_entities.map!{|entity|
    idmap = Maestrano::Connector::Rails::IdMap.find_by(external_id: self.get_id_from_external_entity_hash(entity), external_entity: self.external_entity_name.downcase, organization_id: organization.id)

    # No idmap: creating one, nothing else to do
    unless idmap
      next {entity: self.map_to_connec(entity, organization), idmap: Maestrano::Connector::Rails::IdMap.create(external_id: self.get_id_from_external_entity_hash(entity), external_entity: self.external_entity_name.downcase, organization_id: organization.id)}
    end

    # Not pushing entity to Connec!
    next nil unless idmap.to_connec

    # Entity has not been modified since its last push to connec!
    if idmap.last_push_to_connec && idmap.last_push_to_connec > self.get_last_update_date_from_external_entity_hash(entity)
      Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Discard #{@@external_name} #{self.external_entity_name} : #{entity}")
      next nil
    end

    # Check for conflict with entities from connec!
    if idmap.connec_id && connec_entity = connec_entities.detect{|connec_entity| connec_entity['id'] == idmap.connec_id}
      # We keep the most recently updated entity
      if !opts[:connec_preemption].nil?
        keep_external = !opts[:connec_preemption]
      else
        keep_external = connec_entity['updated_at'] < self.get_last_update_date_from_external_entity_hash(entity)
      end

      if keep_external
        Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Conflict between #{@@external_name} #{self.external_entity_name} #{entity} and Connec! #{self.connec_entity_name} #{connec_entity}. Entity from #{@@external_name} kept")
        connec_entities.delete(connec_entity)
        {entity: self.map_to_connec(entity, organization), idmap: idmap}
      else
        Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Conflict between #{@@external_name} #{self.external_entity_name} #{entity} and Connec! #{self.connec_entity_name} #{connec_entity}. Entity from Connec! kept")
        nil
      end

    else
      {entity: self.map_to_connec(entity, organization), idmap: idmap}
    end
  }.compact!

  connec_entities.map!{|entity|
    self.map_to_external_with_idmap(entity, organization)
  }.compact!
end

#create_connec_entity(connec_client, mapped_external_entity, connec_entity_name, organization) ⇒ Object



100
101
102
103
104
105
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 100

def create_connec_entity(connec_client, mapped_external_entity, connec_entity_name, organization)
  Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Sending create #{connec_entity_name}: #{mapped_external_entity} to Connec!")
  response = connec_client.post("/#{connec_entity_name.downcase.pluralize}", { "#{connec_entity_name.downcase.pluralize}".to_sym => mapped_external_entity })
  raise "No response received from Connec! when trying to create a #{self.connec_entity_name}" unless response
  JSON.parse(response.body)["#{connec_entity_name.downcase.pluralize}"]
end

#create_external_entity(client, mapped_connec_entity, external_entity_name, organization) ⇒ Object



162
163
164
165
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 162

def create_external_entity(client, mapped_connec_entity, external_entity_name, organization)
  Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Sending create #{external_entity_name}: #{mapped_connec_entity} to #{@@external_name}")
  raise "Not implemented"
end

#external_entity_nameObject

Entity name in external system



244
245
246
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 244

def external_entity_name
  raise "Not implemented"
end

#get_connec_entities(client, last_synchronization, organization, opts = {}) ⇒ Object


Connec! methods



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 31

def get_connec_entities(client, last_synchronization, organization, opts={})
  Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Fetching Connec! #{self.connec_entity_name}")

  entities = []

  # Fetch first page
  if last_synchronization.blank? || opts[:full_sync]
    Maestrano::Connector::Rails::ConnectorLogger.log('debug', organization, "entity=#{self.connec_entity_name}, fetching all data")
    response = client.get("/#{self.connec_entity_name.downcase.pluralize}")
  else
    Maestrano::Connector::Rails::ConnectorLogger.log('debug', organization, "entity=#{self.connec_entity_name}, fetching data since #{last_synchronization.updated_at.iso8601}")
    query_param = URI.encode("$filter=updated_at gt '#{last_synchronization.updated_at.iso8601}'")
    response = client.get("/#{self.connec_entity_name.downcase.pluralize}?#{query_param}")
  end
  raise "No data received from Connec! when trying to fetch #{self.connec_entity_name.pluralize}" unless response

  response_hash = JSON.parse(response.body)
  Maestrano::Connector::Rails::ConnectorLogger.log('debug', organization, "received first page entity=#{self.connec_entity_name}, response=#{response.body}")
  if response_hash["#{self.connec_entity_name.downcase.pluralize}"]
    entities << response_hash["#{self.connec_entity_name.downcase.pluralize}"]
  else
    raise "Received unrecognized Connec! data when trying to fetch #{self.connec_entity_name.pluralize}"
  end

  # Fetch subsequent pages
  while response_hash['pagination'] && response_hash['pagination']['next']
    # ugly way to convert https://api-connec/api/v2/group_id/organizations?next_page_params to /organizations?next_page_params
    next_page = response_hash['pagination']['next'].gsub(/^(.*)\/#{self.connec_entity_name.downcase.pluralize}/, self.connec_entity_name.downcase.pluralize)
    response = client.get(next_page)

    raise "No data received from Connec! when trying to fetch subsequent page of #{self.connec_entity_name.pluralize}" unless response
    Maestrano::Connector::Rails::ConnectorLogger.log('debug', organization, "received next page entity=#{self.connec_entity_name}, response=#{response.body}")

    response_hash = JSON.parse(response.body)
    if response_hash["#{self.connec_entity_name.downcase.pluralize}"]
      entities << response_hash["#{self.connec_entity_name.downcase.pluralize}"]
    else
      raise "Received unrecognized Connec! data when trying to fetch subsequent page of #{self.connec_entity_name.pluralize}"
    end
  end

  entities = entities.flatten
  Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Received data: Source=Connec!, Entity=#{self.connec_entity_name}, Data=#{entities}")
  entities
end

#get_external_entities(client, last_synchronization, organization, opts = {}) ⇒ Object


External methods



128
129
130
131
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 128

def get_external_entities(client, last_synchronization, organization, opts={})
  Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Fetching #{@@external_name} #{self.external_entity_name.pluralize}")
  raise "Not implemented"
end

#get_id_from_external_entity_hash(entity) ⇒ Object



172
173
174
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 172

def get_id_from_external_entity_hash(entity)
  raise "Not implemented"
end

#get_last_update_date_from_external_entity_hash(entity) ⇒ Object



176
177
178
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 176

def get_last_update_date_from_external_entity_hash(entity)
  raise "Not implemented"
end

#map_to_connec(entity, organization) ⇒ Object

Map an external entity to Connec! format



24
25
26
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 24

def map_to_connec(entity, organization)
  self.mapper_class.denormalize(entity)
end

#map_to_external(entity, organization) ⇒ Object


Mapper methods

Map a Connec! entity to the external format



19
20
21
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 19

def map_to_external(entity, organization)
  self.mapper_class.normalize(entity)
end

#map_to_external_with_idmap(entity, organization) ⇒ Object



114
115
116
117
118
119
120
121
122
123
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 114

def map_to_external_with_idmap(entity, organization)
  idmap = Maestrano::Connector::Rails::IdMap.find_by(connec_id: entity['id'], connec_entity: self.connec_entity_name.downcase, organization_id: organization.id)

  if idmap && ((!idmap.to_external) || (idmap.last_push_to_external && idmap.last_push_to_external > entity['updated_at']))
    Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Discard Connec! #{self.connec_entity_name} : #{entity}")
    nil
  else
    {entity: self.map_to_external(entity, organization), idmap: idmap || Maestrano::Connector::Rails::IdMap.create(connec_id: entity['id'], connec_entity: self.connec_entity_name.downcase, organization_id: organization.id)}
  end
end

#mapper_classObject

Entity Mapper Class



249
250
251
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 249

def mapper_class
  raise "Not implemented"
end

#push_entities_to_connec(connec_client, mapped_external_entities_with_idmaps, organization) ⇒ Object



77
78
79
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 77

def push_entities_to_connec(connec_client, mapped_external_entities_with_idmaps, organization)
  self.push_entities_to_connec_to(connec_client, mapped_external_entities_with_idmaps, self.connec_entity_name, organization)
end

#push_entities_to_connec_to(connec_client, mapped_external_entities_with_idmaps, connec_entity_name, organization) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 81

def push_entities_to_connec_to(connec_client, mapped_external_entities_with_idmaps, connec_entity_name, organization)
  Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Sending #{@@external_name} #{self.external_entity_name.pluralize} to Connec! #{connec_entity_name.pluralize}")
  mapped_external_entities_with_idmaps.each do |mapped_external_entity_with_idmap|
    external_entity = mapped_external_entity_with_idmap[:entity]
    idmap = mapped_external_entity_with_idmap[:idmap]

    if idmap.connec_id.blank?
      connec_entity = self.create_connec_entity(connec_client, external_entity, connec_entity_name, organization)
      idmap.update_attributes(connec_id: connec_entity['id'], connec_entity: connec_entity_name.downcase, last_push_to_connec: Time.now, message: nil)
    else
      connec_entity = self.update_connec_entity(connec_client, external_entity, idmap.connec_id, connec_entity_name, organization)
      idmap.update_attributes(last_push_to_connec: Time.now, message: nil)
    end

    # Store Connec! error if any
    idmap.update_attributes(message: connec_entity['errors'].first['title']) unless connec_entity.blank? || connec_entity['errors'].blank?
  end
end

#push_entities_to_external(external_client, mapped_connec_entities_with_idmaps, organization) ⇒ Object



133
134
135
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 133

def push_entities_to_external(external_client, mapped_connec_entities_with_idmaps, organization)
  push_entities_to_external_to(external_client, mapped_connec_entities_with_idmaps, self.external_entity_name, organization)
end

#push_entities_to_external_to(external_client, mapped_connec_entities_with_idmaps, external_entity_name, organization) ⇒ Object



137
138
139
140
141
142
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 137

def push_entities_to_external_to(external_client, mapped_connec_entities_with_idmaps, external_entity_name, organization)
  Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Sending Connec! #{self.connec_entity_name.pluralize} to #{@@external_name} #{external_entity_name.pluralize}")
  mapped_connec_entities_with_idmaps.each do |mapped_connec_entity_with_idmap|
    self.push_entity_to_external(external_client, mapped_connec_entity_with_idmap, external_entity_name, organization)
  end
end

#push_entity_to_external(external_client, mapped_connec_entity_with_idmap, external_entity_name, organization) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 144

def push_entity_to_external(external_client, mapped_connec_entity_with_idmap, external_entity_name, organization)
  idmap = mapped_connec_entity_with_idmap[:idmap]
  connec_entity = mapped_connec_entity_with_idmap[:entity]

  begin
    if idmap.external_id.blank?
      external_id = self.create_external_entity(external_client, connec_entity, external_entity_name, organization)
      idmap.update_attributes(external_id: external_id, external_entity: external_entity_name.downcase, last_push_to_external: Time.now, message: nil)
    else
      self.update_external_entity(external_client, connec_entity, idmap.external_id, external_entity_name, organization)
      idmap.update_attributes(last_push_to_external: Time.now, message: nil)
    end
  rescue => e
    # Store External error
    idmap.update_attributes(message: e.message)
  end
end

#update_connec_entity(connec_client, mapped_external_entity, connec_id, connec_entity_name, organization) ⇒ Object



107
108
109
110
111
112
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 107

def update_connec_entity(connec_client, mapped_external_entity, connec_id, connec_entity_name, organization)
  Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Sending update #{connec_entity_name}: #{mapped_external_entity} to Connec!")
  response = connec_client.put("/#{connec_entity_name.downcase.pluralize}/#{connec_id}", { "#{connec_entity_name.downcase.pluralize}".to_sym => mapped_external_entity })
  raise "No response received from Connec! when trying to update a #{self.connec_entity_name}" unless response
  JSON.parse(response.body)["#{connec_entity_name.downcase.pluralize}"]
end

#update_external_entity(client, mapped_connec_entity, external_id, external_entity_name, organization) ⇒ Object



167
168
169
170
# File 'app/models/maestrano/connector/rails/concerns/entity.rb', line 167

def update_external_entity(client, mapped_connec_entity, external_id, external_entity_name, organization)
  Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Sending update #{external_entity_name} (id=#{external_id}): #{mapped_connec_entity} to #{@@external_name}")
  raise "Not implemented"
end