@@ -24,6 +24,7 @@ package replication
2424
2525import (
2626 "context"
27+ "sort"
2728 "time"
2829
2930 "github.com/arangodb/arangosync/client"
@@ -240,28 +241,66 @@ func (dr *DeploymentReplication) hasOutgoingEndpoint(status client.SyncInfo, epS
240241func createEndpointStatus (status client.SyncInfo , outgoingID string ) api.EndpointStatus {
241242 result := api.EndpointStatus {}
242243 if outgoingID == "" {
243- for _ , s := range status .Shards {
244- result .Shards = append (result .Shards , api.ShardStatus {
245- Database : s .Database ,
246- Collection : s .Collection ,
247- ShardIndex : s .ShardIndex ,
248- Status : string (s .Status ),
249- })
244+ return createEndpointStatusFromShards (status .Shards )
245+ }
246+ for _ , o := range status .Outgoing {
247+ if o .ID != outgoingID {
248+ continue
250249 }
251- } else {
252- for _ , o := range status .Outgoing {
253- if o .ID != outgoingID {
254- continue
250+ return createEndpointStatusFromShards (o .Shards )
251+ }
252+
253+ return result
254+ }
255+
256+ // createEndpointStatusFromShards creates an api EndpointStatus from the given list of shard statuses.
257+ func createEndpointStatusFromShards (shards []client.ShardSyncInfo ) api.EndpointStatus {
258+ result := api.EndpointStatus {}
259+
260+ getDatabase := func (name string ) * api.DatabaseStatus {
261+ for i , d := range result .Databases {
262+ if d .Name == name {
263+ return & result .Databases [i ]
255264 }
256- for _ , s := range o .Shards {
257- result .Shards = append (result .Shards , api.ShardStatus {
258- Database : s .Database ,
259- Collection : s .Collection ,
260- ShardIndex : s .ShardIndex ,
261- Status : string (s .Status ),
262- })
265+ }
266+ // Not found, add it
267+ result .Databases = append (result .Databases , api.DatabaseStatus {Name : name })
268+ return & result .Databases [len (result .Databases )- 1 ]
269+ }
270+
271+ getCollection := func (db * api.DatabaseStatus , name string ) * api.CollectionStatus {
272+ for i , c := range db .Collections {
273+ if c .Name == name {
274+ return & db .Collections [i ]
263275 }
264276 }
277+ // Not found, add it
278+ db .Collections = append (db .Collections , api.CollectionStatus {Name : name })
279+ return & db .Collections [len (db .Collections )- 1 ]
280+ }
281+
282+ // Sort shard by index
283+ sort .Slice (shards , func (i , j int ) bool {
284+ return shards [i ].ShardIndex < shards [j ].ShardIndex
285+ })
286+ for _ , s := range shards {
287+ db := getDatabase (s .Database )
288+ col := getCollection (db , s .Collection )
289+
290+ // Add "missing" shards if needed
291+ for len (col .Shards ) < s .ShardIndex {
292+ col .Shards = append (col .Shards , api.ShardStatus {Status : "" })
293+ }
294+
295+ // Add current shard
296+ col .Shards = append (col .Shards , api.ShardStatus {Status : string (s .Status )})
297+ }
298+
299+ // Sort result
300+ sort .Slice (result .Databases , func (i , j int ) bool { return result .Databases [i ].Name < result .Databases [j ].Name })
301+ for i , db := range result .Databases {
302+ sort .Slice (db .Collections , func (i , j int ) bool { return db .Collections [i ].Name < db .Collections [j ].Name })
303+ result .Databases [i ] = db
265304 }
266305 return result
267306}
0 commit comments