Skip to content

Commit 3678b18

Browse files
authored
Add credential options (#286)
Option --uri added to CLI utility Option --uri enables to specify RabbitMQ URI including credentials.
1 parent a36b905 commit 3678b18

File tree

8 files changed

+136
-25
lines changed

8 files changed

+136
-25
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 2.1.2
2+
- Added external parameters to send username, password and/or uri to connect to Messagebus.
3+
14
## 2.1.1
25
- Implemented the changes to log the eventId and HTTPStatus while the level is INFO.
36
- Implemented the changes to print the user information while the log level is INFO.

publish-cli/src/main/java/com/ericsson/eiffel/remrem/publish/cli/CliOptions.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class CliOptions {
3434
static private Options options=null;
3535
static private CommandLine commandLine;
3636
private static final String SEMANTICS_ROUTINGKEY_TYPE_OVERRIDE_FILEPATH = "semanticsRoutingKeyTypeOverrideFilepath";
37+
public static final String[] VALID_TLS_VERSIONS = new String[]{"1", "1.1", "1.2", "1.3", "default"};
38+
3739
//Used for testing purposes
3840
private static ArrayList<Integer> testErrorCodes = new ArrayList<>();
3941

@@ -75,7 +77,7 @@ public static void createCLIOptions() {
7577
options.addOption("np", "non_persistent", false, "remove persistence from message sending");
7678
options.addOption("port", "port", true, "port to connect to message bus, default is 5672");
7779
options.addOption("vh", "virtual_host", true, "virtual host to connect to (optional)");
78-
options.addOption("tls", "tls", true, "tls version, specify a valid tls version: '1', '1.1, '1.2' or 'default'. It is required for RabbitMq secured port.");
80+
options.addOption("tls", "tls", true, "tls version, specify a valid tls version: '1'..'1.3' or 'default'. It is required for RabbitMq secured port.");
7981
options.addOption("mp", "messaging_protocol", true, "name of messaging protocol to be used, e.g. eiffel3, eiffelsemantics, default is eiffelsemantics");
8082
options.addOption("domain", "domainId", true, "identifies the domain that produces the event");
8183
options.addOption("cc", "channelsCount", true, "Number of channels connected to message bus, default is 1");
@@ -86,6 +88,9 @@ public static void createCLIOptions() {
8688
options.addOption("rk", "routing_key", true, "routing key of the eiffel message. When provided routing key is not generated and the value provided is used.");
8789
options.addOption("tto", "tcp_time_out", true, "specifies tcp connection timeout, default time is 60000 milliseconds");
8890
options.addOption("srkt", SEMANTICS_ROUTINGKEY_TYPE_OVERRIDE_FILEPATH, true, "Default uses the routing key defined in Eiffel Sepia.To make it compatible to prior routing key structure provide the path to routing-key-overrides.properties.");
91+
options.addOption("un", "username", true, "username to connect to message bus");
92+
options.addOption("pwd", "password", true, "password to connect to message bus");
93+
options.addOption("ur", "uri", true, "URI to connect to message bus");
8994

9095
contentGroup = createContentGroup();
9196
options.addOptionGroup(contentGroup);
@@ -246,8 +251,7 @@ public static void handleMessageBusOptions() throws HandleMessageBusException {
246251
if (tls_ver == null) {
247252
tls_ver = "NULL";
248253
}
249-
String[] validTlsVersions = new String[]{"1", "1.1", "1.2", "default"};
250-
if (!ArrayUtils.contains(validTlsVersions, tls_ver)) {
254+
if (!ArrayUtils.contains(VALID_TLS_VERSIONS, tls_ver)) {
251255
throw new HandleMessageBusException("Specified TLS version is not valid! Specify a valid TLS version!");
252256
}
253257
String key = PropertiesConfig.TLS;
@@ -260,6 +264,24 @@ public static void handleMessageBusOptions() throws HandleMessageBusException {
260264
System.setProperty(key, semanticsRoutingKeyTypeOverrideFilepath);
261265
}
262266

267+
if (commandLine.hasOption("username")) {
268+
String usernm = commandLine.getOptionValue("username");
269+
String key = PropertiesConfig.USERNAME;
270+
System.setProperty(key, usernm);
271+
}
272+
273+
if (commandLine.hasOption("password")) {
274+
String passwd = commandLine.getOptionValue("password");
275+
String key = PropertiesConfig.PASSWORD;
276+
System.setProperty(key, passwd);
277+
}
278+
279+
if (commandLine.hasOption("uri")) {
280+
String passwd = commandLine.getOptionValue("uri");
281+
String key = PropertiesConfig.URI;
282+
System.setProperty(key, passwd);
283+
}
284+
263285
String usePersistance = "true";
264286
if (commandLine.hasOption("np")) {
265287
usePersistance = "false";
@@ -297,6 +319,9 @@ public static void clearSystemProperties() {
297319
System.clearProperty(PropertiesConfig.TCP_TIMEOUT);
298320
System.clearProperty(PropertiesConfig.WAIT_FOR_CONFIRMS_TIME_OUT);
299321
System.clearProperty(PropertiesConfig.SEMANTICS_ROUTINGKEY_TYPE_OVERRIDE_FILEPATH);
322+
System.clearProperty(PropertiesConfig.USERNAME);
323+
System.clearProperty(PropertiesConfig.PASSWORD);
324+
System.clearProperty(PropertiesConfig.URI);
300325
}
301326

302327
/**

publish-cli/src/test/java/com/ericsson/eiffel/remrem/publish/cli/CliOptionsUnitTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.junit.After;
2323
import org.junit.Before;
24+
import org.junit.Ignore;
2425
import org.junit.Test;
2526

2627
import com.ericsson.eiffel.remrem.publish.config.PropertiesConfig;
@@ -80,6 +81,7 @@ public void testTlsOptionFails() throws Exception {
8081
}
8182

8283
@Test
84+
@Ignore // Why TLS 1.3 should not be accepted? Ignoring the test...
8385
public void testTlsVer13OptionFails() throws Exception {
8486
String[] args = {"-f", "/a/b/c/test.file", "test", "-tls", "1.3"};
8587
CliOptions.parse(args);

publish-common/src/main/java/com/ericsson/eiffel/remrem/publish/config/PropertiesConfig.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ public class PropertiesConfig {
2828
public static final String TEST_MODE = "com.ericsson.eiffel.remrem.publish.cli.test.mode";
2929
public static final String DEBUG = "Debug";
3030
public static final String DOMAIN_ID = "com.ericsson.eiffel.remrem.publish.domain";
31+
public static final String USERNAME = "com.ericsson.eiffel.remrem.publish.messagebus.username";
32+
public static final String PASSWORD = "com.ericsson.eiffel.remrem.publish.messagebus.password";
33+
public static final String URI = "com.ericsson.eiffel.remrem.publish.messagebus.uri";
3134

3235
public static final String INVALID_EVENT_CONTENT = "Invalid event content, client need to fix problem in event before submitting again";
3336
public static final String INVALID_MESSAGE = "Bad Request";

publish-common/src/main/java/com/ericsson/eiffel/remrem/publish/helper/RabbitMqProperties.java

Lines changed: 79 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,12 @@
1616

1717
import java.io.FileInputStream;
1818
import java.io.IOException;
19+
import java.net.URI;
20+
import java.net.URISyntaxException;
1921
import java.security.KeyManagementException;
2022
import java.security.NoSuchAlgorithmException;
21-
import java.util.ArrayList;
22-
import java.util.List;
23-
import java.util.MissingResourceException;
24-
import java.util.Random;
25-
import java.util.ResourceBundle;
23+
import java.util.*;
2624
import java.util.concurrent.TimeoutException;
27-
import java.util.PropertyResourceBundle;
2825

2926
import org.apache.commons.lang3.StringUtils;
3027
import org.slf4j.LoggerFactory;
@@ -61,6 +58,8 @@ public class RabbitMqProperties {
6158
private boolean createExchangeIfNotExisting;
6259
private String routingKeyTypeOverrideFilePath;
6360
private Integer tcpTimeOut;
61+
private String uri;
62+
private URI parsedUri;
6463
private boolean hasExchange = false;
6564
// built in tcp connection timeout value for MB in milliseconds.
6665
public static final Integer DEFAULT_TCP_TIMEOUT = 60000;
@@ -100,7 +99,13 @@ public void setWaitForConfirmsTimeOut(Long waitForConfirmsTimeOut) {
10099
}
101100

102101
public String getHost() {
103-
return host;
102+
if (host != null)
103+
return host;
104+
105+
if (parsedUri != null)
106+
return parsedUri.getHost();
107+
108+
return null;
104109
}
105110

106111
public void setHost(String host) {
@@ -119,7 +124,13 @@ public void setExchangeName(String exchangeName) {
119124
}
120125

121126
public Integer getPort() {
122-
return port;
127+
if (port != null)
128+
return port;
129+
130+
if (parsedUri != null)
131+
return parsedUri.getPort();
132+
133+
return null;
123134
}
124135

125136
public void setPort(Integer port) {
@@ -139,15 +150,35 @@ public void setTlsVer(String tlsVer) {
139150
}
140151

141152
public String getUsername() {
142-
return username;
153+
if (username != null)
154+
return username;
155+
156+
return parseUserInfoFromUri(0 /* password is at index 1 */);
143157
}
144158

145159
public void setUsername(String user) {
146160
this.username = user;
147161
}
148162

163+
private String parseUserInfoFromUri(int index) {
164+
if (parsedUri == null)
165+
parsedUri = URI.create(uri);
166+
167+
String userInfo = parsedUri.getUserInfo();
168+
if (userInfo != null) {
169+
String[] usernameAndPassword = userInfo.split(":");
170+
if (usernameAndPassword.length > index)
171+
return usernameAndPassword[index];
172+
}
173+
174+
return null;
175+
}
176+
149177
public String getPassword() {
150-
return password;
178+
if (password != null)
179+
return password;
180+
181+
return parseUserInfoFromUri(1 /* password is at index 1 */);
151182
}
152183

153184
public void setPassword(String password) {
@@ -225,10 +256,16 @@ public void init() {
225256
} else {
226257
initService();
227258
}
228-
madatoryParametersCheck();
259+
229260
try {
230-
factory.setHost(host);
231-
log.info("Host address: " + host);
261+
if (uri != null) {
262+
factory.setUri(uri);
263+
}
264+
265+
if (host != null) {
266+
factory.setHost(host);
267+
log.info("Host address: " + host);
268+
}
232269

233270
if (port != null) {
234271
factory.setPort(port);
@@ -265,10 +302,16 @@ public void init() {
265302
log.info("Using standard connection method to RabbitMQ.");
266303
}
267304

305+
madatoryParametersCheck();
268306
} catch (KeyManagementException e) {
269307
log.error(e.getMessage(), e);
308+
throw new RuntimeException(e);
270309
} catch (NoSuchAlgorithmException e) {
271-
log.error(e.getMessage(), e);
310+
log.error(e.getMessage(), e);
311+
throw new RuntimeException(e);
312+
} catch (URISyntaxException e) {
313+
log.error(e.getMessage(), e);
314+
throw new RuntimeException(e);
272315
}
273316
try {
274317
//The exception can be safely handled here as there is a check for existence of exchange is done before each publish.
@@ -433,6 +476,18 @@ private void setValues() {
433476
createExchangeIfNotExisting = Boolean.parseBoolean(getValuesFromSystemProperties(PropertiesConfig.CREATE_EXCHANGE_IF_NOT_EXISTING));
434477
tcpTimeOut = Integer.getInteger(PropertiesConfig.TCP_TIMEOUT);
435478
routingKeyTypeOverrideFilePath = getValuesFromSystemProperties(PropertiesConfig.SEMANTICS_ROUTINGKEY_TYPE_OVERRIDE_FILEPATH);
479+
username = getValuesFromSystemProperties(PropertiesConfig.USERNAME);
480+
password = decryptString(getValuesFromSystemProperties(PropertiesConfig.PASSWORD));
481+
uri = getValuesFromSystemProperties(PropertiesConfig.URI);
482+
if (!StringUtils.isBlank(uri))
483+
parsedUri = URI.create(uri);
484+
}
485+
486+
private String decryptString(String password) {
487+
if (password == null)
488+
return null;
489+
490+
return new String(Base64.getDecoder().decode(password));
436491
}
437492

438493
private String getValuesFromSystemProperties(String propertyName) {
@@ -443,11 +498,16 @@ private String getValuesFromSystemProperties(String propertyName) {
443498
* This method is used to check mandatory RabbitMQ properties.
444499
*/
445500
private void madatoryParametersCheck() {
446-
if(host == null || exchangeName == null) {
447-
if (Boolean.getBoolean(PropertiesConfig.CLI_MODE)) {
448-
System.err.println("Mandatory RabbitMq properties missing");
449-
System.exit(-1);
450-
}
501+
if (factory == null) {
502+
throw new RuntimeException("Missing RabbitMQ factory intialization");
503+
}
504+
505+
if (StringUtils.isBlank(host) && StringUtils.isBlank(factory.getHost())) {
506+
throw new RuntimeException("Missing host name");
507+
}
508+
509+
if (StringUtils.isBlank(exchangeName)) {
510+
throw new RuntimeException("Missing exchange name");
451511
}
452512
}
453513

publish-common/src/test/java/com/ericsson/eiffel/remrem/publish/helper/RMQHelperUnitTest.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ public class RMQHelperUnitTest {
5555
private static final Long waitForConfirmTimeOut= 5000L;
5656
private String protocol = "eiffelsemantics";
5757
private String createExchange = "true";
58+
private static final String username= "guest";
59+
private static final String password= "Z3Vlc3Q=";
5860

5961
@InjectMocks
6062
RMQHelper rmqHelper;
@@ -106,6 +108,8 @@ private void initProperties() {
106108
System.setProperty(PropertiesConfig.CHANNELS_COUNT, Integer.toString(channelsCount));
107109
System.setProperty(PropertiesConfig.TCP_TIMEOUT, Integer.toString(tcpTimeOut));
108110
System.setProperty(PropertiesConfig.WAIT_FOR_CONFIRMS_TIME_OUT, Long.toString(waitForConfirmTimeOut));
111+
System.setProperty(PropertiesConfig.USERNAME, username);
112+
System.setProperty(PropertiesConfig.PASSWORD, password);
109113
}
110114

111115
private void cleanProperties() {
@@ -122,6 +126,8 @@ private void cleanProperties() {
122126
System.clearProperty(PropertiesConfig.CHANNELS_COUNT);
123127
System.clearProperty(PropertiesConfig.TCP_TIMEOUT);
124128
System.clearProperty(PropertiesConfig.WAIT_FOR_CONFIRMS_TIME_OUT);
129+
System.clearProperty(PropertiesConfig.USERNAME);
130+
System.clearProperty(PropertiesConfig.PASSWORD);
125131
}
126132

127133
@Test public void getHostTest() {
@@ -160,7 +166,7 @@ public void testConnection() throws RemRemPublishException {
160166
}
161167

162168
@Test public void setTlsVersionTest() {
163-
String tlsVersion = "1.1";
169+
String tlsVersion = "1.3";
164170
rabbitmqProtocolProperties.setTlsVer(tlsVersion);
165171
assertTrue(rabbitmqProtocolProperties.getTlsVer().equals(tlsVersion));
166172
}
@@ -181,7 +187,7 @@ public void testConnection() throws RemRemPublishException {
181187
String host = "HOSTC";
182188
Integer portNumber = 1928;
183189
String virtHost = "/eiffel/test2";
184-
String tlsVersion = "1.0";
190+
String tlsVersion = "1.3";
185191
String exchangeNameTest = "EN2";
186192
String usePersistenceTest = "false";
187193
Integer tcpTimeOut = 5000;

publish-service/src/test/java/com/ericsson/eiffel/remrem/publish/service/EventTemplateHandlerTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.junit.Test;
2121
import org.junit.runner.RunWith;
2222
import org.skyscreamer.jsonassert.JSONAssert;
23+
import org.skyscreamer.jsonassert.JSONCompareMode;
2324
import org.slf4j.Logger;
2425
import org.slf4j.LoggerFactory;
2526
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -362,9 +363,10 @@ private void testParser(String EventName) {
362363
JsonNode expectedJson = mapper.readTree(expectedDocument);
363364
JsonNode actualParsedEventJson = eventTemplateHandler.eventTemplateParser(dataToBeParsed, EventName);
364365

365-
LOG.info("expectedJsonString: " + expectedJson.toString());
366+
LOG.info("expectedJsonString: " + expectedJson.toString());
366367
LOG.info("actualParsedEventJson: " + actualParsedEventJson.toString());
367368

369+
JSONAssert.assertEquals(expectedJson.toString(), actualParsedEventJson.toString(), JSONCompareMode.NON_EXTENSIBLE);
368370
JSONAssert.assertEquals(expectedJson.toString(), actualParsedEventJson.toString(), true);
369371

370372
} catch (Exception e) {

wiki/markdown/usage/cli.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,23 @@ usage: java -jar
6161
-tag,--tag <arg> Tag to be used in routing key.
6262
6363
-v,--list_versions Lists the versions of publish and all loaded protocols.
64+
65+
-un,--username <arg> Username to connect to Messagebus
66+
67+
-pwd,--password <arg> Encrypted Password to connect to MessageBus. Plaintext password
68+
should be encrypted using Base64 Encryption Mechanism.
69+
-uri,--uri <uri> URI to message but, see https://www.rabbitmq.com/uri-spec.html.
6470
```
6571

6672
For publish we have input only from file that can contain one or more messages in a JSON array (surrounded with square brackets) separated by comma.
6773

6874
The routing key is generated in the protocol library based on the event type.
6975
To get more information on routing key see [here](https://github.com/eiffel-community/eiffel-remrem-semantics).
7076

77+
URI may contain username, password, etc, see https://www.rabbitmq.com/uri-spec.html for
78+
more details. If other options with the same meaning are provided their values overwrite
79+
values given by option `--uri`, regardless of their order on command line.
80+
7181
## Examples
7282

7383
Typical examples of usage Eiffel REMReM Publish CLI are described below.

0 commit comments

Comments
 (0)