28
28
import org .commonjava .indy .data .StoreValidator ;
29
29
import org .commonjava .indy .measure .annotation .Measure ;
30
30
import org .commonjava .indy .model .core .ArtifactStore ;
31
+ import org .commonjava .indy .model .core .Group ;
31
32
import org .commonjava .indy .model .core .HostedRepository ;
32
33
import org .commonjava .indy .model .core .StoreKey ;
33
34
import org .commonjava .indy .model .core .StoreType ;
37
38
import org .slf4j .LoggerFactory ;
38
39
39
40
import javax .inject .Inject ;
41
+ import java .util .ArrayList ;
42
+ import java .util .Collection ;
40
43
import java .util .Collections ;
44
+ import java .util .HashSet ;
45
+ import java .util .List ;
41
46
import java .util .Map ;
42
47
import java .util .Set ;
43
48
import java .util .concurrent .atomic .AtomicReference ;
47
52
import java .util .stream .Collectors ;
48
53
import java .util .stream .Stream ;
49
54
55
+ import static org .commonjava .indy .db .common .StoreUpdateAction .DELETE ;
56
+ import static org .commonjava .indy .db .common .StoreUpdateAction .STORE ;
50
57
import static org .commonjava .indy .model .core .StoreType .hosted ;
51
58
52
59
public abstract class AbstractStoreDataManager
@@ -146,6 +153,11 @@ else if ( !store.isDisabled() && original.isDisabled() )
146
153
}
147
154
}
148
155
}
156
+ // Hosted or Remote update does not change affectedBy relationships
157
+ if ( store instanceof Group )
158
+ {
159
+ refreshAffectedBy ( store , original , STORE );
160
+ }
149
161
}
150
162
151
163
protected void preDelete ( final ArtifactStore store , final ChangeSummary summary , final boolean fireEvents ,
@@ -169,6 +181,14 @@ protected void postDelete( final ArtifactStore store, final ChangeSummary summar
169
181
{
170
182
dispatcher .deleted ( eventMetadata , store );
171
183
}
184
+
185
+ refreshAffectedBy ( store , null , DELETE );
186
+ }
187
+
188
+ protected void refreshAffectedBy ( final ArtifactStore store , final ArtifactStore original , StoreUpdateAction action )
189
+ throws IndyDataException
190
+ {
191
+ //do nothing by default
172
192
}
173
193
174
194
protected abstract ArtifactStore removeArtifactStoreInternal ( StoreKey key );
@@ -422,4 +442,73 @@ public Set<StoreKey> getStoreKeysByPkgAndType( final String pkg, final StoreType
422
442
return streamArtifactStoreKeys ().filter ( key -> key .getPackageType ().equals ( pkg ) && key .getType () == type )
423
443
.collect ( Collectors .toSet () );
424
444
}
445
+
446
+ public Set <Group > affectedBy ( final Collection <StoreKey > keys )
447
+ throws IndyDataException
448
+ {
449
+ return affectedByFromStores ( keys );
450
+ }
451
+
452
+ protected Set <Group > affectedByFromStores ( final Collection <StoreKey > keys )
453
+ throws IndyDataException
454
+ {
455
+ Logger logger = LoggerFactory .getLogger ( getClass () );
456
+ logger .debug ( "Getting groups affected by: {}" , keys );
457
+
458
+ List <StoreKey > toProcess = new ArrayList <>( new HashSet <>( keys ) );
459
+
460
+ Set <Group > groups = new HashSet <>();
461
+ if ( toProcess .isEmpty () )
462
+ {
463
+ return groups ;
464
+ }
465
+
466
+ Set <StoreKey > processed = new HashSet <>();
467
+ final String packageType = toProcess .get ( 0 ).getPackageType ();
468
+
469
+ Set <ArtifactStore > all = this .getAllArtifactStores ().stream ().filter ( st -> {
470
+ if ( packageType != null && !st .getPackageType ().equals ( packageType ) )
471
+ {
472
+ return false ;
473
+ }
474
+
475
+ if ( st .getType () != StoreType .group )
476
+ {
477
+ return false ;
478
+ }
479
+
480
+ return true ;
481
+ } ).collect ( Collectors .toSet () );
482
+
483
+ while ( !toProcess .isEmpty () )
484
+ {
485
+ // as long as we have another key to process, pop it off the list (remove it) and process it.
486
+ StoreKey next = toProcess .remove ( 0 );
487
+ if ( processed .contains ( next ) )
488
+ {
489
+ // if we've already handled this group (via another branch in the group membership tree, etc. then don't bother.
490
+ continue ;
491
+ }
492
+
493
+ // use this to avoid reprocessing groups we've already encountered.
494
+ processed .add ( next );
495
+
496
+ for ( ArtifactStore store : all )
497
+ {
498
+ if ( ( store instanceof Group ) && !processed .contains ( store .getKey () ) )
499
+ {
500
+ Group g = (Group ) store ;
501
+ if ( g .getConstituents () != null && g .getConstituents ().contains ( next ) )
502
+ {
503
+ groups .add ( g );
504
+
505
+ // add this group as another one to process for groups that contain it...and recurse upwards
506
+ toProcess .add ( g .getKey () );
507
+ }
508
+ }
509
+ }
510
+ }
511
+
512
+ return groups ;
513
+ }
425
514
}
0 commit comments