1111import com .park .utmstack .service .dto .correlation .AdversaryType ;
1212import com .park .utmstack .service .dto .correlation .UtmCorrelationRulesDTO ;
1313import com .park .utmstack .service .dto .correlation .UtmCorrelationRulesMapper ;
14+ import com .park .utmstack .service .logstash_filter .UtmLogstashFilterService ;
1415import lombok .Data ;
1516import lombok .RequiredArgsConstructor ;
1617import org .slf4j .Logger ;
2021import org .springframework .transaction .annotation .Transactional ;
2122import org .yaml .snakeyaml .Yaml ;
2223
24+ import javax .annotation .PostConstruct ;
2325import java .io .IOException ;
26+ import java .lang .Exception ;
2427import java .nio .file .Files ;
2528import java .nio .file .Path ;
2629import java .nio .file .Paths ;
@@ -40,28 +43,40 @@ public class DefinitionSyncService implements CommandLineRunner {
4043 private final UtmDataTypesRepository dataTypesRepository ;
4144 private final UtmCorrelationRulesService rulesService ;
4245 private final UtmCorrelationRulesMapper rulesMapper ;
46+ private final UtmLogstashFilterService filterService ;
4347
4448 @ Override
45- @ Transactional
4649 public void run (String ... args ) {
47- log .info ("Starting definition sync from filesystem..." );
48- syncFilters ();
49- syncRules ();
50- 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+ }
5162 }
5263
53- private void syncFilters () {
64+ private Set <String > syncFilters () {
65+ Set <String > foundModules = new HashSet <>();
5466 Path filtersPath = Paths .get ("." ,Constants .APP_FILTER_DEFINITIONS );
5567 if (!Files .exists (filtersPath ) || !Files .isDirectory (filtersPath )) {
5668 log .warn ("Filters directory not found: {}" , Constants .APP_FILTER_DEFINITIONS );
57- return ;
69+ return foundModules ;
5870 }
5971
6072 try (Stream <Path > paths = Files .walk (filtersPath )) {
6173 paths .filter (path -> Files .isRegularFile (path ) && isYamlFile (path )).forEach (path -> {
62- String moduleName = getFileNameWithoutExtension (path );
74+ String rawName = getFileNameWithoutExtension (path );
75+ String moduleName = rawName .toUpperCase ().replace ("-" , "_" );
76+ foundModules .add (moduleName );
6377 try {
6478 String content = Files .readString (path );
79+
6580 Optional <UtmLogstashFilter > filterOpt = filterRepository .findOneByModuleName (moduleName );
6681
6782 if (filterOpt .isPresent ()) {
@@ -70,11 +85,11 @@ private void syncFilters() {
7085 log .info ("Updating existing filter for module: {}" , moduleName );
7186 filter .setLogstashFilter (content );
7287 filter .setUpdatedAt (Instant .now ());
73- filterRepository .save (filter );
88+ filterService .save (filter , true );
7489 }
7590 } else {
76- log .info ("Inserting new filter for module: {}" , moduleName );
7791 UtmLogstashFilter filter = new UtmLogstashFilter ();
92+ filter .setId (filterService .getSystemSequenceNextValue ());
7893 filter .setModuleName (moduleName );
7994 filter .setFilterName (moduleName + " Filter" );
8095 filter .setLogstashFilter (content );
@@ -88,7 +103,7 @@ private void syncFilters() {
88103 filter .setDatatype (dataType .get ());
89104 }
90105
91- filterRepository .save (filter );
106+ filterService .save (filter , true );
92107 }
93108 } catch (IOException e ) {
94109 log .error ("Error reading filter file {}: {}" , path , e .getMessage ());
@@ -97,13 +112,15 @@ private void syncFilters() {
97112 } catch (IOException e ) {
98113 log .error ("Error listing filters directory: {}" , e .getMessage ());
99114 }
115+ return foundModules ;
100116 }
101117
102- private void syncRules () {
118+ private Set <String > syncRules () {
119+ Set <String > foundRules = new HashSet <>();
103120 Path rulesPath = Paths .get ("." ,Constants .APP_RULE_DEFINITIONS );
104121 if (!Files .exists (rulesPath ) || !Files .isDirectory (rulesPath )) {
105122 log .warn ("Rules directory not found: {}" , Constants .APP_RULE_DEFINITIONS );
106- return ;
123+ return foundRules ;
107124 }
108125
109126 Yaml yaml = new Yaml ();
@@ -118,13 +135,14 @@ private void syncRules() {
118135 return ;
119136 }
120137
138+ foundRules .add (ruleYaml .getName ());
121139 Optional <UtmCorrelationRules > ruleOpt = rulesRepository .findOneByRuleName (ruleYaml .getName ());
122140 UtmCorrelationRulesDTO ruleDto = new UtmCorrelationRulesDTO ();
123141
124142 if (ruleOpt .isPresent ()) {
125143 ruleDto .setId (ruleOpt .get ().getId ());
126144 } else {
127- ruleDto .setId (rulesRepository . getNextId ());
145+ ruleDto .setId (rulesService . getSystemSequenceNextValue ());
128146 }
129147
130148 ruleDto .setName (ruleYaml .getName ());
@@ -158,11 +176,10 @@ private void syncRules() {
158176
159177 UtmCorrelationRules entity = rulesMapper .toEntity (ruleDto );
160178 if (ruleOpt .isPresent ()) {
161- rulesService .updateRule (entity );
162- log .error ("Updated rule {}: {}" , path , ruleDto .getName ());
179+ rulesService .updateRule (entity , true );
163180
164181 } else {
165- rulesService .save (entity );
182+ rulesService .save (entity , true );
166183 }
167184
168185 } catch (Exception e ) {
@@ -172,11 +189,38 @@ private void syncRules() {
172189 } catch (IOException e ) {
173190 log .error ("Error walking rules directory: {}" , e .getMessage ());
174191 }
192+ return foundRules ;
175193 }
176194
177- private boolean isYamlFile (Path path ) {
195+ private void cleanupOrphanedFilters (Set <String > currentFilesystemModules ) {
196+ if (currentFilesystemModules .isEmpty ()) return ;
197+
198+ List <UtmLogstashFilter > systemFilters = filterRepository .findAllBySystemOwnerIsTrue ();
199+ systemFilters .stream ()
200+ .filter (filter -> !currentFilesystemModules .contains (filter .getModuleName ()))
201+ .forEach (filter -> {
202+ log .info ("Deleting orphaned system filter: {}" , filter .getModuleName ());
203+ filterService .delete (filter .getId ());
204+ });
205+ }
178206
179- log .error ("Analyzing files: {} " , path );
207+ private void cleanupOrphanedRules (Set <String > currentFilesystemRules ) {
208+ if (currentFilesystemRules .isEmpty ()) return ;
209+
210+ List <UtmCorrelationRules > systemRules = rulesRepository .findAllBySystemOwnerIsTrue ();
211+ systemRules .stream ()
212+ .filter (rule -> !currentFilesystemRules .contains (rule .getRuleName ()))
213+ .forEach (rule -> {
214+ log .info ("Deleting orphaned system rule: {}" , rule .getRuleName ());
215+ try {
216+ rulesService .deleteRule (rule .getId (), true );
217+ } catch (Exception e ) {
218+ log .error ("Error deleting orphaned system rule {}: {}" , rule .getRuleName (), e .getMessage ());
219+ }
220+ });
221+ }
222+
223+ private boolean isYamlFile (Path path ) {
180224 String fileName = path .getFileName ().toString ().toLowerCase ();
181225 return fileName .endsWith (".yaml" ) || fileName .endsWith (".yml" );
182226 }
0 commit comments