@@ -237,7 +237,7 @@ func CreateServiceAsset(session et.Session, src *dbt.Entity, rel oam.Relation, s
237237}
238238
239239func CreateOrgAsset (session et.Session , obj * dbt.Entity , rel oam.Relation , o * org.Organization , src * et.Source ) (* dbt.Entity , error ) {
240- if orgent := orgDedupChecks (session , obj , rel , o ); orgent != nil {
240+ if orgent := orgDedupChecks (session , obj , o ); orgent != nil {
241241 if err := createRelation (session , obj , rel , orgent , src ); err != nil {
242242 return nil , err
243243 }
@@ -265,14 +265,25 @@ func CreateOrgAsset(session et.Session, obj *dbt.Entity, rel oam.Relation, o *or
265265 return nil , errors .New ("failed to create the OAM Organization asset" )
266266}
267267
268- func orgDedupChecks (session et.Session , obj * dbt.Entity , rel oam. Relation , o * org.Organization ) * dbt.Entity {
268+ func orgDedupChecks (session et.Session , obj * dbt.Entity , o * org.Organization ) * dbt.Entity {
269269 var result * dbt.Entity
270270
271271 switch obj .Asset .(type ) {
272272 case * contact.ContactRecord :
273273 if org , found := orgNameExistsInContactRecord (session , obj , o .Name ); found {
274274 result = org
275275 }
276+ if org , err := orgExistsAndSharesLocEntity (session , obj , o ); err == nil {
277+ result = org
278+ }
279+ case * org.Organization :
280+ if org , err := orgExistsAndSharesLocEntity (session , obj , o ); err == nil {
281+ result = org
282+ }
283+ default :
284+ if org , err := orgExistsAndSharesAncestorEntity (session , o ); err == nil {
285+ result = org
286+ }
276287 }
277288
278289 return result
@@ -312,6 +323,101 @@ func orgNameExistsInContactRecord(session et.Session, cr *dbt.Entity, name strin
312323 return nil , false
313324}
314325
326+ func orgExistsAndSharesLocEntity (session et.Session , obj * dbt.Entity , o * org.Organization ) (* dbt.Entity , error ) {
327+ var locs []* dbt.Entity
328+
329+ if edges , err := session .Cache ().OutgoingEdges (obj , time.Time {}, "location" ); err == nil {
330+ for _ , edge := range edges {
331+ if a , err := session .Cache ().FindEntityById (edge .ToEntity .ID ); err == nil && a != nil {
332+ if _ , ok := a .Asset .(* contact.Location ); ok {
333+ locs = append (locs , a )
334+ }
335+ }
336+ }
337+ }
338+
339+ var orgents , crecords []* dbt.Entity
340+ for _ , loc := range locs {
341+ if edges , err := session .Cache ().IncomingEdges (loc , time.Time {}, "location" ); err == nil {
342+ for _ , edge := range edges {
343+ if a , err := session .Cache ().FindEntityById (edge .FromEntity .ID ); err == nil && a != nil {
344+ if _ , ok := a .Asset .(* contact.ContactRecord ); ok && a .ID != obj .ID {
345+ crecords = append (crecords , a )
346+ } else if _ , ok := a .Asset .(* org.Organization ); ok {
347+ orgents = append (orgents , a )
348+ }
349+ }
350+ }
351+ }
352+ }
353+
354+ for _ , cr := range crecords {
355+ if edges , err := session .Cache ().OutgoingEdges (cr , time.Time {}, "organization" ); err == nil {
356+ for _ , edge := range edges {
357+ if a , err := session .Cache ().FindEntityById (edge .ToEntity .ID ); err == nil && a != nil {
358+ if _ , ok := a .Asset .(* org.Organization ); ok {
359+ orgents = append (orgents , a )
360+ }
361+ }
362+ }
363+ }
364+ }
365+
366+ for _ , orgent := range orgents {
367+ if strings .EqualFold (orgent .Asset .(* org.Organization ).Name , o .Name ) {
368+ return orgent , nil
369+ }
370+ }
371+
372+ return nil , errors .New ("no matching org found" )
373+ }
374+
375+ func orgExistsAndSharesAncestorEntity (session et.Session , o * org.Organization ) (* dbt.Entity , error ) {
376+ var idents []* dbt.Entity
377+
378+ if assets , err := session .Cache ().FindEntitiesByContent (& general.Identifier {
379+ UniqueID : fmt .Sprintf ("%s:%s" , "org_name" , o .Name ),
380+ EntityID : o .Name ,
381+ Type : "org_name" ,
382+ }, time.Time {}); err == nil {
383+ for _ , a := range assets {
384+ if _ , ok := a .Asset .(* general.Identifier ); ok {
385+ idents = append (idents , a )
386+ }
387+ }
388+ }
389+
390+ var orgents []* dbt.Entity
391+ for _ , ident := range idents {
392+ if edges , err := session .Cache ().IncomingEdges (ident , time.Time {}, "id" ); err == nil {
393+ for _ , edge := range edges {
394+ if a , err := session .Cache ().FindEntityById (edge .FromEntity .ID ); err == nil && a != nil {
395+ if _ , ok := a .Asset .(* org.Organization ); ok {
396+ orgents = append (orgents , a )
397+ }
398+ }
399+ }
400+ }
401+ }
402+
403+ ancestors := make (map [string ]struct {})
404+ for _ , orgent := range orgents {
405+ if edges , err := session .Cache ().IncomingEdges (orgent , time.Time {}); err == nil {
406+ for _ , edge := range edges {
407+ if a , err := session .Cache ().FindEntityById (edge .FromEntity .ID ); err == nil && a != nil {
408+ if _ , found := ancestors [a .ID ]; ! found {
409+ ancestors [a .ID ] = struct {}{}
410+ } else {
411+ return orgent , nil
412+ }
413+ }
414+ }
415+ }
416+ }
417+
418+ return nil , errors .New ("no matching org found" )
419+ }
420+
315421func createRelation (session et.Session , obj * dbt.Entity , rel oam.Relation , subject * dbt.Entity , src * et.Source ) error {
316422 edge , err := session .Cache ().CreateEdge (& dbt.Edge {
317423 Relation : rel ,
0 commit comments