2121import org .springframework .transaction .annotation .Transactional ;
2222import org .yaml .snakeyaml .Yaml ;
2323
24+ import javax .annotation .PostConstruct ;
2425import java .io .IOException ;
26+ import java .lang .Exception ;
2527import java .nio .file .Files ;
2628import java .nio .file .Path ;
2729import java .nio .file .Paths ;
@@ -44,26 +46,37 @@ public class DefinitionSyncService implements CommandLineRunner {
4446 private final UtmLogstashFilterService filterService ;
4547
4648 @ Override
47- @ Transactional
4849 public void run (String ... args ) {
49- log .info ("Starting definition sync from filesystem..." );
50- syncFilters ();
51- syncRules ();
52- log .info ("Definition sync completed." );
50+ log .info ("Starting definition sync from filesystem... ---" );
51+ try {
52+ Set <String > filesystemFilters = syncFilters ();
53+ Set <String > filesystemRules = syncRules ();
54+
55+ cleanupOrphanedFilters (filesystemFilters );
56+ cleanupOrphanedRules (filesystemRules );
57+
58+ log .info ("Definition sync completed successfully. ---" );
59+ } catch (Exception e ) {
60+ log .error ("CRITICAL: Definition sync failed. Reason: {} ---" , e .getMessage (), e );
61+ }
5362 }
5463
55- private void syncFilters () {
64+ private Set <String > syncFilters () {
65+ Set <String > foundModules = new HashSet <>();
5666 Path filtersPath = Paths .get ("." ,Constants .APP_FILTER_DEFINITIONS );
5767 if (!Files .exists (filtersPath ) || !Files .isDirectory (filtersPath )) {
5868 log .warn ("Filters directory not found: {}" , Constants .APP_FILTER_DEFINITIONS );
59- return ;
69+ return foundModules ;
6070 }
6171
6272 try (Stream <Path > paths = Files .walk (filtersPath )) {
6373 paths .filter (path -> Files .isRegularFile (path ) && isYamlFile (path )).forEach (path -> {
64- String moduleName = getFileNameWithoutExtension (path );
74+ String rawName = getFileNameWithoutExtension (path );
75+ String moduleName = rawName .toUpperCase ().replace ("-" , "_" );
76+ foundModules .add (moduleName );
6577 try {
6678 String content = Files .readString (path );
79+
6780 Optional <UtmLogstashFilter > filterOpt = filterRepository .findOneByModuleName (moduleName );
6881
6982 if (filterOpt .isPresent ()) {
@@ -75,7 +88,6 @@ private void syncFilters() {
7588 filterService .save (filter , true );
7689 }
7790 } else {
78- log .info ("Inserting new filter for module: {}" , moduleName );
7991 UtmLogstashFilter filter = new UtmLogstashFilter ();
8092 filter .setModuleName (moduleName );
8193 filter .setFilterName (moduleName + " Filter" );
@@ -99,13 +111,15 @@ private void syncFilters() {
99111 } catch (IOException e ) {
100112 log .error ("Error listing filters directory: {}" , e .getMessage ());
101113 }
114+ return foundModules ;
102115 }
103116
104- private void syncRules () {
117+ private Set <String > syncRules () {
118+ Set <String > foundRules = new HashSet <>();
105119 Path rulesPath = Paths .get ("." ,Constants .APP_RULE_DEFINITIONS );
106120 if (!Files .exists (rulesPath ) || !Files .isDirectory (rulesPath )) {
107121 log .warn ("Rules directory not found: {}" , Constants .APP_RULE_DEFINITIONS );
108- return ;
122+ return foundRules ;
109123 }
110124
111125 Yaml yaml = new Yaml ();
@@ -120,6 +134,7 @@ private void syncRules() {
120134 return ;
121135 }
122136
137+ foundRules .add (ruleYaml .getName ());
123138 Optional <UtmCorrelationRules > ruleOpt = rulesRepository .findOneByRuleName (ruleYaml .getName ());
124139 UtmCorrelationRulesDTO ruleDto = new UtmCorrelationRulesDTO ();
125140
@@ -173,6 +188,35 @@ private void syncRules() {
173188 } catch (IOException e ) {
174189 log .error ("Error walking rules directory: {}" , e .getMessage ());
175190 }
191+ return foundRules ;
192+ }
193+
194+ private void cleanupOrphanedFilters (Set <String > currentFilesystemModules ) {
195+ if (currentFilesystemModules .isEmpty ()) return ;
196+
197+ List <UtmLogstashFilter > systemFilters = filterRepository .findAllBySystemOwnerIsTrue ();
198+ systemFilters .stream ()
199+ .filter (filter -> !currentFilesystemModules .contains (filter .getModuleName ()))
200+ .forEach (filter -> {
201+ log .info ("Deleting orphaned system filter: {}" , filter .getModuleName ());
202+ filterService .delete (filter .getId ());
203+ });
204+ }
205+
206+ private void cleanupOrphanedRules (Set <String > currentFilesystemRules ) {
207+ if (currentFilesystemRules .isEmpty ()) return ;
208+
209+ List <UtmCorrelationRules > systemRules = rulesRepository .findAllBySystemOwnerIsTrue ();
210+ systemRules .stream ()
211+ .filter (rule -> !currentFilesystemRules .contains (rule .getRuleName ()))
212+ .forEach (rule -> {
213+ log .info ("Deleting orphaned system rule: {}" , rule .getRuleName ());
214+ try {
215+ rulesService .deleteRule (rule .getId (), true );
216+ } catch (Exception e ) {
217+ log .error ("Error deleting orphaned system rule {}: {}" , rule .getRuleName (), e .getMessage ());
218+ }
219+ });
176220 }
177221
178222 private boolean isYamlFile (Path path ) {
0 commit comments