diff --git a/README.md b/README.md index c464c9a..4c853b6 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ The values `startsAt`, `endsAt` and `generatorURL` will be transmitted to the Al `startsAt` will be set to the point of time when the condition triggered the alert. `endsAt` will be set to the point of time when the condition triggered the alert plus the set grace time which is configured for the alert. +Additionally you can configure your own custom annotations and labels which should be submitted to the AlertManager (see screenshot below). + ## How to deploy on Graylog You can easily build the plugin by executing `./gradlew build`. Afterwards there should be a `.jar` file inside the `build/libs/` directory. @@ -37,9 +39,6 @@ Follow the instructions mentioned [here](http://docs.graylog.org/en/2.4/pages/pl ![Configuration of Callback](images/New_AlertManager_Callback_Window.png) ## Planned Features -* Add possibility to define custom labels in UI when configuring the callback -* Add possibility to define custom annotations in UI when configuring the callback - You would like to contribute anything? - Take a look at [CONTRIBUTING.md](CONTRIBUTING.md). ## Known Issues diff --git a/images/New_AlertManager_Callback_Window.png b/images/New_AlertManager_Callback_Window.png index 38f214c..a3e1300 100644 Binary files a/images/New_AlertManager_Callback_Window.png and b/images/New_AlertManager_Callback_Window.png differ diff --git a/src/main/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerAlarmCallback.java b/src/main/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerAlarmCallback.java index 47ddd55..414fdd4 100644 --- a/src/main/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerAlarmCallback.java +++ b/src/main/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerAlarmCallback.java @@ -12,19 +12,25 @@ import org.graylog2.plugin.configuration.fields.TextField; import org.graylog2.plugin.streams.Stream; +import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.Map; public class AlertManagerAlarmCallback implements AlarmCallback { + static final String CONFIGURATION_KEY_API_URL = "alertmanager_api_url"; + static final String CONFIGURATION_KEY_ALERT_NAME = "alertmanager_alert_name"; + static final String CONFIGURATION_KEY_CUSTOM_LABELS = "alertmanager_custom_labels"; + static final String CONFIGURATION_KEY_CUSTOM_ANNOTATIONS = "alertmanager_custom_annotations"; + private Configuration configuration; private AlertManagerPostRequestSender alertManagerPostRequestSender; @Override public void initialize(Configuration config) throws AlarmCallbackConfigurationException { configuration = config; - alertManagerPostRequestSender = new AlertManagerPostRequestSender(config.getString("alertmanager_api_url")); + alertManagerPostRequestSender = new AlertManagerPostRequestSender(config.getString(CONFIGURATION_KEY_API_URL)); } @Override @@ -44,7 +50,7 @@ public ConfigurationRequest getRequestedConfiguration() { // API URL ConfigurationField alertmanagerApiUrl = new TextField( - "alertmanager_api_url", + CONFIGURATION_KEY_API_URL, "AlertManager API URL", "http://localhost:9093/api/v1/alerts", "This callback sends a POST-Request to an AlertManager API. It converts the information into a format which is readable by the AlertManager.", @@ -54,7 +60,7 @@ public ConfigurationRequest getRequestedConfiguration() { // Alert Name ConfigurationField alertName = new TextField( - "alertmanager_alert_name", + CONFIGURATION_KEY_ALERT_NAME, "AlertManager Alert Name", "TestAlert", "The name for the specific AlertManager alert (will be transmitted as 'alertname'-label).", @@ -62,6 +68,26 @@ public ConfigurationRequest getRequestedConfiguration() { ); configurationRequest.addField(alertName); + // Custom labels + ConfigurationField customLabels = new TextField( + CONFIGURATION_KEY_CUSTOM_LABELS, + "Custom AlertManager labels", + "", + "The custom AlertManager label key-value-pairs separated by '" + CustomPropertiesTextFieldParser.KEY_VALUE_PAIR_SEPARATOR + "' to set for each alert. Please use the following notation: 'label1=value1" + CustomPropertiesTextFieldParser.KEY_VALUE_PAIR_SEPARATOR + "label2=value2'", + Optional.OPTIONAL + ); + configurationRequest.addField(customLabels); + + // Custom annotations + ConfigurationField customAnnotations = new TextField( + CONFIGURATION_KEY_CUSTOM_ANNOTATIONS, + "Custom AlertManager annotations", + "", + "The custom AlertManager annotation key-value-pairs separated by '" + CustomPropertiesTextFieldParser.KEY_VALUE_PAIR_SEPARATOR + "' to set for each alert. Please use the following notation: 'annotation1=value1" + CustomPropertiesTextFieldParser.KEY_VALUE_PAIR_SEPARATOR + "annotation2=value2'", + Optional.OPTIONAL + ); + configurationRequest.addField(customAnnotations); + return configurationRequest; } @@ -77,14 +103,34 @@ public Map getAttributes() { @Override public void checkConfiguration() throws ConfigurationException { - String apiUrl = configuration.getString("alertmanager_api_url"); + final String apiUrl = configuration.getString(CONFIGURATION_KEY_API_URL); if (apiUrl == null) { throw new ConfigurationException("AlertManager API URL has to be set."); } + try { new URI(apiUrl); } catch (URISyntaxException e) { throw new ConfigurationException("The URL: '" + apiUrl + "' is not a valid URL. " + e.getMessage()); } + + + CustomPropertiesTextFieldParser customPropertiesTextFieldParser = new CustomPropertiesTextFieldParser(); + + final String customLabels = configuration.getString(CONFIGURATION_KEY_CUSTOM_LABELS); + try { + customPropertiesTextFieldParser.extractKeyValuePairsFromCustomField(customLabels); + } catch (IOException e) { + // Not a valid configuration for custom labels + throw new ConfigurationException("The format for given custom labels is invalid. " + e.getMessage()); + } + + final String customAnnotations = configuration.getString(CONFIGURATION_KEY_CUSTOM_ANNOTATIONS); + try { + customPropertiesTextFieldParser.extractKeyValuePairsFromCustomField(customAnnotations); + } catch (IOException e) { + // Not a valid configuration for custom labels + throw new ConfigurationException("The format for given custom annotations is invalid. " + e.getMessage()); + } } } diff --git a/src/main/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerPayloadBuilder.java b/src/main/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerPayloadBuilder.java index 25ad08d..c00b9b0 100644 --- a/src/main/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerPayloadBuilder.java +++ b/src/main/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerPayloadBuilder.java @@ -5,20 +5,22 @@ import org.graylog2.plugin.streams.Stream; import org.joda.time.DateTime; +import java.io.IOException; import java.util.HashMap; import java.util.Map; class AlertManagerPayloadBuilder { - private static final String STREAM_TITLE_KEY = "stream_title"; - private static final String ALERTMANAGER_ALERT_NAME_KEY = "alertmanager_alert_name"; private static final String ALERTNAME_KEY = "alertname"; + private Stream stream; private AlertCondition.CheckResult checkResult; private Configuration configuration; + private CustomPropertiesTextFieldParser customPropertiesTextFieldParser; private AlertManagerPayloadBuilder() { // Private constructor to hide the implicit one + customPropertiesTextFieldParser = new CustomPropertiesTextFieldParser(); } static AlertManagerPayloadBuilder newInstance() { @@ -56,12 +58,20 @@ AlertManagerPayload build() { private Map extractLabels() { Map labels = new HashMap<>(); - if(configuration != null && configuration.getString(ALERTMANAGER_ALERT_NAME_KEY) != null) { - labels.put(ALERTNAME_KEY, configuration.getString(ALERTMANAGER_ALERT_NAME_KEY)); + if(configuration != null && configuration.getString(AlertManagerAlarmCallback.CONFIGURATION_KEY_ALERT_NAME) != null) { + labels.put(ALERTNAME_KEY, configuration.getString(AlertManagerAlarmCallback.CONFIGURATION_KEY_ALERT_NAME)); } else { labels.put(ALERTNAME_KEY, "Please add a valid configuration object to AlertManager plugin."); } + // custom labels + final String customLabelString = configuration != null ? configuration.getString(AlertManagerAlarmCallback.CONFIGURATION_KEY_CUSTOM_LABELS) : null; + try { + labels.putAll(customPropertiesTextFieldParser.extractKeyValuePairsFromCustomField(customLabelString)); + } catch (IOException e) { + // damaged configuration, so we'll not put any additional label into the map + } + return labels; } @@ -69,7 +79,7 @@ private Map extractAnnotations() { Map annotations = new HashMap<>(); if(stream != null && stream.getTitle() != null) { - annotations.put(STREAM_TITLE_KEY, stream.getTitle()); + annotations.put("stream_title", stream.getTitle()); } if(checkResult != null) { @@ -80,6 +90,14 @@ private Map extractAnnotations() { } } + // custom annotations + final String customAnnotationString = configuration != null ? configuration.getString(AlertManagerAlarmCallback.CONFIGURATION_KEY_CUSTOM_ANNOTATIONS) : null; + try { + annotations.putAll(customPropertiesTextFieldParser.extractKeyValuePairsFromCustomField(customAnnotationString)); + } catch (IOException e) { + // damaged configuration, so we'll not put any additional annotation into the map + } + return annotations; } diff --git a/src/main/java/de/gdata/mobilelab/alertmanagercallback/CustomPropertiesTextFieldParser.java b/src/main/java/de/gdata/mobilelab/alertmanagercallback/CustomPropertiesTextFieldParser.java new file mode 100644 index 0000000..8f207b1 --- /dev/null +++ b/src/main/java/de/gdata/mobilelab/alertmanagercallback/CustomPropertiesTextFieldParser.java @@ -0,0 +1,47 @@ +package de.gdata.mobilelab.alertmanagercallback; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * This parser can parse key-value-pairs from a text field string. + * It uses {@link #KEY_VALUE_PAIR_SEPARATOR} for separating each key-value-pair. + * The keys and related values will be parsed using {@link Properties#load(InputStream)}. + */ +class CustomPropertiesTextFieldParser { + + /** The separator used in text field to split between key-value-pairs. */ + static final String KEY_VALUE_PAIR_SEPARATOR = ";"; + + /** The separator used by {@link Properties#load(InputStream)} for key-value-pair separation. */ + private static final String PROPERTIES_KEY_VALUE_PAIR_SEPARATOR = "\n"; + + /** + * Parses the text field value with custom key-value-pairs into a map.
+ * It uses the {@link #KEY_VALUE_PAIR_SEPARATOR} for the line separation. This separation is required + * for loading the key-value-pairs using {@link Properties#load(InputStream)}. + * + * @param textFieldValue the text field value + * @return the map with key-value-pairs from text field + * @throws IOException if parsing the key-value-pairs fails + */ + Map extractKeyValuePairsFromCustomField(String textFieldValue) throws IOException { + Map extractedPairs = new HashMap<>(); + + if (textFieldValue != null && !"".equals(textFieldValue)) { + final String preparedTextFieldValue = textFieldValue.replaceAll(KEY_VALUE_PAIR_SEPARATOR, PROPERTIES_KEY_VALUE_PAIR_SEPARATOR); + Properties properties = new Properties(); + InputStream stringInputStream = new ByteArrayInputStream(preparedTextFieldValue.getBytes(StandardCharsets.UTF_8)); + properties.load(stringInputStream); + properties.forEach((key, value) -> extractedPairs.put((String) key, value)); + } + + return extractedPairs; + } + +} diff --git a/src/test/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerAlarmCallbackTest.java b/src/test/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerAlarmCallbackTest.java index e5acea0..67ed08c 100644 --- a/src/test/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerAlarmCallbackTest.java +++ b/src/test/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerAlarmCallbackTest.java @@ -51,7 +51,7 @@ public void getRequestedConfiguration() { ConfigurationRequest configurationRequest = alertManagerAlarmCallback.getRequestedConfiguration(); // then: text fields have been set - assertEquals(2, configurationRequest.getFields().size()); + assertEquals(4, configurationRequest.getFields().size()); ConfigurationField field = configurationRequest.getField("alertmanager_api_url"); assertNotNull(field); @@ -69,6 +69,22 @@ public void getRequestedConfiguration() { assertEquals("TestAlert", field.getDefaultValue()); assertEquals("The name for the specific AlertManager alert (will be transmitted as 'alertname'-label).", field.getDescription()); assertEquals(ConfigurationField.Optional.NOT_OPTIONAL, field.isOptional()); + + field = configurationRequest.getField("alertmanager_custom_labels"); + assertNotNull(field); + assertEquals(TextField.FIELD_TYPE, field.getFieldType()); + assertEquals("Custom AlertManager labels", field.getHumanName()); + assertEquals("", field.getDefaultValue()); + assertEquals("The custom AlertManager label key-value-pairs separated by '" + CustomPropertiesTextFieldParser.KEY_VALUE_PAIR_SEPARATOR + "' to set for each alert. Please use the following notation: 'label1=value1" + CustomPropertiesTextFieldParser.KEY_VALUE_PAIR_SEPARATOR + "label2=value2'", field.getDescription()); + assertEquals(ConfigurationField.Optional.OPTIONAL, field.isOptional()); + + field = configurationRequest.getField("alertmanager_custom_annotations"); + assertNotNull(field); + assertEquals(TextField.FIELD_TYPE, field.getFieldType()); + assertEquals("Custom AlertManager annotations", field.getHumanName()); + assertEquals("", field.getDefaultValue()); + assertEquals("The custom AlertManager annotation key-value-pairs separated by '" + CustomPropertiesTextFieldParser.KEY_VALUE_PAIR_SEPARATOR + "' to set for each alert. Please use the following notation: 'annotation1=value1" + CustomPropertiesTextFieldParser.KEY_VALUE_PAIR_SEPARATOR + "annotation2=value2'", field.getDescription()); + assertEquals(ConfigurationField.Optional.OPTIONAL, field.isOptional()); } @Test diff --git a/src/test/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerPayloadBuilderTest.java b/src/test/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerPayloadBuilderTest.java index 68626bd..7700842 100644 --- a/src/test/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerPayloadBuilderTest.java +++ b/src/test/java/de/gdata/mobilelab/alertmanagercallback/AlertManagerPayloadBuilderTest.java @@ -105,6 +105,8 @@ public void buildWithFullInformation() { // given: configuration mock Configuration configuration = mock(Configuration.class); when(configuration.getString("alertmanager_alert_name")).thenReturn("AlertName"); + when(configuration.getString("alertmanager_custom_annotations")).thenReturn("environment: production;system=webapp;priority=major"); + when(configuration.getString("alertmanager_custom_labels")).thenReturn("environmentlabel: productionlabel;systemlabel=webapplabel;prioritylabel=majorlabel"); // and: stream mock Stream stream = mock(Stream.class); @@ -133,12 +135,18 @@ public void buildWithFullInformation() { // expect: correct values set // - labels assertEquals("AlertName", alertManagerPayload.getLabels().get("alertname")); + assertEquals("productionlabel", alertManagerPayload.getLabels().get("environmentlabel")); + assertEquals("webapplabel", alertManagerPayload.getLabels().get("systemlabel")); + assertEquals("majorlabel", alertManagerPayload.getLabels().get("prioritylabel")); // - annotations assertEquals("StreamTitle", alertManagerPayload.getAnnotations().get("stream_title")); assertEquals(triggeredAt.toString(), alertManagerPayload.getAnnotations().get("triggered_at")); assertEquals("aDescription", alertManagerPayload.getAnnotations().get("triggered_rule_description")); assertEquals("aTitle", alertManagerPayload.getAnnotations().get("triggered_rule_title")); + assertEquals("production", alertManagerPayload.getAnnotations().get("environment")); + assertEquals("webapp", alertManagerPayload.getAnnotations().get("system")); + assertEquals("major", alertManagerPayload.getAnnotations().get("priority")); // - startsAt assertEquals(triggeredAt.toString(), alertManagerPayload.getStartsAt()); @@ -269,4 +277,199 @@ public void buildWithNoInformationForStreamUrlParameters() { // - generatorUrl assertNull(alertManagerPayload.getGeneratorURL()); } + + @Test + public void buildWithCustomLabels() { + // given: configuration mock + Configuration configuration = mock(Configuration.class); + when(configuration.getString("alertmanager_alert_name")).thenReturn("Test234"); + when(configuration.getString("alertmanager_custom_labels")).thenReturn("environment: production;system=webapp;priority=major"); + + + // and: instance with set mocks as values + AlertManagerPayload alertManagerPayload = AlertManagerPayloadBuilder.newInstance() + .withConfiguration(configuration) + .build(); + + // expect: correct values set + // - labels + assertEquals("Test234", alertManagerPayload.getLabels().get("alertname")); + assertEquals("production", alertManagerPayload.getLabels().get("environment")); + assertEquals("webapp", alertManagerPayload.getLabels().get("system")); + assertEquals("major", alertManagerPayload.getLabels().get("priority")); + assertEquals(4, alertManagerPayload.getLabels().size()); + } + + @Test + public void buildWithoutCustomLabels() { + // given: configuration mock + Configuration configuration = mock(Configuration.class); + when(configuration.getString("alertmanager_alert_name")).thenReturn("Test234"); + when(configuration.getString("alertmanager_custom_labels")).thenReturn(""); + + + // and: instance with set mocks as values + AlertManagerPayload alertManagerPayload = AlertManagerPayloadBuilder.newInstance() + .withConfiguration(configuration) + .build(); + + // expect: correct values set + // - labels + assertEquals("Test234", alertManagerPayload.getLabels().get("alertname")); + assertEquals(1, alertManagerPayload.getLabels().size()); + } + + @Test + public void buildWithOneCustomLabel() { + // given: configuration mock + Configuration configuration = mock(Configuration.class); + when(configuration.getString("alertmanager_alert_name")).thenReturn("Test234"); + when(configuration.getString("alertmanager_custom_labels")).thenReturn("level: critical"); + + + // and: instance with set mocks as values + AlertManagerPayload alertManagerPayload = AlertManagerPayloadBuilder.newInstance() + .withConfiguration(configuration) + .build(); + + // expect: correct values set + // - labels + assertEquals("Test234", alertManagerPayload.getLabels().get("alertname")); + assertEquals("critical", alertManagerPayload.getLabels().get("level")); + assertEquals(2, alertManagerPayload.getLabels().size()); + } + + @Test + public void buildWithStrangeNotatedCustomLabels() { + // given: configuration mock + Configuration configuration = mock(Configuration.class); + when(configuration.getString("alertmanager_alert_name")).thenReturn("Test234"); + when(configuration.getString("alertmanager_custom_labels")).thenReturn(";level;;;system=production=staging;;"); + + + // and: instance with set mocks as values + AlertManagerPayload alertManagerPayload = AlertManagerPayloadBuilder.newInstance() + .withConfiguration(configuration) + .build(); + + // expect: correct values set + // - labels + assertEquals("Test234", alertManagerPayload.getLabels().get("alertname")); + assertEquals("", alertManagerPayload.getLabels().get("level")); + assertEquals("production=staging", alertManagerPayload.getLabels().get("system")); + assertEquals(3, alertManagerPayload.getLabels().size()); + } + + @Test + public void buildWithCustomAnnotations() { + // given: configuration mock + Configuration configuration = mock(Configuration.class); + when(configuration.getString("alertmanager_custom_annotations")).thenReturn("environment: production;system=webapp;priority=major"); + + + // and: instance with set mocks as values + AlertManagerPayload alertManagerPayload = AlertManagerPayloadBuilder.newInstance() + .withConfiguration(configuration) + .build(); + + // expect: correct values set + // - annotations + assertEquals("production", alertManagerPayload.getAnnotations().get("environment")); + assertEquals("webapp", alertManagerPayload.getAnnotations().get("system")); + assertEquals("major", alertManagerPayload.getAnnotations().get("priority")); + assertEquals(3, alertManagerPayload.getAnnotations().size()); + } + + @Test + public void buildWithCustomAnnotationsInAdditionToDefaultOnes() { + // given: configuration mock + Configuration configuration = mock(Configuration.class); + when(configuration.getString("alertmanager_custom_annotations")).thenReturn("environment: production;system=webapp;priority=major"); + + // and: stream mock + Stream stream = mock(Stream.class); + when(stream.getTitle()).thenReturn("StreamTitle"); + + // and: checkResult mock + AlertCondition.CheckResult checkResult = mock(AlertCondition.CheckResult.class); + DateTime triggeredAt = new DateTime(); + when(checkResult.getTriggeredAt()).thenReturn(triggeredAt); + AlertCondition alertCondition = mock(AlertCondition.class); + when(alertCondition.getDescription()).thenReturn("aDescription"); + when(alertCondition.getTitle()).thenReturn("aTitle"); + when(checkResult.getTriggeredCondition()).thenReturn(alertCondition); + + + // and: instance with set mocks as values + AlertManagerPayload alertManagerPayload = AlertManagerPayloadBuilder.newInstance() + .withConfiguration(configuration) + .withStream(stream) + .withCheckResult(checkResult) + .build(); + + // expect: correct values set + // - annotations + assertEquals("production", alertManagerPayload.getAnnotations().get("environment")); + assertEquals("webapp", alertManagerPayload.getAnnotations().get("system")); + assertEquals("major", alertManagerPayload.getAnnotations().get("priority")); + assertEquals("StreamTitle", alertManagerPayload.getAnnotations().get("stream_title")); + assertEquals(triggeredAt.toString(), alertManagerPayload.getAnnotations().get("triggered_at")); + assertEquals("aDescription", alertManagerPayload.getAnnotations().get("triggered_rule_description")); + assertEquals("aTitle", alertManagerPayload.getAnnotations().get("triggered_rule_title")); + assertEquals(7, alertManagerPayload.getAnnotations().size()); + } + + @Test + public void buildWithoutCustomAnnotations() { + // given: configuration mock + Configuration configuration = mock(Configuration.class); + when(configuration.getString("alertmanager_custom_annotations")).thenReturn(""); + + + // and: instance with set mocks as values + AlertManagerPayload alertManagerPayload = AlertManagerPayloadBuilder.newInstance() + .withConfiguration(configuration) + .build(); + + // expect: correct values set + // - annotations + assertEquals(0, alertManagerPayload.getAnnotations().size()); + } + + @Test + public void buildWithOneCustomAnnotation() { + // given: configuration mock + Configuration configuration = mock(Configuration.class); + when(configuration.getString("alertmanager_custom_annotations")).thenReturn("level: critical"); + + + // and: instance with set mocks as values + AlertManagerPayload alertManagerPayload = AlertManagerPayloadBuilder.newInstance() + .withConfiguration(configuration) + .build(); + + // expect: correct values set + // - annotations + assertEquals("critical", alertManagerPayload.getAnnotations().get("level")); + assertEquals(1, alertManagerPayload.getAnnotations().size()); + } + + @Test + public void buildWithStrangeNotatedCustomAnnotations() { + // given: configuration mock + Configuration configuration = mock(Configuration.class); + when(configuration.getString("alertmanager_custom_annotations")).thenReturn(";level;;;system=production=staging;;"); + + + // and: instance with set mocks as values + AlertManagerPayload alertManagerPayload = AlertManagerPayloadBuilder.newInstance() + .withConfiguration(configuration) + .build(); + + // expect: correct values set + // - annotations + assertEquals("", alertManagerPayload.getAnnotations().get("level")); + assertEquals("production=staging", alertManagerPayload.getAnnotations().get("system")); + assertEquals(2, alertManagerPayload.getAnnotations().size()); + } } \ No newline at end of file diff --git a/src/test/java/de/gdata/mobilelab/alertmanagercallback/CustomPropertiesTextFieldParserTest.java b/src/test/java/de/gdata/mobilelab/alertmanagercallback/CustomPropertiesTextFieldParserTest.java new file mode 100644 index 0000000..1badc0b --- /dev/null +++ b/src/test/java/de/gdata/mobilelab/alertmanagercallback/CustomPropertiesTextFieldParserTest.java @@ -0,0 +1,33 @@ +package de.gdata.mobilelab.alertmanagercallback; + +import org.junit.Test; + +import java.io.IOException; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class CustomPropertiesTextFieldParserTest { + + @Test + public void constructor() { + assertNotNull(new CustomPropertiesTextFieldParser()); + } + + @Test + public void extractKeyValuePairsFromCustomField() throws IOException { + // given: instance + CustomPropertiesTextFieldParser customPropertiesTextFieldParser = new CustomPropertiesTextFieldParser(); + + // when: parsing key-value-pairs from custom string + Map extractedPairs = customPropertiesTextFieldParser.extractKeyValuePairsFromCustomField(";key3;;key1: value1;key2=value2;;"); + + // then: values should have been set + assertEquals(3, extractedPairs.size()); + assertEquals("value1", extractedPairs.get("key1")); + assertEquals("value2", extractedPairs.get("key2")); + assertEquals("", extractedPairs.get("key3")); + } + +} \ No newline at end of file