diff --git a/docs/architecture/overview.adoc b/docs/architecture/overview.adoc new file mode 100644 index 000000000..c920bc5fb --- /dev/null +++ b/docs/architecture/overview.adoc @@ -0,0 +1,3 @@ += Amido Stacks - Architecture Overview + +video::658523841[vimeo] \ No newline at end of file diff --git a/docs/contents.adoc b/docs/contents.adoc new file mode 100644 index 000000000..009ed0b15 --- /dev/null +++ b/docs/contents.adoc @@ -0,0 +1,9 @@ +About Stacks: +....... + +.Architecture +[%collapsible%open] +==== +xref:introduction.adoc[Architecture docs] +==== + diff --git a/docs/development-patterns/introduction.adoc b/docs/development-patterns/introduction.adoc new file mode 100644 index 000000000..5e4e331fc --- /dev/null +++ b/docs/development-patterns/introduction.adoc @@ -0,0 +1,7 @@ += Development Patterns + +The following pages describe in detail how Stacks is developed. + +As with any active project third party libraries are depended upon to enhance functionality, standardise approaches across the wider community and to reduce boilerplate code or "re-inventing the wheel"; these pages describe how they are used within the context of Stacks. + +In addition to this as part of ongoing refactoring activities, code is often reworked to address performance or readability concerns and this too is outlined. \ No newline at end of file diff --git a/docs/development-patterns/reducing_bean_mapping.adoc b/docs/development-patterns/reducing_bean_mapping.adoc new file mode 100644 index 000000000..e0d4710e0 --- /dev/null +++ b/docs/development-patterns/reducing_bean_mapping.adoc @@ -0,0 +1,142 @@ += Reducing Bean Mapping Boilerplate + +== Context +Good programming techniques tell us that we should be following a principle of separation of concerns. This means that as developers we often have to shuffle data from one object to another. + +A common example of this is where we have a Data Transfer Object (DTO) passed as a parameter in a REST API call, and we need to copy the data from object-graph to another, for example into a Domain Object for it to be subsequently persisted. The same is required in reverse, when we read an object from the data store we need to convert that object into a DTO that is then passed back to the caller. + +This becomes more complex when we have not only single instances of an object, but we have a collection of them. + +To be clear, it is bad practice to use the same object (i.e., `Class`) in your code for both of the internal operations (managing the domain) and external operations (receiving or passing data to/from a caller) as it makes future change more complex. + +The vanilla Java way to approach this is through overloaded constructors or the use of the builder pattern - both of which can become unwieldy as the number of the properties on the class increases. It also means that specific methods need to be manually written to support single objects or lists/collections of objects. + +== Solution +The link:https://mapstruct.org/[MapStruct] open-source project is a code generator that greatly simplifies the implementation of mappings between Java bean types based on a convention over configuration approach. + +The generated mapping code uses plain method invocations and thus is fast, type-safe and easy to understand (this is important, as other mappers that use runtime reflection are "black boxes" that need to be executed in order to be debugged). + +In addition, there is full support for Spring auto-wiring and Unit Testing. + +MapStruct is an "annotation processor" so please make sure this is switched on for your project. Base on your setup, it may also be necessary to `mvn compile` after creating any new mappers. + +== Implementation Examples +MapStruct is capable of working in many ways, although the approach taken in the Stacks project is to follow the pattern whereby it uses interfaces to define mapper objects. With the addition of some mapper utility functions it means that a bean-mapper that supports single objects and collections (in addition to other features such as UUID<->String auto-conversion) can be created very easily. + +=== Base Mapper Code +The following generic base mapper interface (this is as show at time of writing for example purposes, refer to GitHub for the latest) is used to define a standard set of mapping functions and lives in the Stacks `core-commons` module. + +The generic template placeholder D is for the DTO (external) representation and E is for the Entity (internal) representation. As can be seen, this will provide a number of "out of the box" methods such as `toDto()`, `fromDto()`, `toDtoList()` etc. +[source,java] +---- +public interface BaseMapper { +D toDto(E entity); + + E fromDto(D dto); + + void updateFromDto(D dto, @MappingTarget E entity); + + void updateFromEntity(E entity, @MappingTarget D dto); + + List toDtoList(List list); + + List fromDtoList(List list); +} +---- +In addition to this, some mapping utility functions are included. Some Stacks modules use a UUID as the external representation of an ID whereas internally it uses a String (for persistence). + +The mapping utility class is currently structured as follows. This has simple functions that MapStruct will use whenever it needs to convert between these data types. +[source,java] +---- +public class MapperUtils { + + private MapperUtils() { + // Utility class + } + + public static UUID map(String value) { + return (value != null && !value.trim().isEmpty()) ? fromString(value) : null; + } + + public static String map(UUID uuid) { + return uuid != null ? uuid.toString() : null; + } +} +---- +=== Project Mapper Code +==== Example 1 +Whenever a higher-level module (such as project code) requires a mapper between beans (or object-graphs) the implementation is a simple interface that extends the base mapper and imports (or uses) the mapping utility class shown above. + +A simple mapper is as follows. This mapper maps between `MenuDTO` and a `Menu` domain object. + +It can be seen that it also "uses" another mapper (so that an entire object hierarchy) can be converted in one go, and also uses the `MapperUtils` class that supports the conversion from UUID to String data types. +[source,java] +---- +@Mapper( +componentModel = "spring", +uses = {MapperUtils.class, CategoryMapper.class}, +nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface MenuMapper extends BaseMapper {} +---- +==== Example 2 +A more complex mapper is shown below. This mapper maps between a top-level Stacks `CreateMenuRequest` DTO and related domain object called `CreateMenuCommand`. The name of fields differs between these two objects, so it is necessary in this instance to overload the `toDto()` and `fromDto()` methods to tell MapStruct how to map between the fields. +[source,java] +---- +@Mapper( +componentModel = "spring", +uses = {}, +nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface CreateMenuMapper extends BaseMapper { + + @Override + @Mapping(source = "restaurantId", target = "tenantId") + CreateMenuRequest toDto(CreateMenuCommand command); + + @Override + @Mapping(source = "tenantId", target = "restaurantId") + CreateMenuCommand fromDto(CreateMenuRequest request); +} +---- +== Unit Test Code +As previously mentioned, MapStruct has full support for Spring Boot testing frameworks such as JUnit. + +To use any mappers that have been created structure your tests as follows: +[source,java] +---- +@Tag("Unit") +@SpringBootTest( +classes = { +MenuMapper.class, +MenuMapperImpl.class, +... +}) +class DomainToDtoMapperMapstructTest { + + @Autowired private MenuMapper menuMapper; + + ... + + @Test + void menuToMenuDto() { + + // Given + UUID id = randomUUID(); + UUID restaurantId = randomUUID(); + ... + + Menu menu = + new Menu( + id.toString(), + restaurantId.toString(), + ...); + + // When + MenuDTO menuDTO = menuMapper.toDto(menu); + + // Then + assertThat(menuDTO.getId()).isEqualTo(id); + assertThat(menuDTO.getRestaurantId()).isEqualTo(restaurantId); + ... + } +} +---- \ No newline at end of file diff --git a/docs/development-patterns/reducing_swagger_annotation.adoc b/docs/development-patterns/reducing_swagger_annotation.adoc new file mode 100644 index 000000000..92c8266da --- /dev/null +++ b/docs/development-patterns/reducing_swagger_annotation.adoc @@ -0,0 +1,96 @@ += Reducing Swagger Annotation Overload + +== Context +The API documentation is an essential part of building REST APIs to make the services available to all audience. This documentation should help consumers of the service know which all services are available and its fine details. Also, there should be some simple way to test if the service is up. + +SpringDoc simplifies the generation and maintenance of API docs based on the OpenAPI 3 specification for the spring boot applications. The exposed services are bound to change and the documentation needs to be updated as the services change. If this is done manually, then it will become a complex process, and it will be prone to error, especially as the number of REST services increase. This is where swagger helps to automate this documentation process and the consumers of this API would see the output of all of this in the swagger UI (for example, the Swagger API Doc Endpoint at /swagger/index.html). + +The proliferation of Swagger annotation's means that there is a lot of duplicated APIResponse annotations that bloat the code and make it difficult to maintain and read. + +== Solution +To avoid the code duplication around swagger annotations, we have opted to use our own @interface Java annotation to "carry" these annotations and make them a reusable unit which will minimise the duplicated Swagger annotations from controller methods. + +== Implementation Examples +We have defined custom java annotations per CRUD operation to be used by the controller classes. This will promote re-usability of the swagger annotations rather than duplicating the code across multiple controller classes. + +*Example of java custom annotation:* + +In the below example we have: + +Added multiple Swagger REST response annotations to our own annotation +Added the Security Requirement annotation +This is so that we have a single annotation that a developer can use to easily apply all of these Swagger repetitive annotations across multiple classes using just a single annotation per class, therefore fixing the problem being addressed - annotation bloat. + +In the below example, we are creating ReadAPIResponses annotation. + +[source,java] +---- +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@ApiResponses({@ApiResponse( +responseCode = "404", +description = "Resource not found", +content = {@Content( +mediaType = "application/json", +schema = @Schema( +implementation = ErrorResponse.class))}), +@ApiResponse( +responseCode = "400", +description = "Bad Request", +content = {@Content( +mediaType = "application/json", +schema = @Schema( +implementation = ErrorResponse.class))} +)}) +@SecurityRequirement(name = "bearerAuth") +public @interface ReadAPIResponses {} +---- +*Using the custom Annotation @ReadAPIResponses:* + +In the below code example, java custom annotation @ReadAPIResponses has been used. + +[source,java] +---- +@RestController +public class MenuController { + + @GetMapping(value = "/{id}") + @Operation(tags = "Menu", summary = "Get a menu", description = "By passing the menu id, ...") + @ReadAPIResponses + ResponseEntity getMenu( + @PathVariable(name = "id") UUID id, + @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { + + // Code here + + } +} +---- +*Overriding the custom annotations:* + +We can override our new custom annotation entries by placing the annotation before the new custom annotation. In the below example, @ApiResponse entry will override the 200 response code in @ReadAPIResponses custom annotation as the @ApiResponse comes before @ReadAPIResponses. We just have to make that the annotations are placed in the right order. + +[source,java] +---- +@RestController +public class MenuController { + + @GetMapping(value = "/{id}") + @Operation(tags = "Menu", summary = "Get a menu", description = "By passing the menu id, ...") + @ApiResponse( + responseCode = "200", + description = "Menu", + content = + @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = MenuDTO.class))) + @ReadAPIResponses + ResponseEntity getMenu( + @PathVariable(name = "id") UUID id, + @Parameter(hidden = true) @RequestAttribute("CorrelationId") String correlationId) { + + // Code here + + } +} +---- \ No newline at end of file diff --git a/docs/development-patterns/seperation_of_concerns.adoc b/docs/development-patterns/seperation_of_concerns.adoc new file mode 100644 index 000000000..8bbeabbca --- /dev/null +++ b/docs/development-patterns/seperation_of_concerns.adoc @@ -0,0 +1,109 @@ += Separation of Concerns + +== Context +As the size of an application codebase grows, unless the code is structured in a way that makes it straight-forward for it to be evolved then the chances are that any modifications to be made will take longer and new bugs introduced. + +This is for a number of reasons, not limited to: - + +. No clear view on which code areas need to be modified to effect a business change +. Difficult to replace components or code units as they are not ring-fenced having clear interfaces +. Uncertainty in how the code being modified is actually invoked and executed +. Code blocks that are repeated in numerous places (and may actually differ ever so slightly) +. Difficulty in testing all paths through the codebase for any given change +All of this increases the cognitive load on the developer making it more likely that the quality of the codebase will probably reduce over time. + +== Solution +The solution to the problems mentioned above are to ensure that there is clear separation of concerns. + +Separation of concerns is a design principle for separating a computer program into distinct sections, such that each section addresses a separate concern. For example the business logic of the application is a concern and the user interface is another concern. Changing the user interface should not require changes to business logic and vice versa. + +=== 3-Layer Applications +One common way to manage this in a Spring Boot application is to follow the Controller-Service-Repository pattern. One of the big reasons this pattern is so popular is that it does a great job ensuring separation of concerns. + +image::https://stacks.amido.com/img/java_separation_of_concerns.png[Tux,450,350] + +The Controller layer, the top layer in the diagram above, is solely responsible for exposing the functionality so that it can be consumed by external consumers (including, perhaps, a UI component). The Repository layer, at the bottom, is responsible for storing and retrieving some set of data. The Service layer in the middle is where all the business logic should go. If the business logic requires fetching/saving data, it use a Repository. If someone wants to access the business logic from the outside world, they go through a Controller to get there. It is of course perfectly acceptable for one service to call another service. + +This sets up a pretty simple separation of concerns. If code is related to storage/retrieval, it should go in the Repository. If it's dealing with exposing functionality to external consumers, it goes in the Controller. Anything unique in the business logic would go in the Service layer. The Repository doesn’t care which component is invoking it; it simply does what it is asked. The Service layer doesn’t care how it gets accessed, it just does its work, using a Repository where required. And the Controller is just passing the work down to the Service layer, so it can stay nice and lean. + +=== Improved Testing +Where this really starts to pay dividends is in the unit testing philosophy. + +By having a clean separation of concerns, it is possible to mock adjacent layers and worry about only testing the concerns of that particular layer. Our Controller tests are only worried about response codes and values, and it's easy to mock the service to trigger those conditions. The Service layer can even be tested as a POJO, and by mocking Repository conditions it's possible to test all the business logic therein without having to worry about going through the controller layer to test it. + +== Implementation Examples +Spring Boot is based heavily on the Spring dependency injection framework. Dependency injection (DI) means that when one component requires the use of another then it is provided to it (auto-magically) by an overarching management container that contains references to all available components (that are declared using Java annotations in the codebase and discovered at startup). + +This makes it very easy to create Spring components (essentially just Java classes) that provide this separation of concerns. Of course, it's still possible for a rogue developer to break this pattern and put the code in the wrong places, but having this pattern should help to alleviate this. + +=== Controller Layer +The `@RestController` annotated class is used to manage the transport-level concerns of the application. As can be seen below, it manages the REST API path (in this example a HTTP GET request available at URI `/thing/{id})` and the shuffling of data from the internal representation (a `Thing` domain object) and its external representation (a `ThingDTO` data transfer object). + +It can be seen that a `ThingService` component is "wired" into the controller class, whose responsibility it is to provide any business logic (and/or to call peers (other services) or delegate to lower layers). + +The code in the controller layer should be as minimal as possible and simply delegate to a service. + +[source,java] +---- +@RestController +@RequestMapping("/thing") +public class ThingController { + + @Autowired + private ThingService thingService; + + @GetMapping("/{id}") + public ResponseEntity getThing(@PathVariable("id") UUID id) { + + return ResponseEntity.ok(thingService.getThing(id)); + + } +} +---- + +=== Service Layer +The `@Service` annotated class is the component where any business logic should be performed. This may include sense-checking values or performing custom logic. By doing these activities here it makes the unit re-usable across the application, and means that should the business logic change then it only needs to be modified in one place, and that one place is very clearly related to the thing (no pun intended) in scope. + +It can be seen that a `ThingRepository` component is "wired" into the service class, whose responsibility it is to manage any persistence activities such as reading from or writing to a database. Should the business require data to persisted using a different mechanism (such as to/from a filesystem) then only one repository can be switched out for an alternate (observe that it's an interface in the code). + +Note the use of in the example below to perform simple bean mapping between domain objects and DTO classes, and vice versa. + +[source,java] +---- +@Service +public class ThingService { + + @Autowired + private ThingRepository thingRepository; + + @Autowired + private ThingMapper thingMapper; + + public ThingDTO getThing(UUID id) { + + Optional optThing = thingRepository.findById(id); + + if (optThing.isPresent()) { + + // Map between Thing and ThingDTO, probably using MapStruct ... + return thingMapper.toDto(optThing.get()); + + } + + throw new ThingNotFoundException(); + + } +} +---- +=== Repository Layer +As discussed above, the `@Repository` annotated class is the component that manages persistence. Spring Boot provides a number of standard interfaces out-of-the-box (such as the `CrudRepository` shown below) which provide methods such as `findById()`, `findAll()`, `save()`, `deleteById()` and so on. + +[source,java] +---- +@Repository +public interface ThingRepository extends CrudRepository { + + // Add any bespoke CRUD methods here + +} +---- \ No newline at end of file diff --git a/docs/introduction.adoc b/docs/introduction.adoc new file mode 100644 index 000000000..e69de29bb diff --git a/docs/quick_start.adoc b/docs/quick_start.adoc new file mode 100644 index 000000000..e69de29bb diff --git a/docs/workloads/architecture/modularity_overview.adoc b/docs/workloads/architecture/modularity_overview.adoc new file mode 100644 index 000000000..a691a228a --- /dev/null +++ b/docs/workloads/architecture/modularity_overview.adoc @@ -0,0 +1,54 @@ += Overview of Maven modularity + +In order to reduce code duplication, make maintenance easier and allow +better customisation control, the Stacks Workloads use the following +internal dependencies: + +== Common Modules + +These modules are shared modules, independant of the cloud provider +selected: - + +TODO internal links +* link:/docs/workloads/common/backend/java/architecture/dependency_parent_java[Stacks +modules parent], found in +https://github.com/amido/stacks-java-module-parent[stacks-java-module-parent] +* link:/docs/workloads/common/backend/java/architecture/dependency_commons_java[Stacks +commons core module], found in +https://github.com/amido/stacks-java-core-commons[stacks-java-core-commons] +* link:/docs/workloads/common/backend/java/architecture/dependency_api_java[Stacks +commons API module], found in +https://github.com/amido/stacks-java-core-api[stacks-java-core-api] +* link:/docs/workloads/common/backend/java/architecture/dependency_cqrs_java[Stacks +commons CQRS module], found in +https://github.com/amido/stacks-java-core-cqrs[stacks-java-core-cqrs] +* link:/docs/workloads/common/backend/java/architecture/dependency_messaging_java[Stacks +messaging core module], found in +https://github.com/amido/stacks-java-core-messaging[stacks-java-core-messaging] + +== Azure Capability Modules + +Capabilities are provided by the Azure cloud platform: - + +* link:/docs/workloads/azure/backend/java/architecture/dependency_servicebus_java[Stacks +Azure Service Bus module], found in +https://github.com/amido/stacks-java-azure-servicebus[stacks-java-azure-servicebus] +* link:/docs/workloads/azure/backend/java/architecture/dependency_cosmos_java[Stacks +Azure CosmosDB module], found in +https://github.com/amido/stacks-java-azure-cosmos[stacks-java-azure-cosmos] + +== AWS Capability Modules + +Capabilities are provided by the AWS cloud platform: - + +* link:/docs/workloads/aws/backend/java/architecture/dependency_sqs_java[Stacks +AWS SQS module], found in +https://github.com/amido/stacks-java-aws-sqs[stacks-java-aws-sqs] +* link:/docs/workloads/aws/backend/java/architecture/dependency_dynamodb_java[Stacks +AWS DynamoDB module], found in +https://github.com/amido/stacks-java-aws-dynamodb[stacks-java-aws-dynamodb] + +The modules are built and published independently of the Workloads and +by default are pulled into the project as Maven dependencies. You can +easily replace these by cloning individual repositories and placing them +in your application either directly or as modules. \ No newline at end of file diff --git a/docs/workloads/architecture/modules/core_api_modules.adoc b/docs/workloads/architecture/modules/core_api_modules.adoc new file mode 100644 index 000000000..d5e732725 --- /dev/null +++ b/docs/workloads/architecture/modules/core_api_modules.adoc @@ -0,0 +1,313 @@ += Stacks Core API module + +== Module Overviewlink:#module-overview[​] + +This module provides basic functionality to create an MVC project. It's +based on Spring and contains the required functionality to handle +authentication, token acquisition, filtering and API exception handling. +It's intended to be a module for Amido Stacks but can also get used in +your project. + +== Module Structurelink:#module-structure[​] + +In the following diagram, you can see all the relevant files of this +module. Be aware, pulling from the repository will have some extra files +that are not relevant to the logic but required to build and deploy. + +=== Project structurelink:#project-structure[​] + +[source,shell] +---- +java +\_.mvn +: |_settings.xml +|_archetype.properties +|_pom.xml +\_src +: \_main +: \_java +: \_com.amido.stacks.core.api +: \_auth +: |_AuthController.java +: \_impl +: |_AuthControllerImpl.java +: \_dto +: |_ErrorResponse.java +: \_request +: |_GenerateTokenRequest.java +: \_response +: |_GenerateTokenResponse.java +: |_ResourceCreatedResponse.java +: \_exception +: |_ApiException.java +: |_ApiExceptionAdvice.java +: \_filter +: |_CorrelationIdFilter.java +: |_CorrelationIdFilterConfiguration.java +---- + + +== How to uselink:#how-to-use[​] + +There are four ways to integrate this module into your project: + +* Use it as a link:#use-it-as-a-dependency[dependency] +* Create a localized solution using +link:#localized-solution-using-maven-archetypes[Maven Archetypes +artifacts] available in our Artifactory repo +* Clone this repo, +link:#building-the-module-locally-from-this-repository[locally build] +and use it as a Maven dependency +* Clone this repo, create a +link:#creating-an-archetype-from-this-repository[custom archetype] and +then use it as a Maven dependency + +=== Use it as a dependency[[use-it-as-a-dependency]] + +==== Mavenlink:#maven[​] + +In the `+dependencies+` section of your application's `+pom.xml+` add: + +[source,xml] +---- + + com.amido.stacks.modules + stacks-core-api + 1.0.0 + +---- + +Then you can do a `+./mvnw clean compile+` to fetch it; after that, you +can use it like any other dependency. + +[source,shell] +---- +./mvnw clean compile +---- + + +==== Otherslink:#others[​] + +Use it as you'd use any dependency in your build tool. + +=== Localized solution using Maven Archetypes[[localized-solution-using-maven-archetypes]] + +If you wish to customise the module and use your organisation's +namespaces instead of Amido's. You can create a +https://maven.apache.org/archetype/index.html[Maven archetype]. +Archetype is Maven's tool for scaffolding and offers lots of extra +functionality. We suggest spending some time looking into them. We use +Archetype to create a template and enable you to adopt this module under +your organisation's namespace. To use the deployed archetypes: + +. Make and move to a new folder +. Then run ++ +[source,shell] +---- +mvn archetype:generate \ + -DarchetypeGroupId='com.amido.stacks.modules' \ + -DarchetypeArtifactId='stacks-core-api-archetype' \ + -DarchetypeVersion='' \ + -DgroupId='' \ + -DartifactId='' \ + -Dversion='' \ + -Dpackage='' +---- + + +* `++` is a placeholder for your group ID +* `++` is a placeholder for your artefact ID +* `++` is a placeholder for your version +* `++` is a placeholder for the root package name and +structure. It should start with your `+groupdId+` and continue with the +name of the root package. ++ +____ +For example, using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) +____ +. Go to the `+pom.xml+` file of the project you'll be using this module +in and add it as a link:#use-it-as-a-dependency[dependency] + +*Example*: Using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) + +____ +*If you previously had used this module under different namespace (i.e. +the default `+com.amido.stacks.core-api+`):* + +Maven ONLY updates the imports for the module you generated. Any +references in other projects will remain to the previous namespace. + +You will need to + +* Update them manually +* Re-create the relevant `+import+` statements to use the new-made +module instead +* If you plan to use this with Amido Stacks, include your namespace in +the `+@ComponentScan+` annotation of the `+Application+` class. +____ + +=== Building the module locally from this repository[[building-the-module-locally-from-this-repository]] + +To build the module locally: + +. Clone this repo +. Navigate to the `+java+` folder +. run `+./mvnw clean install+` to install the module locally. +. Add it as any other link:#use-it-as-a-dependency[dependency] + +=== Creating an Archetype from this repository[[creating-an-archetype-from-this-repository]] + +If you wish to customise the module and use your organisation's +namespaces instead of Amido's. You can create a +https://maven.apache.org/archetype/index.html[Maven archetype]. +Archetype is Maven's tool for scaffolding and offers lots of extra +functionality. We suggest spending some time looking into them. We use +Archetype to create a template and enable you to adopt this module under +your organisation's namespace. To use the deployed archetypes: To build, +install and use the archetype follow these steps: + +. Clone this repo +. Navigate to the `+/java+` in +the terminal +. Then issue the following Maven commands, using the included wrapper: +.. Create the archetype from the existing code ++ +[source,shell] +---- +./mvnw archetype:create-from-project -DpropertyFile='./archetype.properties' +---- + + +.. Navigate to the folder it was created in ++ +[source,shell] +---- +cd target/generated-sources/archetype +---- + + +.. Install the archetype locally ++ +[source,shell] +---- +..\..\..\mvnw install +---- + +. Make and navigate to a directory in which you'd like to create the +localized project, ideally outside this project's root folder +. To create the project, use the command below: ++ +[source,shell] +---- +/mvnw archetype:generate \ + -DarchetypeGroupId='com.amido' \ + -DarchetypeArtifactId='stacks-core-api' \ + -DarchetypeVersion='1.0.0-SNAPSHOT' \ + -DgroupId='' \ + -DartifactId='' \ + -Dversion='' \ + -Dpackage=''` +---- + +.. `++` is a placeholder for your group ID +.. `++` is a placeholder for your artefact ID +.. `++` is a placeholder for your version +.. `++` is a placeholder for the root package name and +structure. It should start with your `+groupdId+` and continue with the +name of the root package. ++ +____ +For example, using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) +____ +. Go to the `+pom.xml+` file of the project you'll be using this module +in and add it as a link:#use-it-as-a-dependency[dependency] + +*Example*: Using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) + +____ +*If you previously had used this module under different namespace (i.e. +the default `+com.amido.stacks.core-api+`):* + +Maven ONLY updates the imports for the module you generated. Any +references in other projects will remain to the previous namespace. + +You will need to + +* Update them manually +* Re-create the relevant `+import+` statements to use the new-made +module instead +* If you plan to use this with Amido Stacks, include your namespace in +the `+@ComponentScan+` annotation of the `+Application+` class. +____ + +== Accessing Sonatype OSSRHlink:#accessing-sonatype-ossrh[​] + +Our artefacts and archetypes get hosted on Sonatype OSSRH then to maven +central . to access artifact from OSSRH before it get published to maven +central update `+pom.xml+`: + +[source,xml] +---- + + + + snapshots + default-maven-virtual + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + + + true + + releases + default-maven-staging + https://s01.oss.sonatype.org/content/repositories/releases/ + + +---- + +Alternatively, you can also add this configuration as a profile in your +Maven's `+settings.xml+` file in the `+.m2+` folder in your home +directory (any OS): + +[source,xml] +---- + + + + + + snapshots + default-maven-virtual + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + + + true + + releases + default-maven-staging + https://s01.oss.sonatype.org/content/repositories/releases/ + + + nexus + + + + +nexus + +---- diff --git a/docs/workloads/architecture/modules/core_commons_module.adoc b/docs/workloads/architecture/modules/core_commons_module.adoc new file mode 100644 index 000000000..313273c87 --- /dev/null +++ b/docs/workloads/architecture/modules/core_commons_module.adoc @@ -0,0 +1,298 @@ += Stacks Core Commons module + +== Module Overviewlink:#module-overview[​] + +This module provides common code used by more than one of the Stacks +modules: Both +https://github.com/amido/stacks-java-core-messaging/[Events] and +https://github.com/amido/stacks-java-core-cqrs/[CQRS Commands] use the +`+OperationsContext+` abstract class and `+StacksPersistence+` provides +a basic CRUD repository interface used in persistence related modules +like https://github.com/amido/stacks-java-cosmos[Stacks Cosmos]. Please +refer to these modules as examples. + +== Module Structurelink:#module-structure[​] + +In the following diagram, you can see all the relevant files of this +module. Be aware, pulling from the repository will have some extra files +that are not relevant to the logic but required to build and deploy. + +=== Project structurelink:#project-structure[​] + +[source,shell] +---- +java +\_.mvn +: |_settings.xml +|_archetype.properties +|_pom.xml +\_src +: \_main +: \_java +: \_com.amido.stacks.core +: \_operations +: |_OperationContext.java +: \_repository +: |_StacksPersistence.java +---- + +== How to uselink:#how-to-use[​] + +There are four ways to integrate this module into your project: + +* Use it as a link:#use-it-as-a-dependency[dependency] +* Create a localized solution using +link:#localized-solution-using-maven-archetypes[Maven Archetypes +artifacts] available in our Artifactory repo +* Clone this repo, +link:#building-the-module-locally-from-this-repository[locally build] +and use it as a Maven dependency +* Clone this repo, create a +link:#creating-an-archetype-from-this-repository[custom archetype] and +then use it as a Maven dependency + +=== Use it as a dependency[[use-it-as-a-dependency]] + +==== Mavenlink:#maven[​] + +In the `+dependencies+` section of your application's `+pom.xml+` add: + +[source,xml] +---- + + com.amido.stacks.modules + stacks-core-commons + 1.0.0 + +---- + +Then you can do a `+./mvnw clean compile+` to fetch it; after that, you +can use it like any other dependency. + +[source,shell] +---- +./mvnw clean compile +---- + +==== Otherslink:#others[​] + +Use it as you'd use any dependency in your build tool. + +=== Localized solution using Maven Archetypes[[localized-solution-using-maven-archetypes]] + +If you wish to customise the module and use your organisation's +namespaces instead of Amido's. You can create a +https://maven.apache.org/archetype/index.html[Maven archetype]. +Archetype is Maven's tool for scaffolding and offers lots of extra +functionality. We suggest spending some time looking into them. We use +Archetype to create a template and enable you to adopt this module under +your organisation's namespace. To use the deployed archetypes: + +. Make and move to a new folder +. Then run ++ +[source,shell] +---- +mvn archetype:generate \ + -DarchetypeGroupId='com.amido.stacks.modules' \ + -DarchetypeArtifactId='stacks-core-commons-archetype' \ + -DarchetypeVersion='' \ + -DgroupId='' \ + -DartifactId='' \ + -Dversion='' \ + -Dpackage='' +---- + +* `++` is a placeholder for your group ID +* `++` is a placeholder for your artefact ID +* `++` is a placeholder for your version +* `++` is a placeholder for the root package name and +structure. It should start with your `+groupdId+` and continue with the +name of the root package. ++ +____ +For example, using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) +____ +. Go to the `+pom.xml+` file of the project you'll be using this module +in and add it as a link:#use-it-as-a-dependency[dependency] + +*Example*: Using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) + +____ +*If you previously had used this module under different namespace (i.e. +the default `+com.amido.stacks.core-commons+`):* + +Maven ONLY updates the imports for the module you generated. Any +references in other projects will remain to the previous namespace. + +You will need to + +* Update them manually +* Re-create the relevant `+import+` statements to use the new-made +module instead +* If you plan to use this with Amido Stacks, include your namespace in +the `+@ComponentScan+` annotation of the `+Application+` class. +____ + +=== Building the module locally from this repository[[building-the-module-locally-from-this-repository]] + +To build the module locally: + +. Clone this repo +. Navigate to the `+java+` folder +. run `+./mvnw clean install+` to install the module locally. +. Add it as any other link:#use-it-as-a-dependency[dependency] + +=== Creating an Archetype from this repository[[creating-an-archetype-from-this-repository]] + +If you wish to customise the module and use your organisation's +namespaces instead of Amido's. You can create a +https://maven.apache.org/archetype/index.html[Maven archetype]. +Archetype is Maven's tool for scaffolding and offers lots of extra +functionality. We suggest spending some time looking into them. We use +Archetype to create a template and enable you to adopt this module under +your organisation's namespace. To use the deployed archetypes: To build, +install and use the archetype follow these steps: + +. Clone this repo +. Navigate to the `+/java+` in +the terminal +. Then issue the following Maven commands, using the included wrapper: +.. Create the archetype from the existing code ++ +[source,shell] +---- +./mvnw archetype:create-from-project -DpropertyFile='./archetype.properties' +---- + +.. Navigate to the folder it was created in ++ +[source,shell] +---- +cd target/generated-sources/archetype +---- + +.. Install the archetype locally ++ +[source,shell] +---- +..\..\..\mvnw install +---- + +. Make and navigate to a directory in which you'd like to create the +localized project, ideally outside this project's root folder +. To create the project, use the command below: ++ +[source,shell] +---- +/mvnw archetype:generate \ + -DarchetypeGroupId='com.amido' \ + -DarchetypeArtifactId='stacks-core-commons' \ + -DarchetypeVersion='1.0.0-SNAPSHOT' \ + -DgroupId='' \ + -DartifactId='' \ + -Dversion='' \ + -Dpackage=''` +---- + +.. `++` is a placeholder for your group ID +.. `++` is a placeholder for your artefact ID +.. `++` is a placeholder for your version +.. `++` is a placeholder for the root package name and +structure. It should start with your `+groupdId+` and continue with the +name of the root package. ++ +____ +For example, using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) +____ +. Go to the `+pom.xml+` file of the project you'll be using this module +in and add it as a link:#use-it-as-a-dependency[dependency] + +*Example*: Using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) + +____ +*If you previously had used this module under different namespace (i.e. +the default `+com.amido.stacks.core-commons+`):* + +Maven ONLY updates the imports for the module you generated. Any +references in other projects will remain to the previous namespace. + +You will need to + +* Update them manually +* Re-create the relevant `+import+` statements to use the new-made +module instead +* If you plan to use this with Amido Stacks, include your namespace in +the `+@ComponentScan+` annotation of the `+Application+` class. +____ + +== Accessing Sonatype OSSRHlink:#accessing-sonatype-ossrh[​] + +Our artefacts and archetypes get hosted on Sonatype OSSRH then to maven +central . to access artifact from OSSRH before it get published to maven +central update `+pom.xml+`: + +[source,xml] +---- + + + + snapshots + default-maven-virtual + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + + + true + + releases + default-maven-staging + https://s01.oss.sonatype.org/content/repositories/releases/ + + +---- + +Alternatively, you can also add this configuration as a profile in your +Maven's `+settings.xml+` file in the `+.m2+` folder in your home +directory (any OS): + +[source,xml] +---- + + + + + + snapshots + default-maven-virtual + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + + + true + + releases + default-maven-staging + https://s01.oss.sonatype.org/content/repositories/releases/ + + + nexus + + + + +nexus + +---- \ No newline at end of file diff --git a/docs/workloads/architecture/modules/core_cqrs_module.adoc b/docs/workloads/architecture/modules/core_cqrs_module.adoc new file mode 100644 index 000000000..9d33c70ab --- /dev/null +++ b/docs/workloads/architecture/modules/core_cqrs_module.adoc @@ -0,0 +1,303 @@ += Stacks Core CQRS module + +== Module Overviewlink:#module-overview[​] + +This module provides functionality to implement a basic CQRS +functionality, by using the `+ApplicationCommand+` and +`+CommandHandler+` classes. Please refer to sny of the +https://github.com/amido/stacks-java-cqrs/[CQRS] and +https://github.com/amido/stacks-java-cqrs-events/[CQRS with Events] +Stacks workload templates. + +== Module Structurelink:#module-structure[​] + +In the following diagram, you can see all the relevant files of this +module. Be aware, pulling from the repository will have some extra files +that are not relevant to the logic but required to build and deploy. + +=== Project structurelink:#project-structure[​] + +[source,shell] +---- +java +\_.mvn +: |_settings.xml +|_archetype.properties +|_pom.xml +\_src +: \_main +: \_java +: \_com.amido.stacks.core.cqrs +: \_command +: |CommandHandler.java +: \_handler +: |_CommandHandler.java +---- + +== How to uselink:#how-to-use[​] + +There are four ways to integrate this module into your project: + +* Use it as a link:#use-it-as-a-dependency[dependency] +* Create a localized solution using +link:#localized-solution-using-maven-archetypes[Maven Archetypes +artifacts] available in our Artifactory repo +* Clone this repo, +link:#building-the-module-locally-from-this-repository[locally build] +and use it as a Maven dependency +* Clone this repo, create a +link:#creating-an-archetype-from-this-repository[custom archetype] and +then use it as a Maven dependency + +=== Use it as a dependency[[use-it-as-a-dependency]] + +==== Mavenlink:#maven[​] + +In the `+dependencies+` section of your application's `+pom.xml+` add: + +[source,xml] +---- + + com.amido.stacks.modules + stacks-core-cqrs + 1.0.0 + +---- + + +Then you can do a `+./mvnw clean compile+` to fetch it; after that, you +can use it like any other dependency. + +[source,shell] +---- +./mvnw clean compile +---- + +==== Otherslink:#others[​] + +Use it as you'd use any dependency in your build tool. + +=== Localized solution using Maven Archetypes[[localized-solution-using-maven-archetypes]] + +If you wish to customise the module and use your organisation's +namespaces instead of Amido's. You can create a +https://maven.apache.org/archetype/index.html[Maven archetype]. +Archetype is Maven's tool for scaffolding and offers lots of extra +functionality. We suggest spending some time looking into them. We use +Archetype to create a template and enable you to adopt this module under +your organisation's namespace. To use the deployed archetypes: + +. Make and move to a new folder +. Then run ++ +[source,shell] +---- +mvn archetype:generate \ + -DarchetypeGroupId='com.amido.stacks.modules' \ + -DarchetypeArtifactId='stacks-core-cqrs-archetype' \ + -DarchetypeVersion='' \ + -DgroupId='' \ + -DartifactId='' \ + -Dversion='' \ + -Dpackage='' +---- + + +* `++` is a placeholder for your group ID +* `++` is a placeholder for your artefact ID +* `++` is a placeholder for your version +* `++` is a placeholder for the root package name and +structure. It should start with your `+groupdId+` and continue with the +name of the root package. ++ +____ +For example, using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) +____ +. Go to the `+pom.xml+` file of the project you'll be using this module +in and add it as a link:#use-it-as-a-dependency[dependency] + +*Example*: Using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) + +____ +*If you previously had used this module under different namespace (i.e. +the default `+com.amido.stacks.core-cqrs+`):* + +Maven ONLY updates the imports for the module you generated. Any +references in other projects will remain to the previous namespace. + +You will need to + +* Update them manually +* Re-create the relevant `+import+` statements to use the new-made +module instead +* If you plan to use this with Amido Stacks, include your namespace in +the `+@ComponentScan+` annotation of the `+Application+` class. +____ + +=== Building the module locally from this repository[[building-the-module-locally-from-this-repository]] + +To build the module locally: + +. Clone this repo +. Navigate to the `+java+` folder +. run `+./mvnw clean install+` to install the module locally. +. Add it as any other link:#use-it-as-a-dependency[dependency] + +=== Creating an Archetype from this repository[[creating-an-archetype-from-this-repository]] + +If you wish to customise the module and use your organisation's +namespaces instead of Amido's. You can create a +https://maven.apache.org/archetype/index.html[Maven archetype]. +Archetype is Maven's tool for scaffolding and offers lots of extra +functionality. We suggest spending some time looking into them. We use +Archetype to create a template and enable you to adopt this module under +your organisation's namespace. To use the deployed archetypes: To build, +install and use the archetype follow these steps: + +. Clone this repo +. Navigate to the `+/java+` in +the terminal +. Then issue the following Maven commands, using the included wrapper: +.. Create the archetype from the existing code ++ +[source,shell] +---- +./mvnw archetype:create-from-project -DpropertyFile='./archetype.properties' +---- + + +.. Navigate to the folder it was created in ++ +[source,shell] +---- +cd target/generated-sources/archetype +---- + + +.. Install the archetype locally ++ +[source,shell] +---- +..\..\..\mvnw install +---- + + +. Make and navigate to a directory in which you'd like to create the +localized project, ideally outside this project's root folder +. To create the project, use the command below: ++ +[source,shell] +---- +/mvnw archetype:generate \ + -DarchetypeGroupId='com.amido' \ + -DarchetypeArtifactId='stacks-core-cqrs' \ + -DarchetypeVersion='1.0.0-SNAPSHOT' \ + -DgroupId='' \ + -DartifactId='' \ + -Dversion='' \ + -Dpackage=''` +---- + + +.. `++` is a placeholder for your group ID +.. `++` is a placeholder for your artefact ID +.. `++` is a placeholder for your version +.. `++` is a placeholder for the root package name and +structure. It should start with your `+groupdId+` and continue with the +name of the root package. ++ +____ +For example, using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) +____ +. Go to the `+pom.xml+` file of the project you'll be using this module +in and add it as a link:#use-it-as-a-dependency[dependency] + +*Example*: Using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) + +____ +*If you previously had used this module under different namespace (i.e. +the default `+com.amido.stacks.core-cqrs+`):* + +Maven ONLY updates the imports for the module you generated. Any +references in other projects will remain to the previous namespace. + +You will need to + +* Update them manually +* Re-create the relevant `+import+` statements to use the new-made +module instead +* If you plan to use this with Amido Stacks, include your namespace in +the `+@ComponentScan+` annotation of the `+Application+` class. +____ + +== Accessing Sonatype OSSRHlink:#accessing-sonatype-ossrh[​] + +Our artefacts and archetypes get hosted on Sonatype OSSRH then to maven +central . to access artifact from OSSRH before it get published to maven +central update `+pom.xml+`: + +[source,xml] +---- + + + + snapshots + default-maven-virtual + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + + + true + + releases + default-maven-staging + https://s01.oss.sonatype.org/content/repositories/releases/ + + +---- + + + +Alternatively, you can also add this configuration as a profile in your +Maven's `+settings.xml+` file in the `+.m2+` folder in your home +directory (any OS): + +[source,xml] +---- + + + + + + snapshots + default-maven-virtual + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + + + true + + releases + default-maven-staging + https://s01.oss.sonatype.org/content/repositories/releases/ + + + nexus + + + + +nexus + \ No newline at end of file diff --git a/docs/workloads/architecture/modules/core_messaging_module.adoc b/docs/workloads/architecture/modules/core_messaging_module.adoc new file mode 100644 index 000000000..ed9379d29 --- /dev/null +++ b/docs/workloads/architecture/modules/core_messaging_module.adoc @@ -0,0 +1,302 @@ += Stacks Core CQRS module + +== Module Overviewlink:#module-overview[​] + +This module provides functionality to implement a basic CQRS +functionality, by using the `+ApplicationCommand+` and +`+CommandHandler+` classes. Please refer to sny of the +https://github.com/amido/stacks-java-cqrs/[CQRS] and +https://github.com/amido/stacks-java-cqrs-events/[CQRS with Events] +Stacks workload templates. + +== Module Structurelink:#module-structure[​] + +In the following diagram, you can see all the relevant files of this +module. Be aware, pulling from the repository will have some extra files +that are not relevant to the logic but required to build and deploy. + +=== Project structurelink:#project-structure[​] + +[source,shell] +---- +java +\_.mvn +: |_settings.xml +|_archetype.properties +|_pom.xml +\_src +: \_main +: \_java +: \_com.amido.stacks.core.cqrs +: \_command +: |CommandHandler.java +: \_handler +: |_CommandHandler.java +---- + + +== How to uselink:#how-to-use[​] + +There are four ways to integrate this module into your project: + +* Use it as a link:#use-it-as-a-dependency[dependency] +* Create a localized solution using +link:#localized-solution-using-maven-archetypes[Maven Archetypes +artifacts] available in our Artifactory repo +* Clone this repo, +link:#building-the-module-locally-from-this-repository[locally build] +and use it as a Maven dependency +* Clone this repo, create a +link:#creating-an-archetype-from-this-repository[custom archetype] and +then use it as a Maven dependency + +=== Use it as a dependency[[use-it-as-a-dependency]] + +==== Mavenlink:#maven[​] + +In the `+dependencies+` section of your application's `+pom.xml+` add: + +[source,xml] +---- + + com.amido.stacks.modules + stacks-core-cqrs + 1.0.0 + +---- + + +Then you can do a `+./mvnw clean compile+` to fetch it; after that, you +can use it like any other dependency. + +[source,shell] +---- +./mvnw clean compile +---- + + +==== Otherslink:#others[​] + +Use it as you'd use any dependency in your build tool. + +=== Localized solution using Maven Archetypes[[localized-solution-using-maven-archetypes]] + +If you wish to customise the module and use your organisation's +namespaces instead of Amido's. You can create a +https://maven.apache.org/archetype/index.html[Maven archetype]. +Archetype is Maven's tool for scaffolding and offers lots of extra +functionality. We suggest spending some time looking into them. We use +Archetype to create a template and enable you to adopt this module under +your organisation's namespace. To use the deployed archetypes: + +. Make and move to a new folder +. Then run ++ +[source,shell] +---- +mvn archetype:generate \ + -DarchetypeGroupId='com.amido.stacks.modules' \ + -DarchetypeArtifactId='stacks-core-cqrs-archetype' \ + -DarchetypeVersion='' \ + -DgroupId='' \ + -DartifactId='' \ + -Dversion='' \ + -Dpackage='' +---- + + +* `++` is a placeholder for your group ID +* `++` is a placeholder for your artefact ID +* `++` is a placeholder for your version +* `++` is a placeholder for the root package name and +structure. It should start with your `+groupdId+` and continue with the +name of the root package. ++ +____ +For example, using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) +____ +. Go to the `+pom.xml+` file of the project you'll be using this module +in and add it as a link:#use-it-as-a-dependency[dependency] + +*Example*: Using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) + +____ +*If you previously had used this module under different namespace (i.e. +the default `+com.amido.stacks.core-cqrs+`):* + +Maven ONLY updates the imports for the module you generated. Any +references in other projects will remain to the previous namespace. + +You will need to + +* Update them manually +* Re-create the relevant `+import+` statements to use the new-made +module instead +* If you plan to use this with Amido Stacks, include your namespace in +the `+@ComponentScan+` annotation of the `+Application+` class. +____ + +=== Building the module locally from this repository[[building-the-module-locally-from-this-repository]] + +To build the module locally: + +. Clone this repo +. Navigate to the `+java+` folder +. run `+./mvnw clean install+` to install the module locally. +. Add it as any other link:#use-it-as-a-dependency[dependency] + +=== Creating an Archetype from this repository[[creating-an-archetype-from-this-repository]] + +If you wish to customise the module and use your organisation's +namespaces instead of Amido's. You can create a +https://maven.apache.org/archetype/index.html[Maven archetype]. +Archetype is Maven's tool for scaffolding and offers lots of extra +functionality. We suggest spending some time looking into them. We use +Archetype to create a template and enable you to adopt this module under +your organisation's namespace. To use the deployed archetypes: To build, +install and use the archetype follow these steps: + +. Clone this repo +. Navigate to the `+/java+` in +the terminal +. Then issue the following Maven commands, using the included wrapper: +.. Create the archetype from the existing code ++ +[source,shell] +---- +./mvnw archetype:create-from-project -DpropertyFile='./archetype.properties' +---- + + +.. Navigate to the folder it was created in ++ +[source,shell] +---- +cd target/generated-sources/archetype +---- + +.. Install the archetype locally ++ +[source,shell] +---- +..\..\..\mvnw install +---- + +. Make and navigate to a directory in which you'd like to create the +localized project, ideally outside this project's root folder +. To create the project, use the command below: ++ +[source,prism-code,language-bash,codeBlock_rtdJ,thin-scrollbar] +---- +/mvnw archetype:generate \ + -DarchetypeGroupId='com.amido' \ + -DarchetypeArtifactId='stacks-core-cqrs' \ + -DarchetypeVersion='1.0.0-SNAPSHOT' \ + -DgroupId='' \ + -DartifactId='' \ + -Dversion='' \ + -Dpackage=''` +---- + +.. `++` is a placeholder for your group ID +.. `++` is a placeholder for your artefact ID +.. `++` is a placeholder for your version +.. `++` is a placeholder for the root package name and +structure. It should start with your `+groupdId+` and continue with the +name of the root package. ++ +____ +For example, using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) +____ +. Go to the `+pom.xml+` file of the project you'll be using this module +in and add it as a link:#use-it-as-a-dependency[dependency] + +*Example*: Using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) + +____ +*If you previously had used this module under different namespace (i.e. +the default `+com.amido.stacks.core-cqrs+`):* + +Maven ONLY updates the imports for the module you generated. Any +references in other projects will remain to the previous namespace. + +You will need to + +* Update them manually +* Re-create the relevant `+import+` statements to use the new-made +module instead +* If you plan to use this with Amido Stacks, include your namespace in +the `+@ComponentScan+` annotation of the `+Application+` class. +____ + +== Accessing Sonatype OSSRHlink:#accessing-sonatype-ossrh[​] + +Our artefacts and archetypes get hosted on Sonatype OSSRH then to maven +central . to access artifact from OSSRH before it get published to maven +central update `+pom.xml+`: + +[source,xml] +---- + + + + snapshots + default-maven-virtual + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + + + true + + releases + default-maven-staging + https://s01.oss.sonatype.org/content/repositories/releases/ + + +---- + + +Alternatively, you can also add this configuration as a profile in your +Maven's `+settings.xml+` file in the `+.m2+` folder in your home +directory (any OS): + +[source,xml] +---- + + + + + + snapshots + default-maven-virtual + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + + + true + + releases + default-maven-staging + https://s01.oss.sonatype.org/content/repositories/releases/ + + + nexus + + + + +nexus + +---- diff --git a/docs/workloads/architecture/modules/parent_module.adoc b/docs/workloads/architecture/modules/parent_module.adoc new file mode 100644 index 000000000..d315ecfc9 --- /dev/null +++ b/docs/workloads/architecture/modules/parent_module.adoc @@ -0,0 +1,277 @@ += Stacks Parent module + +== Module Overviewlink:#module-overview[​] + +This parent module provides shared functionality to the Stacks java +modules. It's based on Spring and contains the dependency management, +shared properties, plugins, profiles, reporting and repositories. It's +intended to be the parent module for Amido Stacks but can also get used +in your project. + +== Module Structurelink:#module-structure[​] + +In the following diagram, you can see all the relevant files of this +module. Be aware, pulling from the repository will have some extra files +that are not relevant to the logic but required to build and deploy. + +=== Project structurelink:#project-structure[​] + +[source] +---- +java +\_.mvn +: |_settings.xml +|_archetype.properties +|_pom.xml +---- + +== How to uselink:#how-to-use[​] + +There are four ways to integrate this module into your project: + +* Use it as a link:#use-it-as-a-dependency[dependency] +* Create a localized solution using +link:#maven-atypes[Maven Archetypes] +artifacts>> available in our Artifactory repo +* Clone this repo, +link:#locally-build[locally build] +and use it as a Maven dependency +* Clone this repo, create a +link:#custom-atypes[custom archetype] and +then use it as a Maven dependency + +=== Use it as a dependency[[use-it-as-a-dependency]] + +==== Mavenlink:#maven[​] + +In the `+parent+` section of your application's `+pom.xml+` add: + +[source,xml] +---- + + com.amido.stacks.modules + stacks-modules-parent + 1.0.0 + +---- + +Then you can do a `+./mvnw clean compile+` to fetch it; after that, you +can use it like any other dependency. + +[source,shell] +---- +./mvnw clean compile +---- + + +==== Otherslink:#others[​] + +Use it as you'd use any dependency in your build tool. + +=== Localized solution using Maven Archetypes[[maven-atypes]] + +If you wish to customise the module and use your organisation's +namespaces instead of Amido's. You can create a +https://maven.apache.org/archetype/index.html[Maven archetype]. +Archetype is Maven's tool for scaffolding and offers lots of extra +functionality. We suggest spending some time looking into them. We use +Archetype to create a template and enable you to adopt this module under +your organisation's namespace. To use the deployed archetypes: + +. Make and move to a new folder +. Then run ++ +[source,shell] +---- +mvn archetype:generate \ + -DarchetypeGroupId='com.amido.stacks.modules' \ + -DarchetypeArtifactId='stacks-modules-parent-archetype' \ + -DarchetypeVersion='' \ + -DgroupId='' \ + -DartifactId='' \ + -Dversion='' \ + -Dpackage='' +---- + +* `++` is a placeholder for your group ID +* `++` is a placeholder for your artefact ID +* `++` is a placeholder for your version +* `++` is a placeholder for the root package name and +structure. It should start with your `+groupdId+` and continue with the +name of the root package. ++ +____ +For example, using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) +____ +. Go to the `+pom.xml+` file of the project you'll be using this module +in and add it as a link:#use-it-as-a-dependency[dependency] + +____ +*If you previously had used this module under different namespace (i.e. +the default `+com.amido.stacks.core-api+`):* + +Maven ONLY updates the imports for the module you generated. Any +references in other projects will remain to the previous namespace. + +You will need to + +* Update them manually +* Re-create the relevant `+import+` statements to use the new-made +module instead +* If you plan to use this with Amido Stacks, include your namespace in +the `+@ComponentScan+` annotation of the `+Application+` class. +____ + +=== Building the module locally from this repository[[locally-build]] + +To build the module locally: + +. Clone this repo +. Run `+./mvnw clean install+` to install the module locally. +. Add it as any other link:#use-it-as-a-dependency[dependency] + +=== Creating an Archetype from this repository[[custom-atypes]] + +If you wish to customise the module and use your organisation's +namespaces instead of Amido's. You can create a +https://maven.apache.org/archetype/index.html[Maven archetype]. +Archetype is Maven's tool for scaffolding and offers lots of extra +functionality. We suggest spending some time looking into them. We use +Archetype to create a template and enable you to adopt this module under +your organisation's namespace. To use the deployed archetypes: To build, +install and use the archetype follow these steps: + +. Clone this repo +. Navigate to the `++` in the +terminal +. Then issue the following Maven commands, using the included wrapper: +.. Create the archetype from the existing code ++ +[source,prism-code,language-bash,codeBlock_rtdJ,thin-scrollbar] +---- +./mvnw archetype:create-from-project -DpropertyFile='./archetype.properties' +---- + +.. Navigate to the folder it was created in ++ +[source,prism-code,language-bash,codeBlock_rtdJ,thin-scrollbar] +---- +cd target/generated-sources/archetype +---- + +.. Install the archetype locally ++ +[source,prism-code,language-bash,codeBlock_rtdJ,thin-scrollbar] +---- +..\..\..\mvnw install +---- + +. Make and navigate to a directory in which you'd like to create the +localized project, ideally outside this project's root folder +. To create the project, use the command below: ++ +[source,prism-code,language-bash,codeBlock_rtdJ,thin-scrollbar] +---- +/mvnw archetype:generate \ + -DarchetypeGroupId='com.amido' \ + -DarchetypeArtifactId='stacks-modules-parent-archetype' \ + -DarchetypeVersion='' \ + -DgroupId='' \ + -DartifactId='' \ + -Dversion='' \ + -Dpackage=''` +---- + +.. `++` is a placeholder for your group ID +.. `++` is a placeholder for your artefact ID +.. `++` is a placeholder for your version +.. `++` is a placeholder for the root package name and +structure. It should start with your `+groupdId+` and continue with the +name of the root package. ++ +____ +For example, using `+-DgroupId=com.test+` and +`+-Dpackage=com.test.stacks+` will instruct Maven to place the code in +`+src/main/java/com/test/stacks+` and update all the relevant references +accordingly (i.e. `+imports+`) +____ +. Go to the `+pom.xml+` file of the project you'll be using this module +in and add it as a link:#use-it-as-a-dependency[dependency] + +____ +*If you previously had used this module under different namespace (i.e. +the default `+com.amido.stacks.core-api+`):* + +Maven ONLY updates the imports for the module you generated. Any +references in other projects will remain to the previous namespace. + +You will need to + +* Update them manually +* Re-create the relevant `+import+` statements to use the new-made +module instead +* If you plan to use this with Amido Stacks, include your namespace in +the `+@ComponentScan+` annotation of the `+Application+` class. +____ + +== Accessing Sonatype OSSRHlink:#accessing-sonatype-ossrh[​] + +Our artefacts and archetypes get hosted on Sonatype OSSRH then to maven +central . to access artifact from OSSRH before it get published to maven +central update `+pom.xml+`: + +[source,xml] +---- + + + + snapshots + default-maven-virtual + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + + + true + + releases + default-maven-staging + https://s01.oss.sonatype.org/content/repositories/releases/ + + +---- + +Alternatively, you can also add this configuration as a profile in your +Maven's `+settings.xml+` file in the `+.m2+` folder in your home +directory (any OS): + +[source,xml] +---- + + + + + + snapshots + default-maven-virtual + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + + + true + + releases + default-maven-staging + https://s01.oss.sonatype.org/content/repositories/releases/ + + + nexus + + + + +nexus + +---- \ No newline at end of file diff --git a/docs/workloads/ide_guidlines.adoc b/docs/workloads/ide_guidlines.adoc new file mode 100644 index 000000000..0a3a40d2c --- /dev/null +++ b/docs/workloads/ide_guidlines.adoc @@ -0,0 +1,135 @@ += IDE guidelines for the Java Rest API + +== IDE guidelines + +The IDE we have used is Intellij. + +We recommend that you install the following plugins: + +* Lombok - To reduce the amount of boiler-plate code that needs to be +written +* SonarLint - Fix and detect code quality issues +(https://www.sonarlint.org/) +* Spring Assistant - An IntelliJ plugin for aiding Spring development +projects (https://plugins.jetbrains.com/plugin/10229-spring-assistant) +* Spring Tools - Adds Spring support for IDEs (https://spring.io/tools) +* CheckStyle - Flags up issues with coding style +(https://checkstyle.sourceforge.io/) +* google-java-format Formatter - Formats code according to configuration +(https://github.com/amido/stacks-java/blob/master/tools/formatter/intellij-java-google-style.xml) + +=== Plugins used in POM + +* Lombok - Avoids need to write e.g. Getter, Setter, +RequiredArgsConstructor, ToString, EqualsAndHashCode) in Java classes. +* JaCoCo - A free Java code test coverage library. +* Surefire - Used for reporting purposes (creates reports based on tests +in the Java test package). +* fmt-maven-plugin - Formats the java code based on rules in +java-google-style.xml. +* Spotbugs - Performs a static analysis of the Java code to check for +bugs. + +=== Set up the project + +==== How to import the whole project + +In the IDE(We used Intellij) go to File -> New -> Project. Set project +SDK to Java 11. Click Next -> Next +image:https://stacks.amido.com/assets/images/new_java_project-e8e9490f10c6649dbb58791306565548.png[New +Project] + +Choose the java project folder +image:https://stacks.amido.com/assets/images/new_java_project_1-7a59f9d8d8bc4f4cc5c0f56c0a56a748.png[New +Java Project] click finish. + +==== What setup required to get it up and running + +Open up the "java" folder and right click on pom.xml and choose "Add as +Maven Project". Click on Run -> Edit Configurations +image:https://stacks.amido.com/assets/images/run_configuration-8e78ac0c89d26029063ad8ed1978e076.png[Run +Configurations] Click on Add new Configuration and choose +Application/Spring boot +image:https://stacks.amido.com/assets/images/run_configuration_1-77d3b8880dec264fc3ef5534a982cec2.png[Run +Configurations_1] Choose the main class as "Application.java" and set +any relevant variables, such as to set environment variable for +*AZURE_COSMOSDB_KEY* and set JRE to Java 11. Click OK +image:https://stacks.amido.com/assets/images/run_configuration_2-c59de32a330a307b01632b81da844e19.png[Run +Configurations_2] + +Open Application.java file and right click and choose run +Application.image:https://stacks.amido.com/assets/images/run_java_application-5850fef9cbf5f332cbf52792d4b1c7e6.png[Run +Java Application] + +=== Code Quality + +==== Formatter + +Install the `intellij-java-google-style.xml` formatter configuration +file into the IDE from +https://github.com/amido/stacks-java/blob/master/tools/formatter/intellij-java-google-style.xml[here]. + +The Java source code will automatically be reformatted to comply with +the https://google.github.io/styleguide/javaguide.html[Google Java +Style]. + +You can override the settings locally in the codebase by adding, for +example: + +[source,prism-code] +---- +//@formatter:off +manually formatted code +///@formatter:on +---- + +===== Validating and applying formatting + +From the `/java` folder run + +* Unix + +[source,shell] +---- +./mvnw com.coveo:fmt-maven-plugin:check +---- + +* Windows + +[source,shell] +---- +mvnw.cmd com.coveo:fmt-maven-plugin:check +---- + +To validate the current formatting. You can then run the below code to +apply formatting to the source code. + +* Unix + +[source,shell] +---- +./mvnw com.coveo:fmt-maven-plugin:format +---- + +* Windows + +[source,shell] +---- +mvnw.cmd com.coveo:fmt-maven-plugin:format +---- + +==== Verifying common programming flaws + +* Unix + +[source,shell] +---- +./mvnw spotbugs:check +---- + +* Windows + +[source,shell] +---- +mvnw.cmd spotbugs:check +---- \ No newline at end of file diff --git a/docs/workloads/introduction.adoc b/docs/workloads/introduction.adoc new file mode 100644 index 000000000..dc4f6721a --- /dev/null +++ b/docs/workloads/introduction.adoc @@ -0,0 +1,27 @@ += Introduction to workloads + +Workload options cover all the supported options around what type of cloud infrastructure to provision for a project. + +The key difference between workload and package options is when architectural decisions around their adoption are made on a project. Decisions around which workload options to use are made up front in a project’s life cycle while the high level solution architecture is being agreed (this usually occurs during a project’s discovery phase). Package Options may be decided on or implemented at any point during a project’s life cycle. + +Adopting Stacks for your project is not an all or nothing decision; every part of the Stacks menu can be independently used and reused. For example, a project may choose to run a different compute workload than Stacks currently supports, but still adopt the Stacks Packages and supported workloads around testing. + +== Workload options +Workload options are enacted in Stacks using the scaffolding CLI as a “run once” activity to provision a workload. + +A chosen workload option generates a scaffolded workload to deploy into the cloud, such as a Web API or a Web Application. + +Workload options are broken down into the following types of workload: + +* Workloads for compute, which covers all the workload options that run in the cloud for compute, such as Web Applications and Web APIs; +* Workloads for test, which covers all the workload options that run automated tests in the cloud; +* Workloads for storage, which covers all the workload options that run in the cloud storage, such as relational and non-relational storage options. + +== Workload cloud capabilities +One of the primary functions of Stacks is to demonstrate the use of different technologies across multiple cloud providers. + +Some aspects of stacks are shared and cloud-agnostic and as such are provided by common modules, whilst other capabilities are relevant to a specific cloud platform. + +This exhibits itself through the use of Cloud capability modules that provide the functionality pertaining to that provided by a specific cloud platform. + +Examples of this is the use of CosmosDB as persistence for Azure and DynamodDB for AWS; capabilities are more often than not provided as specific modules that can be selected at runtime. \ No newline at end of file diff --git a/docs/workloads/maven_and_spring_profiles.adoc b/docs/workloads/maven_and_spring_profiles.adoc new file mode 100644 index 000000000..99b74b394 --- /dev/null +++ b/docs/workloads/maven_and_spring_profiles.adoc @@ -0,0 +1,292 @@ += Maven & Spring Profiles + +== Introduction + +This page describes the use of Maven Build profiles and Spring profiles +to support the use of feature sets within Stacks. The term 'feature +sets' means provider support for common tasks such as persistence and +message queue handling. It allows the selection of different mechanisms +across different cloud providers (such as the use of CosmosDB on Azure, +or DynamoDB on AWS). + +== Maven Build Profiles + +Maven build profiles can be used to create customised build +configurations, like targeting a level of test granularity or a specific +deployment environment or feature set. + +The profiles are specified in the applications `pom.xml` and provide +the capability for a number of different elements of the project object +model, such as dependencies and properties to be overridden by passing +switches at startup. The profiles are available to all Maven lifecycles +such as compile, test and package. + +An example of a profile definition is shown below: - + +[source,xml] +---- + + aws + + + . + + + + aws + + + + + +---- + +It is possible to specify profiles as being active via a number of +mechanisms (one option is show above) and then for these to be enabled +or disabled on the command line as per requirements. + +An example of starting the application and specifying profiles is as +follows - this command switches off the `aws` profile and switches on +the `azure` profile: - + +[source,shell] +---- +mvn clean spring-boot:run -P-aws,azure +---- + +== Spring Profiles + +Spring Profiles are a core feature of the Spring framework, allowing +developers to map beans and properties to different profiles. + +Activating a certain profile can have a huge effect on a Spring Boot +application, but under the hood, a profile can merely control two +things: + +* a profile may influence the application properties, and +* a profile may influence which beans are loaded into the application +context + +In the Java code it is possible to specify that Spring beans should only +be loaded into the context if the profile has been activated: - + +[source,java] +---- +@Component +@Profile("foo") +public class FooBean { ... } +---- + +When using Spring Boot any application properties are typically placed +into a file under `+resources+` called `application.yml` (or +alternatively `application.properties`). + +When using Spring Profiles it is possible to create individual +application property files per profile; this gives a clean separation +between property settings. The example below shows properties that are +only loaded (and overlay any similarly named properties in the base +file) if the relevant profile is activated on the command line. + + +=== application-aws.yml + +[source,yaml] +---- +aws: + xray: + enabled: ${AWS_XRAY_ENABLED:false} + secretsmanager: + enabled: ${AWS_SECRETS_ENABLED:false} +---- + +=== application-azure.yml + +[source,yaml] +---- +azure: + application-insights: + instrumentation-key: xxxxxx + enabled: true +---- +There are multiple ways to specify the profiles at application startup. +A few examples are shown below: + +[source,shell] +---- +export SPRING_PROFILES_ACTIVE=foo,bar +java -jar profiles-0.0.1-SNAPSHOT.jar +---- + +[source,shell] +---- +java -Dspring.profiles.active=foo -jar profiles-0.0.1-SNAPSHOT.jar +---- +== Stacks Profile Usagelink:#stacks-profile-usage[​] + +Stacks projects have been configured with both Maven and Spring profiles +in order to support the capability of being able to easily isolate +dependencies and properties between feature sets (such as cloud +provider, persistence and messaging). + +The ultimate aim of Stacks is for a project to be able to deploy an +instance that is as close to developer-written code as possible, whilst +still providing a rich feature set that projects can choose from. It is +also a requirement to make the Stacks maintainer experience as simple as +possible and to allow developers and testers an easy way to switch +between feature sets whilst providing a platform for them to extend +Stacks with new feature sets in the future. + +The use of both profile mechanisms allow dependencies and properties to +be nicely ring-fenced, making it relatively easy for supporting scripts +to be able to re-package the Stacks project and for it to be tailored +more closely to a projects requirements. + +The three Stacks workloads differ slightly in their provided capability, +so this text will now focus on the Stacks CQRS with Events project as +that provides the richest set of features. + +The following areas within the project have been configured to provide +profile support: - + +. `pom.xml` - default properties assigned for all features +. `pom.xml` - Maven build profiles created, one per feature +. `resources/application.yml` - set of Spring profiles to auto-include +based on flags passed to Maven (see `spring.profiles.include`) +. `resources/application-PROFILE_NAME.yml` - application properties +specific to each feature + +As per the section above on Maven Build Profiles it can be seen that a +few of the profiles have been enabled by default. This is to provide +backwards-compatibility and to ensure that the application runs even if +no profiles are specified on the command line. The profiles that have +been enabled at this time by default are `+aws+`, `azure`, +`cosmosdb` and `servicebus`. + +To start the application using a different configuration, say to use +`dynamodb` and `+sqs+` instead, the following command can be used to +switch off the profiles that aren't required and activate the ones that +are. Remember that some profiles are always activated (unless switched +off by prefixing with a `-` character) so these do not need to be +explicitly specified: - + +[source,shell] +---- +mvn clean spring-boot:run -Pdynamodb,sqs,-cosmosdb,-servicebus +---- + +Note that some profiles are mutually exclusive (the persistence and +messaging handler profiles) so the application will fail at startup if +invalid (overlapping) profiles are specified. + +== Support Scripts + +A number of support scripts are included in the projects that aid in the +use of profiles. + +____ +⚠️ The Cloud-related profiles (*AWS & Azure*) do not currently provide +as clean a separation of dependencies as possible - all library +dependencies will be included irrespective of whether they are selected +or not - this issue will be fixed in a later release. +____ + +=== run_scenario.sh + +This script is aimed at *Stacks developers & testers*. + +This bash script provides a command line interface to the user to allow +them to select the feature sets they want to start the Spring Boot +application with. + +After making their choices it will display the Maven command that will +be executed, and then optionally run it for the user. + +[source,bash] +---- +sh run_scenario.sh + +1. Please select the Cloud required: + + [x] azure (Azure Cloud) + [x] aws (AWS Cloud) + +2. Please select the Persistence required: + + [ ] cosmosdb (CosmosDB) + [x] dynamodb (DynamoDB) + +3. Please select the Message Handler required: + + [ ] servicebus (Azure ServiceBus) + [ ] kafka (AWS Kafka) + [x] sqs (AWS SQS) + +You have selected these options for your project: + + * azure + * aws + * dynamodb + * sqs + +About to execute: + + mvn clean spring-boot:run -Pazure,aws,dynamodb,sqs,-cosmosdb,-servicebus + +Press ENTER to accept or CTRL-C to quit +---- + +=== deploy_scenario.sh + +This script is aimed at *Stacks adopters & end projects*. + +This bash script provides a command line interface to the user to allow +them to select the feature sets they want to deploy the Spring Boot +application with. After making their feature set choice it will alter +the code project from being one that supports multiple feature sets to +being one that has the features baked-in. + +[source,bash] +---- +sh deploy_scenario.sh + +1. Please select the Cloud required: + + [x] azure (Azure Cloud) + [x] aws (AWS Cloud) + +2. Please select the Persistence required: + + [ ] cosmosdb (CosmosDB) + [x] dynamodb (DynamoDB) + +3. Please select the Message Handler required: + + [ ] servicebus (Azure ServiceBus) + [x] kafka (AWS Kafka) + [ ] sqs (AWS SQS) + +You have selected these options for your project: + + * azure + * aws + * dynamodb + * kafka + +Press ENTER to accept or CTRL-C to quit +---- + +After pressing ENTER the script will perform the following actions: - + +. Move feature-set related Maven Dependencies to the main library +dependencies section in `pom.xml` +. Remove any non-required feature-set related Maven Build profiles from +`pom.xml` +. Remove any non-required feature-set related Maven Build properties +from `pom.xml` +. Hard-code the feature-set related Spring Profile list in +`+application.yml+` (and remove any unused profiles) +. Remove any non-required Spring profile +`resources/application-PROFILE_NAME.yml` files + +After these operations the Stacks project code should be closer to how a +Project would manually craft their application code. \ No newline at end of file diff --git a/docs/workloads/using_maven_scaffolding.adoc b/docs/workloads/using_maven_scaffolding.adoc new file mode 100644 index 000000000..eb731cb5c --- /dev/null +++ b/docs/workloads/using_maven_scaffolding.adoc @@ -0,0 +1,63 @@ += Using the Maven Scaffolding to create the Java project template + +== Create a custom Java project template from the command linelink:#create-a-custom-java-project-template-from-the-command-line[​] + +video::640390929[vimeo] + +:icons: font +[CAUTION] +Before starting, if using Azure please make sure that your environment +meets all the +link:/TODO[requirements]. + +You can customize the deployment of the project running a handful of +command lines. Currently, scaffolding is handled by Maven and you can +use it by cloning one of the workload repositories and then installing +the project as a Maven archetype locally; from there, we can create a +new project by using that archetype as a template. To do so we do: + +. Clone any of the Stacks Java Workloads (`simple-api`, +`stacks-java-cqrs` or `stacks-java-cqrs-events`) +. Navigate to the `/java` in +the terminal +. Then issue the following Maven commands, using the included wrapper: +.. `./mvnw archetype:create-from-project -DpropertyFile=archetype.properties` - To create the archetype +.. `cd target/generated-sources/archetype` - Navigate to the folder +it was created in +.. `..\..\..\mvnw install` - Install the archetype locally +. Now, navigate to a directory in which you'd like to crate the +localized project into +. To create the project we do: ++ +[source,shell] +---- +/mvn archetype:generate \ + -DarchetypeGroupId='com.amido.stacks.workloads' \ + -DarchetypeArtifactId='' \ + -DarchetypeVersion='' \ + -DgroupId='' \ + -DartifactId='' \ + -Dversion='' \ + -Dpackage=' +---- + + +... `` refers to the archetype name ID, as that +was created above. That ID is made of the artifact name of the original +project as declared in its `pom.xml` suffixed with `-archetype` +.. For example: `stacks-api-cqrs-events-archetype`. The name can also +be observed in the log created from the first command above. +... `` should be taken from the `pom.xml` of the +original project +... `` is a placeholder for your group ID +... `` is a placeholder for your artifact ID +... `` is a placeholder for your version +... `` is a placeholder for the root package name +and structure. +.. For example, using `com.test.stacks` will instruct Maven to place +the code in `src/main/java/com/test/stacks` and update all the +relevant references accordingly (i.e. `imports`) + +[NOTE] +For now, until the release of the Amido STACKS CLI Tool v2 is released, +this is the only way to get started with Stacks. \ No newline at end of file