ℹ️
|
This repository is a thin demonstrative wrapper around the Core container library, for more in depth documentation of available features and config options see the core library’s readme. |
-
Maven
-
NodeJS/NPM
-
Github credentials providing access to VEuPathDB packages
Environment/dependency setup for local development can be done via the command
make install-dev-env
. This will install the dependencies required to build the
project.
After the environment has been set up, the project can be built, tested, and
packaged using make jar
.
Starting the server can be done by running java -jar build/libs/service.jar
.
|
Most projects will require some CLI or environment arguments to run. For a full listing of available options see the core container library documentation. |
ℹ️
|
All project specific system level dependencies must be installed locally for this to work. |
The project container can be built using make docker
. The first build
of the container will take several minutes.
Running the built container can be done with:
$ docker-compose -f docker/docker-compose.dev.yml up
|
Most projects will require some CLI or environment arguments to run. For a full
listing of available options see the
core container library
documentation. When using docker-compose these options can be
set automatically
through the use of a |
-
Create a new project from this template by clicking the "Use this template" button above.
-
Clone your new project and cd into the clone directory
-
Run
make new-project-initialization
This will:-
Link your new project’s git history with the git history of this template repo which will enable the ability to pull fixes and updates from this template into your new project.
-
Install the dev tools needed to build and test your project.
-
-
Edit
build.gradle.kts
with your service’s details -
Edit
api.raml
with your API design -
Create any necessary types in
docs/schema
-
Run
make gen-jaxrs
to generate skeleton code -
Further rename and edit the Java packages and source code under
src/
as desired -
Implement the generated service interfaces
-
Register your services in the
Resources
class -
Run
make test
to run any unit tests and verify that things compile
-
Clone this project and cd into the clone directory
-
Run
make link-template-repo
This will link your currently checked out project back up to the template repo which will enable the ability to pull in fixes and updates published to that template. -
Run
make install-dev-env
This will install the dev tools needed to build and test the project. -
Edit
build.gradle.kts
with your service’s details -
Edit
api.raml
with your API design -
Create any necessary types in
docs/schema
-
Run
make gen-jaxrs
to generate skeleton code -
Further rename and edit the Java packages and source code under
src/
as desired -
Implement the generated service interfaces
-
Register your services in the
Resources
class -
Run
make test
to run any unit tests and verify that things compile
- NPM
-
Required to run raml2html
- Maven
-
Required to build raml-to-jaxrs
Configuration for the build is primarily done through the build.gradle.kts
file. Here you can configure the project’s name, version, container name,
Java package structure, etc. as well as define your project’s dependencies.
For information about adding gradle dependency declarations see the Gradle docs.
The service api is defined in 2 places initially:
In the api.raml
file, there is a statement near the top of the file that
declares the Raml file "uses" schema/library.raml
. This is a generated
file based on the contents of the schema library under schema
. The
library.raml
file should not be edited directly.
api.raml
: uses
declarationuses:
err: .tools/raml/errors.raml
lib: schema/library.raml
The uses
keyword maps an import alias to the imported library. This import
alias is used to access the types defined in that library. In the case of the
above example, library types would be available using lib.{MyTypeName}
api.raml
: Library type usage. body:
application/json:
type: lib.HelloResponse
Each raml library file under schema
should define a root types
object
defining the types used by the API. The name of the types defined under the
types
object will be the name of the generated Java classes based on those
types.
#%RAML 1.0 Library
types:
MyType:
properties:
foo: string
package org.veupathdb.service.demo.generated.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@JsonDeserialize(
as = HealthResponseImpl.class
)
public interface MyType {
@JsonProperty("foo")
String getFoo();
@JsonProperty("foo")
void setFoo(String foo);
}
package org.veupathdb.service.demo.generated.model;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"foo",
})
public class HealthResponseImpl implements HealthResponse {
@JsonProperty("foo")
private String foo;
@JsonProperty("foo")
public String getFoo() {
return this.foo;
}
@JsonProperty("foo")
public void setFoo(String foo) {
this.foo = foo;
}
}
Once your API spec is complete, you can begin development of Java code by
running make gen-jaxrs
. This will create a skeleton of the API in the
generated
source package located under the root package defined using the
projectPackage
value in build.gradle.kts
.
The generated interfaces and types have the basic necessary annotations for use by both Jackson and Jersey.
Once you have implemented the interfaces defined under
{source-package}.generated.resources
they must be registered in the
{source-package}.Resources
class.
Running your service locally can be done by following the same steps as defined above in the Running the Example section:
-
Run
make jar
-
Run
java -jar build/libs/service.jar
Running in Docker can be done by:
-
Run
make build-docker
-
Run
docker run <your-image-name>
The base service contains an authentication layer that will be enabled on any
service class or method annotated with @Authenticated
. This authentication
will validate a VEuPathDB user session against the configured account- (for
registered users) and user- (for guest users) databases and append user
profile information to the incoming request object.
help
-
-
Lists the available make targets.
This is the default target that will be executed if you just runmake
.
-
new-project-initialization
-
-
Runs the make target
link-template-repo
-
Merges the git history of a new template-based project with the git history of template that the project was based on.
-
Runs the make target
install-dev-env
-
link-template-repo
-
-
Links the currently cloned repository back up to the template repository from which the project was created.
This is done to allow pulling in fixes and updates from the template into the template based project.
-
merge-template-repo
-
-
Pulls in changes from the template repo from which this project was created.
-
install-dev-env
-
-
Checks for system prerequisites.
-
Downloads and builds raml-to-jaxrs.
-
Installs the Oracle JDBC components into the
vendor
directory. -
Downloads, builds, and installs the FgpUtil project into the
vendor
directory. -
Installs the required NPM packages
-
compile
-
-
Generates code & docs if the API def has changed.
-
Compiles Java code if anything has changed.
-
test
-
-
Generates code & docs if the API def has changed.
-
Compiles Java code if necessary.
-
Runs unit tests.
-
jar
-
-
Generates code & docs if the API def has changed.
-
Compiles Java code if necessary.
-
Runs unit tests if necessary.
-
Packages a self-contained runnable jar.
-
docker
-
-
Runs
docker build
for the project.
-
Presently the build process is operated through a makefile which calls and sets up the necessary prerequisites. This is a temporary solution to be used until all the utilities in the build utils project are migrated to the gradle plugin project.
The make gen-jaxrs
command is backed by the Mulesoft Raml-for-JaxRs library.
The RAML to JaxRS conversion library has the following known issues that are likely to impact use of the tool:
- Enums
-
-
Enum generation creates types that do not allow access to the raw backing text, which may be desired when constructing complex responses.
-
Enum generation may cause the generator to fail with cryptic errors involving bad imports for the Java builtin type
String
One alternative/workaround for this is defining the enum type in Java and typing the RAML as string with the possible values defined as examples.
-
- Inheritance
-
Extending types can work out for trees with at most 1 parent depth, however going beyond that may cause things to generate in a way that has compile errors.
additionalProperties
aka//:
-
Using a catchall block for maps with anything other than a simple value type will cause the java type to be
Map<String, Object>
. Additionally even a simple value type may have this result.
When developing or testing a service, you may need to provide that service access to resources that cannot be reached without a tunnel or proxy. This is complicated by the fact that Docker containers, by default, will not see those resources.
To allow Dockerized services access to these external resources, the running
container(s) must be given access to the host machine’s network. This can be
done via docker run
using the
network mode "host"
or via docker-compose
by setting the
network_mode
config option to "host".
Binding the containers to your host machine’s network will give the containers access to your running tunnels/proxies, but will also mean binding all exposed container ports to those ports on your host machine which may cause conflicts.
The root directory of this project contains multiple standard files used by Gradle, Docker, Make, and GitHub, in addition to custom files created for developer convenience.
File | For | Description |
---|---|---|
|
Docker |
Similar to |
|
Git |
Tells git to ignore files matching the specified patterns. |
|
RAML |
API endpoint definition. |
|
Gradle |
Standard Gradle build script definition.[3] This particular build script uses the Kotlin DSL for gradle. The project configuration is set here and passed to the gradle plugin, and all other project dependencies are also set here. |
|
Docker |
Docker container definition file.[4] |
|
Gradle |
Standard, autogenerated Gradle script that allows the use of Gradle without requiring the host machine itself to have Gradle installed. |
|
Make |
Convenience wrapper for the build utils until the required tasks are performed which will allow simplifying the build. See Make Targets for usage. |
|
GitHub |
Asciidoc readme file (the source backing this page). |
|
Gradle |
File read by gradle before build.gradle.kts; provides the repository and credentials to download the VEuPathDB gradle plugin. This configuration cannot be contained in |
Directory | For | Description |
---|---|---|
|
Docker/Docker Compose |
Contains docker-compose configuration files. |
|
Gradle |
Contains the backing source for the |
|
RAML |
Contains RAML type definitions imported by the |
|
Java source root |