- Table of Contents
- Pre-Requisites
- Running tests
- How to Deploy
- History
- OpenJDK 17
- Maven (No specific version)
- MyMove PreReqs
This repository relies on the Transcom mymove repository. This means that tests require a connection to that repositories docker containers. Please see the following steps:
- Have two open terminal windows, one for this repository and another for the mymove repository
cd
into the mymove repository in your second window- If you haven't already, run
direnv allow
- Run
make server_test_setup
to configure your docker container - For more documentation on this, please see mymove docs here
- If you haven't already, run
- Open Docker Desktop and confirm that the
milmove-db-test
container is up and running - Change back to your first terminal window for this repository
- Run
mvn test
This section of the README is dedicated to the past history of this repository. It will provide a high-level of the previous version of this repository which was to serve as an API gateway from Transcom's MyMove to Transcom Relational Database Management's (TRDM) servers. This approach was abandoned and switched to a cron job for the sake of time sensitivity and a vastly already out-of-scope feature approach. It can be previewed via the git history prior to release v1.0.0.0
. The release and its changelog can be found here. There are still some deprecated files remaining within this repository.
This lambda function as of version 1 received an overhaul to function as a cron based lambda function invoked via a timer.
It has the complete capability of providing a REST to SOAP conversion service. This can be of use in the future when other services may need to interface through us. It currently is running as spring boot application which is not necessarily needed for a cron job, but due to time sensitivity it was not phased out when overhauling. It does still offer the future ability to turn back on the RESTful aspects to provide said conversion service, but as of right now it is disabled.
Please see documentation here.
We are leveraging the ReturnTableV7
WSDL provided by TRDM. This file has been verified to be unclassified in its entirety, holding no sensitive information and cleared to release into our open source repository by their administrators.
Please refer to the code generation section as to how this WSDL is so important for our function.
Read about which tables we are allowed to access here.
See information about the truststore here.
It is very important to understand the backbone of the SOAP envelope generation. By using the cxf-codegen-plugin
we can provide a WSDL and it will auto generate us code under target
that can be used to generate SOAP envelopes.
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>4.0.3</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${project.basedir}/src/main/resources/ReturnTableV7.wsdl</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
We have found that CI/CD does not work well when using Apache CXF code generation. The plugin generates code at build time, and since CircleCI handles our actual build and release this means that it will be generated within CircleCI. This is normally not a problem and actually a good thing; however, this plugin makes hard coded file references to the file system directories it was built inside of. So, when CircleCI builds it and releases it the code will have hard coded file references to the WSDL such as (Exaggeration) CircleCI/resources/
, meaning when deployed in AWS it will always fail. So, the way around that is to generate it locally, modify it as necessary, and store it within GitHub. This is why you can find the ReturnTableV7 code generated with that plugin added to our src manually here.
After the code was generated and plugged into src
, we had to manually modify the WSDL references. See examples when you search that directory and sub directories for classpath:ReturnTableV7.wsdl
- before these were class paths they were file references with hard coded CircleCI values - hence why when it was hosted into AWS Lambda it couldn't find the CircleCI directories.
Additionally, the following static code was needed to grab the WSDL for the class.
static {
URL url = ReturnTable.class.getClassLoader().getResource("ReturnTableV7.wsdl");
if (url == null) {
java.util.logging.Logger.getLogger(ReturnTable.class.getName())
.log(java.util.logging.Level.INFO,
"Can not initialize the default wsdl from {0}", "classpath:ReturnTableV7.wsdl");
}
WSDL_LOCATION = url;
}
In short, we generated the code with that plugin, imported it into the repository, and manually modified the WSDL file refs to be based on the classpath. Additionally, the imports within the services had to be imported like so:
import cxf.trdm.returntableservice.ReturnTable;
Instead of relying on the target that gets auto generated with the plugin.
Provides a serverless Java application to host an internal RESTful interface. This Java application will handle SOAP-based requests toward TRDM on behalf of our Go MilMove server. It will be hosted as an AWS Lambda function for MilMove API requests to TRDM via SOAP.
The application.yml
can store configurations for your env variables. Which includes both secrets and configs.
To add a new variable simply add it to the application.yml
following the yaml syntax. Then create a new Java class under the config
package.
If there is a prefix for the config, make sure to add it. Then add all the properties related to the config in this file.
Java will read my-prop
as myProp
by default so if you use -
just follow camel case standards when naming your variables in Java.
In the resources
directory you will find multiple different yaml files. The default is application.yml
. Every other yaml file is environment specific.
Ex:
- application-stg.yml
- application-prod.yml
If each env requires a different configuration create a new yaml file following the pattern application-env.yml
where env is the name of your environment. (stg, prod, test, etc).
This application utilizes several core Spring Features.
- Custom Validation for a request body using
Meta Annotations
- Controller Advice to handle errors globally
- Bean represenation of env variables
For the request objects there is some validation that occurs before the application processes it.
In LastTableUpdateRequest
for ex, you will find the annotation @PhysicalNameConstraint
. This lets spring know that this field is constrained by the PhysicalNameConstraint
interface. In this class you will also see PhysicalNameValidator
. This is where the actual logic is placed. You can customize this logic however you see fit.
How to apply the custom validation:
- Create a Constraint.java class
- Create a Validator.java class
- Apply constraint annotation to the field you wish to validate.
The controller advice is called ErrorHandler
in the project.
This class can be used as the global generic error handler for simple errors such as validation, internal server errors, or other common error responses. If you wish to have more specific errors you can have the service
classes throw a custom error and create a new controller advice to handle those specific errors from the service. Just follow how the other methods in ErrorHandler
are setup to manage the errors.
When adding custom properties to the application you can add them directly the the application.yml. (Make sure you add them to the other application-env.yml as well)
Then if you plan on reading them into the application create a CustomPropProps.java
class to handle the custom props you are loading in.