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 first step is to download and install AWS CLI and then AWS SAM CLI.
Let’s run AWS SAM CLI on the path where the template.yaml is located and execute the command:
To build the application run sam build
from the root directory or in the same directory as the template.yml
file.
To run the application locally run sam local start-api
. It will require AWS credentials to turn on, so either you need /.aws/credentials
or if using
aws-vault to manage your credentials you need to wrap your start command like so: aws-vault exec transcom-gov-dev -- sam local start-api
.
To deploy the application to AWS, download the latest release, upload it into the bucket under lambda builds -> trdm-soap-proxy -> Make a new version folder -> upload with proper encryption keys set.
After it has been uploaded into the bucket please update the trdm_soap_proxy_version
variable in terraform here under variables.tf
.
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.