diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..f284e37
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,31 @@
+# Contributing
+
+All Contributions to this repository start with a Jira Item associated with the work request.
+
+## Pull Request Process
+
+1. Fork the repository on you personal github space. see:[working with forks](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/working-with-forks).
+1. [Build](README.md#build) and run the application on your local environment.
+1. Commit your changes to your branch.
+1. Update the README.md with details of changes to the interface, this includes new environment
+ variables, exposed ports, useful file locations and container parameters.
+1. When your change is ready to be reviewed, open a PR on this repository using our [Pull Request Template](.github/PULL_REQUEST_TEMPLATE) and optionally assign one or more reviewer. Also, in the comment of the Jira item, put a link to the Pull Request and move the item to `in review`
+1. If some changes are required, you will be notified in the PR, address any change requested and push to the same branch.
+1. When your change is meeting the requirement, the reviewer will merge the code into master, you can celebrate!
+
+## Open a new bug in jira
+
+- When a bug is detected in the application, a jira bug must be open
+ the bug should be documented as followed:
+ - Expected Behavior
+ - Current Behavior
+ - Steps to Reproduce
+ - Environment
+ - Description (stack traces, screenshot, error messages, splunk logs query)
+ - Optionally you can suggest a possible solution
+ - set the target release
+
+## Open a new feature request in jira
+
+- For feature enhancements, a jira task or story must be open
+ - set the target release
\ No newline at end of file
diff --git a/README.md b/README.md
index 7440790..26deb38 100644
--- a/README.md
+++ b/README.md
@@ -41,6 +41,9 @@ cd bcparis-service
mvn install
```
+## Contributing
+
+Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.
## Run locally
diff --git a/pom.xml b/pom.xml
index c165862..c86a8ae 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
ca.bc.gov.bcparisbcparis-serviceBCPARIS Legacy Migration
- 1.0.19
+ 1.0.20ca.bc.gov.iamp
diff --git a/src/main/java/ca/bc/gov/iamp/bcparis/Keys.java b/src/main/java/ca/bc/gov/iamp/bcparis/Keys.java
new file mode 100644
index 0000000..564e079
--- /dev/null
+++ b/src/main/java/ca/bc/gov/iamp/bcparis/Keys.java
@@ -0,0 +1,25 @@
+package ca.bc.gov.iamp.bcparis;
+
+public class Keys {
+
+ public static final String REQUEST_SCHEMA_FROM_KEY = "FROM";
+ public static final String REQUEST_SCHEMA_TO_KEY = "TO";
+ public static final String REQUEST_SCHEMA_TEXT_KEY = "TEXT";
+ public static final String REQUEST_SCHEMA_RE_KEY = "RE";
+ public static final String REQUEST_SCHEMA_SN_KEY = "SN";
+ public static final String REQUEST_SCHEMA_MT_KEY = "MT";
+ public static final String REQUEST_SCHEMA_MSID_KEY = "MSID";
+ public static final String REQUEST_SCHEMA_SUBJ_KEY = "SUBJ";
+ public static final String REQUEST_SCHEMA_SNME_KEY = "SNME";
+ public static final String REQUEST_SCHEMA_DL_KEY = "DL";
+ public static final String REQUEST_SCHEMA_LIC_KEY = "LIC";
+ public static final String REQUEST_SCHEMA_ODN_KEY = "ODN";
+ public static final String REQUEST_SCHEMA_FLC_KEY = "FLC";
+ public static final String REQUEST_SCHEMA_VIN_KEY = "VIN";
+ public static final String REQUEST_SCHEMA_REG_KEY = "REG";
+ public static final String REQUEST_SCHEMA_RNS_KEY = "RNS";
+ public static final String REQUEST_SCHEMA_RVL_KEY = "RVL";
+ // TODO: REMOVE TOKEN AFTER SATELLITE SERVICE IS DEPRECATED
+ public static final String REQUEST_SCHEMA_TEST_RNS_KEY = "TestRNS";
+
+}
diff --git a/src/main/java/ca/bc/gov/iamp/bcparis/message/MessageUtils.java b/src/main/java/ca/bc/gov/iamp/bcparis/message/MessageUtils.java
new file mode 100644
index 0000000..ac08507
--- /dev/null
+++ b/src/main/java/ca/bc/gov/iamp/bcparis/message/MessageUtils.java
@@ -0,0 +1,115 @@
+package ca.bc.gov.iamp.bcparis.message;
+
+import ca.bc.gov.iamp.bcparis.Keys;
+import org.springframework.util.StringUtils;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class MessageUtils {
+
+ private static final String SEMICOLLON = ":";
+ private static final String STRING_END_ONE = "]]>$";
+ private static final String STRING_END_TWO = "\n$";
+
+ private static HashSet KNOWN_TOKENS = new HashSet() {{
+ add(Keys.REQUEST_SCHEMA_SN_KEY);
+ add(Keys.REQUEST_SCHEMA_MT_KEY);
+ add(Keys.REQUEST_SCHEMA_MSID_KEY);
+ add(Keys.REQUEST_SCHEMA_FROM_KEY);
+ add(Keys.REQUEST_SCHEMA_TO_KEY);
+ add(Keys.REQUEST_SCHEMA_SUBJ_KEY);
+ add(Keys.REQUEST_SCHEMA_TEXT_KEY);
+ add(Keys.REQUEST_SCHEMA_RE_KEY);
+ add(Keys.REQUEST_SCHEMA_SNME_KEY);
+ add(Keys.REQUEST_SCHEMA_DL_KEY);
+ add(Keys.REQUEST_SCHEMA_LIC_KEY);
+ add(Keys.REQUEST_SCHEMA_ODN_KEY);
+ add(Keys.REQUEST_SCHEMA_FLC_KEY);
+ add(Keys.REQUEST_SCHEMA_VIN_KEY);
+ add(Keys.REQUEST_SCHEMA_REG_KEY);
+ add(Keys.REQUEST_SCHEMA_RNS_KEY);
+ add(Keys.REQUEST_SCHEMA_RVL_KEY);
+ add(Keys.REQUEST_SCHEMA_TEST_RNS_KEY);
+ }};
+
+
+ /**
+ * Extract the attribute value based on a give token
+ * Known tokens includes:
+ *
+ *
FROM
+ *
TO
+ *
TEXT
+ *
RE
+ *
SN
+ *
MT
+ *
MSID
+ *
SUBJ
+ *
SNME
+ *
DL
+ *
LIC
+ *
ODN
+ *
FLC
+ *
VIN
+ *
REG
+ *
RNS
+ *
RVL
+ *
TestRNS
+ *
+ *
+ * @param message the source message
+ * @param key a known key
+ * @return the value of the attribute
+ * @throws IllegalArgumentException if the key is not a known key
+ * @since 1.0.20
+ */
+ public static String GetValue(String message, String key) {
+
+ if (!KNOWN_TOKENS.contains(key)) throw new IllegalArgumentException("key must be a known token");
+
+ if (StringUtils.isEmpty(message)) return null;
+
+ message = removeKnownEnd(message);
+
+ message = removeToToken(message, key);
+
+ if (message == null) return null;
+
+ return message.substring(0, getEndIndex(message)).replaceAll("\\s+$", "");
+
+ }
+
+ private static String removeKnownEnd(String message) {
+ message = message.replaceAll(STRING_END_ONE, "");
+ return message.replaceAll(STRING_END_TWO, "");
+ }
+
+ private static String removeToToken(String message, String token) {
+ int startIndex = message.indexOf(token + SEMICOLLON);
+ if (startIndex == -1) return null;
+
+ startIndex += token.length() + 1;
+
+ return message.substring(startIndex);
+ }
+
+ private static int getEndIndex(String message) {
+ int currentEndIndex = message.length();
+
+ for (String token : KNOWN_TOKENS) {
+
+ int tokenIndex = message.indexOf(token + SEMICOLLON);
+
+ if (tokenIndex < currentEndIndex && tokenIndex >= 0) {
+ currentEndIndex = tokenIndex;
+ }
+
+ if (message.indexOf(":") > currentEndIndex) break;
+ }
+
+ return currentEndIndex;
+ }
+}
+
+
diff --git a/src/main/java/ca/bc/gov/iamp/bcparis/processor/datagram/DriverProcessor.java b/src/main/java/ca/bc/gov/iamp/bcparis/processor/datagram/DriverProcessor.java
index bc1b2a9..d6e9bcc 100644
--- a/src/main/java/ca/bc/gov/iamp/bcparis/processor/datagram/DriverProcessor.java
+++ b/src/main/java/ca/bc/gov/iamp/bcparis/processor/datagram/DriverProcessor.java
@@ -35,7 +35,7 @@ public Layer7Message process(Layer7Message message) {
List requests = createIMSContent(message);
if (requests.isEmpty()) {
- message.getEnvelope().getBody().setMsgFFmt(messageService.buildResponse(message.getEnvelope().getBody(), "Unable to parse/formatting error"));
+ message.getEnvelope().getBody().setMsgFFmt(messageService.buildErrorResponse(message.getEnvelope().getBody(), "Unable to parse/formatting error"));
log.warn("Processing Driver: Unable to parse/formatting error");
return message;
}
diff --git a/src/main/java/ca/bc/gov/iamp/bcparis/processor/datagram/VehicleProcessor.java b/src/main/java/ca/bc/gov/iamp/bcparis/processor/datagram/VehicleProcessor.java
index 5d3f03d..c20a746 100644
--- a/src/main/java/ca/bc/gov/iamp/bcparis/processor/datagram/VehicleProcessor.java
+++ b/src/main/java/ca/bc/gov/iamp/bcparis/processor/datagram/VehicleProcessor.java
@@ -37,7 +37,7 @@ public Layer7Message process(Layer7Message message) {
List requests = createIMSContent(message);
if (requests.isEmpty()) {
- message.getEnvelope().getBody().setMsgFFmt(messageService.buildResponse(message.getEnvelope().getBody(), "Unable to parse/formatting error"));
+ message.getEnvelope().getBody().setMsgFFmt(messageService.buildErrorResponse(message.getEnvelope().getBody(), "Unable to parse/formatting error"));
log.warn("Processing Vehicle: Unable to parse/formatting error");
return message;
}
diff --git a/src/main/java/ca/bc/gov/iamp/bcparis/service/MessageService.java b/src/main/java/ca/bc/gov/iamp/bcparis/service/MessageService.java
index ca01665..ab97c87 100644
--- a/src/main/java/ca/bc/gov/iamp/bcparis/service/MessageService.java
+++ b/src/main/java/ca/bc/gov/iamp/bcparis/service/MessageService.java
@@ -1,15 +1,18 @@
package ca.bc.gov.iamp.bcparis.service;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
+import ca.bc.gov.iamp.bcparis.Keys;
+import ca.bc.gov.iamp.bcparis.message.MessageUtils;
import org.springframework.stereotype.Service;
-import ca.bc.gov.iamp.bcparis.exception.message.InvalidMessage;
import ca.bc.gov.iamp.bcparis.model.message.body.Body;
+
@Service
public class MessageService {
@@ -21,6 +24,7 @@ public class MessageService {
"TEXT:${text}${re}" + NEW_LINE +
NEW_LINE +
"${icbc_response}";
+ private final String messageFormat = "SEND MT:M\nFMT:Y\nFROM:{0}\nTO:{1}\nTEXT:{2}{3}\n\n{4}";
public List getQueryAttributesList(Body body, List validAttributes) {
final List result = new ArrayList<>();
@@ -44,7 +48,15 @@ public String buildResponse(final Body body, final String message) {
.replace("${re}", body.containAttribute("RE") ? "RE:" + re : "")
.replace("${icbc_response}", message);
}
-
+
+ public String buildErrorResponse(final Body body, final String errorMessage) {
+ final String receiver = MessageUtils.GetValue(body.getMsgFFmt(),Keys.REQUEST_SCHEMA_FROM_KEY); //This becomes the receiver of the message
+ final String sender = MessageUtils.GetValue(body.getMsgFFmt(),Keys.REQUEST_SCHEMA_TO_KEY); //This will become the sender
+ final String text = MessageUtils.GetValue(body.getMsgFFmt(),Keys.REQUEST_SCHEMA_TEXT_KEY);
+ final String re = MessageUtils.GetValue(body.getMsgFFmt(),Keys.REQUEST_SCHEMA_RE_KEY);
+ return MessageFormat.format(messageFormat, sender, receiver, text,(re != null ? String.format("RE:%s", re):""), errorMessage);
+ }
+
public String escape(String message) {
return message
.replaceAll("&", "&")
diff --git a/src/test/java/ca/bc/gov/iamp/bcparis/FakeCData.java b/src/test/java/ca/bc/gov/iamp/bcparis/FakeCData.java
new file mode 100644
index 0000000..4ae58f8
--- /dev/null
+++ b/src/test/java/ca/bc/gov/iamp/bcparis/FakeCData.java
@@ -0,0 +1,62 @@
+package ca.bc.gov.iamp.bcparis;
+
+public class FakeCData {
+
+ public static String SAMPLE_DRIVER_DL = "";
+ public static String SAMPLE_DRIVER_MULTIPLE_PARAMS = "";
+ public static String SAMPLE_DRIVER_SNME = "";
+ public static String SAMPLE_INVALID_DRIVER = "";
+ public static String SAMPLE_INVALID_VEHICLE = "";
+ public static String SAMPLE_POR = "";
+ public static String SAMPLE_SATELITTE = "";
+ public static String SAMPLE_SATELITTE_ROUND_TRIP = "";
+ public static String SAMPLE_VEHICLE_LIC = "";
+ public static String SAMPLE_VEHICLE_MULTIPLE_PARAMS = "";
+ public static String SAMPLE_VEHICLE_RNS = "";
+ public static String SAMPLE_VEHICLE_RVL = "";
+ public static String SAMPLE_VEHICLE_VIN = "";
+
+}
diff --git a/src/test/java/ca/bc/gov/iamp/bcparis/message/MessageUtilsEdgeCaseGetValueTest.java b/src/test/java/ca/bc/gov/iamp/bcparis/message/MessageUtilsEdgeCaseGetValueTest.java
new file mode 100644
index 0000000..f210bb7
--- /dev/null
+++ b/src/test/java/ca/bc/gov/iamp/bcparis/message/MessageUtilsEdgeCaseGetValueTest.java
@@ -0,0 +1,32 @@
+package ca.bc.gov.iamp.bcparis.message;
+
+import ca.bc.gov.iamp.bcparis.Keys;
+import ca.bc.gov.iamp.bcparis.model.message.body.Body;
+import ca.bc.gov.iamp.bcparis.util.RegexTokenizer;
+import org.junit.Assert;
+import org.junit.Test;
+import java.util.Arrays;
+import java.util.List;
+
+public class MessageUtilsEdgeCaseGetValueTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void WithTokenNotKnownTokenShouldThrowException() {
+ MessageUtils.GetValue("A message", "token");
+ }
+
+
+ @Test
+ public void WithEmptyStringShouldReturnEmptyString() {
+ String result = MessageUtils.GetValue("", Keys.REQUEST_SCHEMA_FROM_KEY);
+ Assert.assertNull(result);
+ }
+
+ @Test
+ public void WithNullStringShouldReturnNullString() {
+ String result = MessageUtils.GetValue(null, Keys.REQUEST_SCHEMA_FROM_KEY);
+ Assert.assertNull(result);
+ }
+
+
+}
diff --git a/src/test/java/ca/bc/gov/iamp/bcparis/message/MessageUtilsGetValueTest.java b/src/test/java/ca/bc/gov/iamp/bcparis/message/MessageUtilsGetValueTest.java
new file mode 100644
index 0000000..314d7d7
--- /dev/null
+++ b/src/test/java/ca/bc/gov/iamp/bcparis/message/MessageUtilsGetValueTest.java
@@ -0,0 +1,309 @@
+package ca.bc.gov.iamp.bcparis.message;
+
+
+import ca.bc.gov.iamp.bcparis.FakeCData;
+import ca.bc.gov.iamp.bcparis.Keys;
+import ca.bc.gov.iamp.bcparis.model.message.body.Body;
+import ca.bc.gov.iamp.bcparis.util.RegexTokenizer;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ErrorCollector;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+@RunWith(Parameterized.class)
+public class MessageUtilsGetValueTest {
+
+ @Rule
+ public ErrorCollector collector = new ErrorCollector();
+
+ @Parameterized.Parameters
+ public static Collection