Skip to content

Commit 34e530f

Browse files
Merge pull request #257 from SolaceProducts/DATAGO-98841-ema-webproxy
DATAGO-98841: EMA can use webProxy
2 parents e3eccab + f6a5f49 commit 34e530f

File tree

7 files changed

+385
-86
lines changed

7 files changed

+385
-86
lines changed

service/application/pom.xml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,6 @@
4949
</dependencies>
5050
</dependencyManagement>
5151
<dependencies>
52-
<dependency>
53-
<groupId>io.projectreactor.netty</groupId>
54-
<artifactId>reactor-netty-http</artifactId>
55-
<version>1.1.27</version>
56-
<scope>compile</scope>
57-
<exclusions>
58-
<exclusion>
59-
<groupId>io.projectreactor.netty</groupId>
60-
<artifactId>reactor-netty-core</artifactId>
61-
</exclusion>
62-
</exclusions>
63-
</dependency>
6452
<dependency>
6553
<groupId>com.fasterxml.jackson.core</groupId>
6654
<artifactId>jackson-databind</artifactId>

service/application/src/main/java/com/solace/maas/ep/event/management/agent/config/SolaceConfiguration.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.solace.maas.ep.event.management.agent.messagingServices.RtoMessagingService;
55
import com.solace.maas.ep.event.management.agent.plugin.config.EnableRtoCondition;
66
import com.solace.maas.ep.event.management.agent.plugin.jacoco.ExcludeFromJacocoGeneratedReport;
7+
import com.solace.maas.ep.event.management.agent.plugin.messagingService.MessagingServiceConnectionProperties;
78
import com.solace.maas.ep.event.management.agent.plugin.messagingService.RtoMessageBuilder;
89
import com.solace.maas.ep.event.management.agent.plugin.publisher.SolacePublisher;
910
import com.solace.maas.ep.event.management.agent.subscriber.SolaceSubscriber;
@@ -26,6 +27,7 @@
2627

2728
import java.util.ArrayList;
2829
import java.util.List;
30+
import java.util.NoSuchElementException;
2931
import java.util.Properties;
3032

3133
@Slf4j
@@ -69,7 +71,10 @@ public String getTopicPrefix() {
6971
@ConditionalOnProperty(name = "event-portal.gateway.messaging.standalone", havingValue = "false")
7072
public MessagingService messagingService() {
7173
String clientName = vmrConfiguration.getProperty(SolaceProperties.ClientProperties.NAME);
72-
log.info("Connecting to event portal using EMA client {}.", clientName);
74+
String message = isProxyEnabled() ?
75+
"Connecting to event portal using EMA client {} via web proxy." :
76+
"Connecting to event portal using EMA client {} without proxy.";
77+
log.info(message, clientName);
7378
return MessagingService.builder(ConfigurationProfile.V1)
7479
.fromProperties(vmrConfiguration)
7580
.withReconnectionRetryStrategy(RetryStrategy.foreverRetry(15_000))
@@ -118,4 +123,13 @@ public SolacePublisher solacePublisher() {
118123
directMessagePublisher());
119124
}
120125

126+
private boolean isProxyEnabled() {
127+
MessagingServiceConnectionProperties gatewayConnection = eventPortalProperties.getGateway().getMessaging().getConnections().stream()
128+
.filter(c -> "eventPortalGateway".equals(c.getName()))
129+
.findFirst()
130+
.orElseThrow(() -> new NoSuchElementException("Event Portal gateway connection properties not found."));
131+
132+
return (Boolean.TRUE.equals(gatewayConnection.getProxyEnabled()));
133+
}
134+
121135
}
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
package com.solace.maas.ep.event.management.agent.webProxy;
2+
3+
import com.solace.maas.ep.event.management.agent.plugin.config.VMRProperties;
4+
import com.solace.maas.ep.event.management.agent.plugin.config.eventPortal.EventPortalPluginProperties;
5+
import com.solace.maas.ep.event.management.agent.plugin.config.eventPortal.GatewayProperties;
6+
import com.solace.maas.ep.event.management.agent.plugin.config.eventPortal.GatewayMessagingProperties;
7+
import com.solace.maas.ep.event.management.agent.plugin.messagingService.MessagingServiceConnectionProperties;
8+
import com.solace.maas.ep.event.management.agent.plugin.messagingService.MessagingServiceUsersProperties;
9+
import lombok.SneakyThrows;
10+
import org.junit.jupiter.api.AfterEach;
11+
import org.junit.jupiter.api.BeforeEach;
12+
import org.junit.jupiter.api.Test;
13+
import org.junit.jupiter.api.extension.ExtendWith;
14+
import org.mockito.Mock;
15+
import org.mockito.junit.jupiter.MockitoExtension;
16+
import org.springframework.test.context.ActiveProfiles;
17+
18+
import java.util.Collections;
19+
import java.util.List;
20+
import java.util.NoSuchElementException;
21+
import java.util.Properties;
22+
23+
import static org.assertj.core.api.Assertions.assertThat;
24+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
25+
import static org.mockito.Mockito.when;
26+
27+
@ActiveProfiles("TEST")
28+
@ExtendWith(MockitoExtension.class)
29+
class VMRPropertiesTests {
30+
31+
@Mock
32+
private EventPortalPluginProperties eventPortalPluginProperties;
33+
34+
@Mock
35+
private GatewayProperties gatewayProperties;
36+
37+
@Mock
38+
private GatewayMessagingProperties gatewayMessagingProperties;
39+
40+
// Class under test
41+
private VMRProperties vmrProperties;
42+
43+
private Properties systemPropertiesBackup;
44+
45+
@BeforeEach
46+
void setUp() {
47+
// MockitoExtension handles mock initialization
48+
when(eventPortalPluginProperties.getGateway()).thenReturn(gatewayProperties);
49+
when(gatewayProperties.getMessaging()).thenReturn(gatewayMessagingProperties);
50+
vmrProperties = new VMRProperties(eventPortalPluginProperties);
51+
52+
// Backup system properties
53+
systemPropertiesBackup = new Properties();
54+
systemPropertiesBackup.putAll(System.getProperties());
55+
56+
// Clear any solace proxy properties before each test
57+
System.clearProperty("solace.proxy.host");
58+
System.clearProperty("solace.proxy.port");
59+
System.clearProperty("solace.proxy.type");
60+
System.clearProperty("solace.proxy.username");
61+
System.clearProperty("solace.proxy.password");
62+
}
63+
64+
@AfterEach
65+
void tearDown() {
66+
// Restore system properties
67+
System.setProperties(systemPropertiesBackup);
68+
}
69+
70+
private MessagingServiceConnectionProperties createConnectionProperties(
71+
Boolean proxyEnabled, String proxyHost, Integer proxyPort, String proxyType,
72+
String proxyUsername, String proxyPassword) {
73+
return MessagingServiceConnectionProperties.builder()
74+
.name("eventPortalGateway")
75+
.url("tcp://localhost:55555")
76+
.msgVpn("default")
77+
.users(Collections.singletonList(MessagingServiceUsersProperties.builder()
78+
.username("testuser")
79+
.password("testpass")
80+
.clientName("testClient")
81+
.build()))
82+
.proxyEnabled(proxyEnabled)
83+
.proxyHost(proxyHost)
84+
.proxyPort(proxyPort)
85+
.proxyType(proxyType)
86+
.proxyUsername(proxyUsername)
87+
.proxyPassword(proxyPassword)
88+
.build();
89+
}
90+
91+
@Test
92+
@SneakyThrows
93+
void testGetVmrPropertiesProxyDisabled() {
94+
MessagingServiceConnectionProperties connectionProps = createConnectionProperties(false, null, null, null, null, null);
95+
when(gatewayMessagingProperties.getConnections()).thenReturn(Collections.singletonList(connectionProps));
96+
97+
vmrProperties.getVmrProperties();
98+
99+
assertThat(System.getProperty("solace.proxy.host")).isNull();
100+
assertThat(System.getProperty("solace.proxy.port")).isNull();
101+
assertThat(System.getProperty("solace.proxy.type")).isNull();
102+
assertThat(System.getProperty("solace.proxy.username")).isNull();
103+
assertThat(System.getProperty("solace.proxy.password")).isNull();
104+
}
105+
106+
@Test
107+
@SneakyThrows
108+
void testGetVmrPropertiesProxyEnabledNoAuth() {
109+
MessagingServiceConnectionProperties connectionProps = createConnectionProperties(true, "proxy.example.com", 8080, "http", null, null);
110+
when(gatewayMessagingProperties.getConnections()).thenReturn(Collections.singletonList(connectionProps));
111+
112+
vmrProperties.getVmrProperties();
113+
114+
assertThat(System.getProperty("solace.proxy.host")).isEqualTo("proxy.example.com");
115+
assertThat(System.getProperty("solace.proxy.port")).isEqualTo("8080");
116+
assertThat(System.getProperty("solace.proxy.type")).isEqualTo("http");
117+
assertThat(System.getProperty("solace.proxy.username")).isNull();
118+
assertThat(System.getProperty("solace.proxy.password")).isNull();
119+
}
120+
121+
@Test
122+
@SneakyThrows
123+
void testGetVmrPropertiesProxyEnabledWithAuth() {
124+
MessagingServiceConnectionProperties connectionProps = createConnectionProperties(
125+
true,
126+
"secureproxy.example.com",
127+
8443,
128+
"http",
129+
"proxyuser",
130+
"proxypass"
131+
);
132+
when(gatewayMessagingProperties.getConnections()).thenReturn(Collections.singletonList(connectionProps));
133+
134+
vmrProperties.getVmrProperties();
135+
136+
assertThat(System.getProperty("solace.proxy.host")).isEqualTo("secureproxy.example.com");
137+
assertThat(System.getProperty("solace.proxy.port")).isEqualTo("8443");
138+
assertThat(System.getProperty("solace.proxy.type")).isEqualTo("http");
139+
assertThat(System.getProperty("solace.proxy.username")).isEqualTo("proxyuser");
140+
assertThat(System.getProperty("solace.proxy.password")).isEqualTo("proxypass");
141+
}
142+
143+
@Test
144+
@SneakyThrows
145+
void testProxyEnabledButHostBlank() {
146+
MessagingServiceConnectionProperties connectionProps = createConnectionProperties(true, " ", 8080, "http", null, null);
147+
when(gatewayMessagingProperties.getConnections()).thenReturn(Collections.singletonList(connectionProps));
148+
149+
assertThatThrownBy(() -> vmrProperties.getVmrProperties())
150+
.isInstanceOf(RuntimeException.class)
151+
.hasMessageContaining("Proxy host must be configured when proxy is enabled.");
152+
}
153+
154+
@Test
155+
@SneakyThrows
156+
void testProxyEnabledButPortNull() {
157+
MessagingServiceConnectionProperties connectionProps = createConnectionProperties(true, "proxy.example.com", null, "http", null, null);
158+
when(gatewayMessagingProperties.getConnections()).thenReturn(Collections.singletonList(connectionProps));
159+
160+
assertThatThrownBy(() -> vmrProperties.getVmrProperties())
161+
.isInstanceOf(RuntimeException.class)
162+
.hasMessageContaining("Proxy port must be configured when proxy is enabled.");
163+
}
164+
165+
@Test
166+
@SneakyThrows
167+
void testProxyEnabledButPortInvalidZero() {
168+
MessagingServiceConnectionProperties connectionProps = createConnectionProperties(true, "proxy.example.com", 0, "http", null, null);
169+
when(gatewayMessagingProperties.getConnections()).thenReturn(Collections.singletonList(connectionProps));
170+
171+
assertThatThrownBy(() -> vmrProperties.getVmrProperties())
172+
.isInstanceOf(RuntimeException.class)
173+
.hasMessageContaining("Proxy port must be a valid port number (1-65535).");
174+
}
175+
176+
@Test
177+
@SneakyThrows
178+
void testProxyEnabledButPortInvalidNegative() {
179+
MessagingServiceConnectionProperties connectionProps = createConnectionProperties(true, "proxy.example.com", -1, "http", null, null);
180+
when(gatewayMessagingProperties.getConnections()).thenReturn(Collections.singletonList(connectionProps));
181+
182+
assertThatThrownBy(() -> vmrProperties.getVmrProperties())
183+
.isInstanceOf(RuntimeException.class)
184+
.hasMessageContaining("Proxy port must be a valid port number (1-65535).");
185+
}
186+
187+
@Test
188+
@SneakyThrows
189+
void testProxyEnabledButPortInvalidTooLarge() {
190+
MessagingServiceConnectionProperties connectionProps = createConnectionProperties(
191+
true,
192+
"proxy.example.com",
193+
65_536, "http",
194+
null,
195+
null
196+
);
197+
when(gatewayMessagingProperties.getConnections()).thenReturn(Collections.singletonList(connectionProps));
198+
199+
assertThatThrownBy(() -> vmrProperties.getVmrProperties())
200+
.isInstanceOf(RuntimeException.class)
201+
.hasMessageContaining("Proxy port must be a valid port number (1-65535).");
202+
}
203+
204+
@Test
205+
@SneakyThrows
206+
void testProxyEnabledButTypeInvalid() {
207+
MessagingServiceConnectionProperties connectionProps = createConnectionProperties(true, "proxy.example.com", 8080, "socks5", null, null);
208+
when(gatewayMessagingProperties.getConnections()).thenReturn(Collections.singletonList(connectionProps));
209+
210+
assertThatThrownBy(() -> vmrProperties.getVmrProperties())
211+
.isInstanceOf(RuntimeException.class)
212+
.hasMessageContaining("Proxy type must be 'http'.");
213+
}
214+
215+
@Test
216+
@SneakyThrows
217+
void testProxyEnabledUsernamePresentPasswordBlank() {
218+
MessagingServiceConnectionProperties connectionProps = createConnectionProperties(true, "proxy.example.com", 8080, "http", "useronly", " ");
219+
when(gatewayMessagingProperties.getConnections()).thenReturn(Collections.singletonList(connectionProps));
220+
221+
assertThatThrownBy(() -> vmrProperties.getVmrProperties())
222+
.isInstanceOf(RuntimeException.class)
223+
.hasMessageContaining("Proxy password must be configured when proxy username is provided.");
224+
}
225+
226+
@Test
227+
@SneakyThrows
228+
void testProxyEnabledUsernamePresentPasswordNull() {
229+
MessagingServiceConnectionProperties connectionProps = createConnectionProperties(true, "proxy.example.com", 8080, "http", "useronly", null);
230+
when(gatewayMessagingProperties.getConnections()).thenReturn(Collections.singletonList(connectionProps));
231+
232+
assertThatThrownBy(() -> vmrProperties.getVmrProperties())
233+
.isInstanceOf(RuntimeException.class)
234+
.hasMessageContaining("Proxy password must be configured when proxy username is provided.");
235+
}
236+
237+
@Test
238+
@SneakyThrows
239+
void testNoGatewayConnectionProperties() {
240+
// Simulate basic properties being set
241+
vmrProperties.setUrl("tcp://localhost:55555");
242+
vmrProperties.setMsgVpn("default");
243+
vmrProperties.setUsername("testuser");
244+
vmrProperties.setPassword("testpass");
245+
246+
// Simulate that the list of connections does not contain "eventPortalGateway"
247+
MessagingServiceConnectionProperties otherConnection = MessagingServiceConnectionProperties.builder()
248+
.name("otherGateway")
249+
.users(Collections.emptyList()) // Initialize users with an empty list
250+
.build();
251+
when(gatewayMessagingProperties.getConnections()).thenReturn(List.of(otherConnection));
252+
253+
// The call to getVmrProperties will trigger parseVmrProperties and then applyProxyConfiguration.
254+
// applyProxyConfiguration will then fail to find the "eventPortalGateway".
255+
assertThatThrownBy(() -> vmrProperties.getVmrProperties())
256+
.hasCauseExactlyInstanceOf(NoSuchElementException.class)
257+
.hasRootCauseMessage("Event Portal gateway connection properties not found.");
258+
}
259+
}

0 commit comments

Comments
 (0)