Skip to content

Commit 1efc31b

Browse files
committed
feat (dispatcher): migrate hub config maps to ClientProperties map
1 parent 32e17db commit 1efc31b

10 files changed

Lines changed: 137 additions & 154 deletions

File tree

hub/dispatcher/src/main/java/com/hubsante/hub/config/HubConfiguration.java

Lines changed: 21 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package com.hubsante.hub.config;
1717

18+
import com.hubsante.hub.service.ClientPropertiesRegistry;
1819
import com.hubsante.model.EdxlHandler;
1920
import com.hubsante.model.Validator;
2021
import com.univocity.parsers.common.ParsingContext;
@@ -26,13 +27,10 @@
2627
import jakarta.annotation.PostConstruct;
2728
import java.io.*;
2829
import java.nio.charset.StandardCharsets;
29-
import java.nio.file.Files;
3030
import java.util.*;
3131
import java.util.stream.Collectors;
3232
import lombok.extern.slf4j.Slf4j;
33-
import org.apache.commons.csv.CSVFormat;
34-
import org.apache.commons.csv.CSVParser;
35-
import org.apache.commons.csv.CSVRecord;
33+
import org.springframework.beans.factory.annotation.Autowired;
3634
import org.springframework.beans.factory.annotation.Value;
3735
import org.springframework.context.annotation.Bean;
3836
import org.springframework.context.annotation.Configuration;
@@ -45,8 +43,6 @@ public class HubConfiguration {
4543
private static final int ROW_LENGTH = 11;
4644
private static final String DATA_DIVIDER = ",";
4745
private static final String COLUMN_DIVIDER = ";";
48-
private static final String CLIENT_ID_HEADER = "client_id";
49-
private static final String INHIBITED_USE_CASES_HEADER = "inhibited_use_cases";
5046

5147
private static final StructuredLogger structuredLog = new StructuredLogger(log);
5248

@@ -64,11 +60,9 @@ public class HubConfiguration {
6460
@Value("${spring.rabbitmq.virtual-host}")
6561
private String vhost;
6662

67-
private HashMap<String, Boolean> useXmlPreferences = new HashMap<>();
68-
private HashMap<String, Boolean> directCisuPreferences = new HashMap<>();
69-
private HashMap<String, String> clientsEditorMap = new HashMap<>();
63+
@Autowired private ClientPropertiesRegistry clientPropertiesRegistry;
64+
7065
private Map<String, Map<String, String>> clientsPerimeterAndVersions = new HashMap<>();
71-
private Map<String, List<String>> clientsInhibitedMessages = new HashMap<>();
7266
private List<String> supportedMessages;
7367

7468
@PostConstruct
@@ -94,9 +88,6 @@ public void rowProcessed(Object[] objects, ParsingContext parsingContext) {
9488
ROW_LENGTH);
9589
}
9690
String[] items = Arrays.asList(objects).toArray(new String[ROW_LENGTH]);
97-
useXmlPreferences.put(items[0], Boolean.parseBoolean(items[1]));
98-
directCisuPreferences.put(items[0], Boolean.parseBoolean(items[2]));
99-
clientsEditorMap.put(items[0], items[3]);
10091
}
10192
};
10293
CsvParserSettings parserSettings = new CsvParserSettings();
@@ -109,7 +100,6 @@ public void rowProcessed(Object[] objects, ParsingContext parsingContext) {
109100
CsvParser parser = new CsvParser(parserSettings);
110101
parser.parse(new BufferedReader(new FileReader(configFile, StandardCharsets.UTF_8)));
111102
clientsPerimeterAndVersions = loadClientsPerimetersAndVersions();
112-
clientsInhibitedMessages = loadClientsInhibitedMessages();
113103
supportedMessages = loadSupportedMessages(vhost);
114104
} catch (Exception e) {
115105
throw new Exception("Could not read config file " + configFile.getAbsolutePath(), e);
@@ -157,18 +147,19 @@ public Map<String, Map<String, String>> loadClientsPerimetersAndVersions() throw
157147
return clientsPerimeterAndVersions;
158148
}
159149

160-
public String[] getClientVersionsForPerimeter(String clientId, String perimeterName) {
161-
Map<String, String> clientPerimeterDefinition =
162-
clientsPerimeterAndVersions.getOrDefault(clientId, null);
163-
if (clientPerimeterDefinition == null) {
164-
structuredLog.warn(
165-
"ClientId was not found in clientsPerimeterAndVersions, or the variable is not initialized.",
166-
Map.of(LogConstants.RECIPIENT_ID, clientId));
167-
return null;
168-
}
169-
String versions = clientPerimeterDefinition.getOrDefault(perimeterName, null);
170-
return splitString(versions);
171-
}
150+
// public String[] getClientVersionsForPerimeter(String clientId, String perimeterName) {
151+
// Map<String, String> clientPerimeterDefinition =
152+
// clientsPerimeterAndVersions.getOrDefault(clientId, null);
153+
// if (clientPerimeterDefinition == null) {
154+
// structuredLog.warn(
155+
// "ClientId was not found in clientsPerimeterAndVersions, or the variable is
156+
// not initialized.",
157+
// Map.of(LogConstants.RECIPIENT_ID, clientId));
158+
// return null;
159+
// }
160+
// String versions = clientPerimeterDefinition.getOrDefault(perimeterName, null);
161+
// return splitString(versions);
162+
// }
172163

173164
public List<String> loadSupportedMessages(String vhost) throws Exception {
174165
List<String> supportedMessages = new ArrayList<>();
@@ -198,64 +189,10 @@ public List<String> loadSupportedMessages(String vhost) throws Exception {
198189
return supportedMessages;
199190
}
200191

201-
private Map<String, List<String>> loadClientsInhibitedMessages() throws IOException {
202-
Map<String, List<String>> result = new HashMap<>();
203-
204-
try (Reader reader = Files.newBufferedReader(configFile.toPath());
205-
CSVParser parser =
206-
CSVFormat.DEFAULT
207-
.builder()
208-
.setDelimiter(';')
209-
.setHeader()
210-
.setSkipHeaderRecord(true)
211-
.setTrim(true)
212-
.build()
213-
.parse(reader)) {
214-
boolean hasUseCasesColumn =
215-
parser.getHeaderMap().containsKey(INHIBITED_USE_CASES_HEADER);
216-
217-
for (CSVRecord record : parser) {
218-
219-
String clientId = record.get(CLIENT_ID_HEADER);
220-
List<String> useCases;
221-
222-
if (hasUseCasesColumn) {
223-
useCases =
224-
Arrays.stream(record.get(INHIBITED_USE_CASES_HEADER).split(","))
225-
.map(String::trim)
226-
.filter(s -> !s.isEmpty())
227-
.toList();
228-
} else {
229-
useCases = List.of();
230-
}
231-
232-
result.put(clientId, useCases);
233-
}
234-
}
235-
236-
return Collections.unmodifiableMap(result);
237-
}
238-
239192
public List<String> getSupportedMessages() {
240193
return supportedMessages;
241194
}
242195

243-
public HashMap<String, Boolean> getUseXmlPreferences() {
244-
return useXmlPreferences;
245-
}
246-
247-
public HashMap<String, Boolean> getDirectCisuPreferences() {
248-
return directCisuPreferences;
249-
}
250-
251-
public HashMap<String, String> getClientsEditorMap() {
252-
return clientsEditorMap;
253-
}
254-
255-
public Map<String, List<String>> getClientsInhibitedMessages() {
256-
return clientsInhibitedMessages;
257-
}
258-
259196
public long getDefaultTTL() {
260197
return defaultTTL;
261198
}
@@ -264,6 +201,10 @@ public String getVhost() {
264201
return vhost;
265202
}
266203

204+
public ClientPropertiesRegistry getClientPropertiesRegistry() {
205+
return clientPropertiesRegistry;
206+
}
207+
267208
@Bean
268209
public EdxlHandler edxlHandler() {
269210
return new EdxlHandler();

hub/dispatcher/src/main/java/com/hubsante/hub/service/ClientPropertiesRegistry.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@
1515
*/
1616
package com.hubsante.hub.service;
1717

18+
import com.hubsante.hub.config.LogConstants;
19+
import com.hubsante.hub.config.StructuredLogger;
1820
import com.hubsante.hub.exception.ClientConfigurationException;
1921
import com.hubsante.hub.model.ClientProperties;
2022
import com.hubsante.hub.model.PerimeterDefinition;
2123
import java.util.*;
2224
import java.util.function.Function;
2325
import java.util.stream.Collectors;
26+
import lombok.extern.slf4j.Slf4j;
2427
import org.springframework.beans.factory.annotation.Value;
2528
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
2629
import org.springframework.boot.context.properties.bind.Bindable;
@@ -31,7 +34,10 @@
3134
import org.springframework.stereotype.Component;
3235

3336
@Component
37+
@Slf4j
3438
public class ClientPropertiesRegistry {
39+
private static final StructuredLogger structuredLog = new StructuredLogger(log);
40+
3541
private Map<String, ClientProperties> clientsById = Map.of();
3642

3743
public ClientPropertiesRegistry(@Value("${client.configuration.file}") Resource resource)
@@ -135,12 +141,30 @@ private ClientConfigurationException buildException(Map<String, List<String>> er
135141
}
136142

137143
public ClientProperties get(String clientId) {
138-
ClientProperties clientProperties = clientsById.get(clientId);
144+
return clientsById.get(clientId);
145+
}
146+
147+
public String[] getClientVersionsForPerimeter(String clientId, String perimeterName) {
148+
ClientProperties clientProperties = get(clientId);
139149

140150
if (clientProperties == null) {
141-
throw new ClientConfigurationException("client " + clientId + " is not configured");
151+
structuredLog.warn(
152+
"Client has no configuration", Map.of(LogConstants.RECIPIENT_ID, clientId));
153+
return null;
142154
}
143155

144-
return clientProperties;
156+
PerimeterDefinition perimeter =
157+
clientProperties.perimeters().stream()
158+
.filter(p -> p.name().equals(perimeterName))
159+
.findFirst()
160+
.orElse(null);
161+
162+
if (perimeter == null) {
163+
structuredLog.warn(
164+
"Client does not support perimeter " + perimeterName,
165+
Map.of(LogConstants.RECIPIENT_ID, clientId));
166+
return null;
167+
}
168+
return perimeter.versions().toArray(String[]::new);
145169
}
146170
}

hub/dispatcher/src/main/java/com/hubsante/hub/service/MessageHandler.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.hubsante.hub.config.LogConstants;
3232
import com.hubsante.hub.config.StructuredLogger;
3333
import com.hubsante.hub.exception.*;
34+
import com.hubsante.hub.model.ClientProperties;
3435
import com.hubsante.hub.utils.ConversionRulesCommand;
3536
import com.hubsante.hub.utils.ConversionUtils;
3637
import com.hubsante.hub.utils.EdxlUtils;
@@ -47,10 +48,7 @@
4748
import io.micrometer.core.instrument.MeterRegistry;
4849
import java.io.IOException;
4950
import java.nio.charset.StandardCharsets;
50-
import java.util.HashMap;
51-
import java.util.List;
52-
import java.util.Map;
53-
import java.util.Objects;
51+
import java.util.*;
5452
import lombok.extern.slf4j.Slf4j;
5553
import org.springframework.amqp.AmqpRejectAndDontRequeueException;
5654
import org.springframework.amqp.core.Message;
@@ -89,6 +87,7 @@ public MessageHandler(
8987
MeterRegistry registry,
9088
XmlMapper xmlMapper,
9189
ObjectMapper jsonMapper,
90+
ClientPropertiesRegistry clientPropertiesRegistry,
9291
ConversionHandler conversionHandler) {
9392
this.rabbitTemplate = rabbitTemplate;
9493
this.edxlHandler = edxlHandler;
@@ -200,7 +199,11 @@ protected void sendErrorReport(Error error, String sender) {
200199
String routingKey = infoQueueName;
201200

202201
Message errorAmqpMessage;
203-
if (convertToXML(sender, hubConfig.getUseXmlPreferences().get(sender))) {
202+
Boolean useXML =
203+
hubConfig.getClientPropertiesRegistry().get(sender) != null
204+
? hubConfig.getClientPropertiesRegistry().get(sender).useXml()
205+
: null;
206+
if (convertToXML(sender, useXML)) {
204207
errorAmqpMessage =
205208
new Message(
206209
edxlHandler.serializeXmlEDXL(errorEdxlMessage).getBytes(),
@@ -498,7 +501,11 @@ private Message getFwdMessageBody(
498501
String messageType = getUseCaseFromMessage(edxlMessage.getFirstContentMessage());
499502

500503
try {
501-
if (convertToXML(recipientId, hubConfig.getUseXmlPreferences().get(recipientId))) {
504+
Boolean useXML =
505+
hubConfig.getClientPropertiesRegistry().get(recipientId) != null
506+
? hubConfig.getClientPropertiesRegistry().get(recipientId).useXml()
507+
: null;
508+
if (convertToXML(recipientId, useXML)) {
502509
edxlString = edxlHandler.serializeXmlEDXL(edxlMessage);
503510
fwdAmqpProperties.setContentType(MessageProperties.CONTENT_TYPE_XML);
504511
} else {
@@ -590,11 +597,17 @@ private Message getFwdStringMessageBody(
590597
}
591598

592599
protected void inhibitMessageIfNeeded(EdxlMessage edxlMessage) {
600+
String recipientId = getRecipientID(edxlMessage);
601+
String useCase = EdxlUtils.getUseCaseFromMessage(edxlMessage.getFirstContentMessage());
602+
ClientProperties clientProperties =
603+
hubConfig.getClientPropertiesRegistry().get(recipientId);
604+
List<String> inhibitedUseCases = new ArrayList<>();
605+
606+
if (clientProperties != null) {
607+
inhibitedUseCases = clientProperties.inhibitedUseCases();
608+
}
593609
checkMessageNotInhibited(
594-
getRecipientID(edxlMessage),
595-
EdxlUtils.getUseCaseFromMessage(edxlMessage.getFirstContentMessage()),
596-
hubConfig.getClientsInhibitedMessages(),
597-
edxlMessage.getDistributionID());
610+
recipientId, useCase, inhibitedUseCases, edxlMessage.getDistributionID());
598611
}
599612

600613
private void logMessage(Message message, EdxlMessage edxlMessage, String receivedEdxl) {
@@ -685,6 +698,7 @@ protected void publishMetrics(EdxlMessage edxlMessage, Message amqpMessage) {
685698
}
686699

687700
private String getEditorFromSender(String sender) {
688-
return hubConfig.getClientsEditorMap().getOrDefault(sender, UNKNOWN);
701+
ClientProperties clientProperties = hubConfig.getClientPropertiesRegistry().get(sender);
702+
return clientProperties != null ? clientProperties.editor() : UNKNOWN;
689703
}
690704
}

hub/dispatcher/src/main/java/com/hubsante/hub/utils/ConversionUtils.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static com.hubsante.hub.utils.MessageUtils.*;
2121

2222
import com.hubsante.hub.config.HubConfiguration;
23+
import com.hubsante.hub.model.ClientProperties;
2324
import com.hubsante.model.edxl.EdxlMessage;
2425
import java.util.Arrays;
2526
import lombok.extern.slf4j.Slf4j;
@@ -83,8 +84,10 @@ public static String[] getTargetVHosts(HubConfiguration hubConfig, EdxlMessage e
8384
(isCisuSender && !isDirectCisu) ? Perimeter.HEALTH.getName() : sourcePerimeter;
8485

8586
targetVersionsOnTargetPerimeter =
86-
hubConfig.getClientVersionsForPerimeter(
87-
recipientId, targetPerimeter); // ex ['1.5, 2.0']
87+
hubConfig
88+
.getClientPropertiesRegistry()
89+
.getClientVersionsForPerimeter(
90+
recipientId, targetPerimeter); // ex ['1.5, 2.0']
8891
return formatVersionToVhosts(
8992
targetVersionsOnTargetPerimeter,
9093
targetPerimeter); // ex ["15-15_v1.5", "15-15_v2.0"]
@@ -135,10 +138,14 @@ public static boolean isDirectCisuForHealthActor(
135138
String recipientId = getRecipientID(edxlMessage);
136139
String senderId = edxlMessage.getSenderID();
137140
String healthActor = senderId.startsWith(HEALTH_PREFIX) ? senderId : recipientId;
138-
Boolean directCisuPreference =
139-
hubConfig
140-
.getDirectCisuPreferences()
141-
.getOrDefault(healthActor, DEFAULT_DIRECT_CISU_PREFERENCE);
142-
return directCisuPreference != null && directCisuPreference;
141+
142+
ClientProperties healthActorProperties =
143+
hubConfig.getClientPropertiesRegistry().get(healthActor);
144+
boolean directCisuPreference =
145+
healthActorProperties != null
146+
? healthActorProperties.directCisu()
147+
: DEFAULT_DIRECT_CISU_PREFERENCE;
148+
149+
return directCisuPreference;
143150
}
144151
}

hub/dispatcher/src/main/java/com/hubsante/hub/utils/MessageUtils.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,10 @@ public static void checkMessageClassNameSupported(
155155
public static void checkMessageNotInhibited(
156156
String recipientId,
157157
String useCase,
158-
Map<String, List<String>> inhibitedMessagesByClient,
158+
List<String> inhibitedUseCases,
159159
String distributionId) {
160160

161-
List<String> blockedUseCases =
162-
inhibitedMessagesByClient.getOrDefault(recipientId, List.of());
163-
164-
boolean isInhibited = blockedUseCases.contains(useCase);
161+
boolean isInhibited = inhibitedUseCases.contains(useCase);
165162

166163
if (isInhibited) {
167164
String errorMessage =

hub/dispatcher/src/test/java/com/hubsante/hub/service/ClientPropertiesRegistryTest.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,12 @@ public void shouldLoadClientConfiguration() {
6666
assertNotNull(this.clientPropertiesRegistry);
6767

6868
ClientProperties samuV1Properties = clientPropertiesRegistry.get("fr.health.samuV1");
69-
ClientProperties samuV3Properties = clientPropertiesRegistry.get("fr.health.samuV3");
70-
71-
assertThrows(
72-
ClientConfigurationException.class, () -> clientPropertiesRegistry.get("unknown"));
73-
7469
List<String> samuV1InhibitedMessages = samuV1Properties.inhibitedUseCases();
70+
7571
assertNotNull(samuV1InhibitedMessages);
7672
assertEquals(List.of("ResourcesInfoCisuWrapper"), samuV1InhibitedMessages);
73+
74+
assertNull(clientPropertiesRegistry.get("unknown"));
7775
}
7876

7977
@Test

0 commit comments

Comments
 (0)