Skip to content

Commit

Permalink
fix(archunit): Update ArchUnit template, validate names when generati…
Browse files Browse the repository at this point in the history
…ng model or usecases (#548)

* fix(archunit): Update ArchUnit template, validate names when generating model or usecases
* update docs
  • Loading branch information
juancgalvis authored Sep 19, 2024
1 parent 385b7be commit 6d80baf
Show file tree
Hide file tree
Showing 14 changed files with 854 additions and 31 deletions.
8 changes: 4 additions & 4 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Before submitting a pull request, please read
https://github.com/bancolombia/scaffold-clean-architecture/wiki/Contributing
https://bancolombia.github.io/scaffold-clean-architecture/docs/contributing

## Description
<!--- Describe your changes in detail -->
Expand All @@ -10,10 +10,10 @@ https://github.com/bancolombia/scaffold-clean-architecture/wiki/Contributing
- [ ] Ci / Docs

## Checklist
- [ ] The pull request is complete according to the [guide of contributing](https://github.com/bancolombia/scaffold-clean-architecture/wiki/Contributing)
- [ ] The pull request is complete according to the [guide of contributing](https://bancolombia.github.io/scaffold-clean-architecture/docs/contributing)
- [ ] Automated tests are written
- [ ] The documentation is up-to-date
- [ ] The pull request has a descriptive title that describes what has changed, and provides enough context for the changelog
- [ ] If the pull request has a new driven-adapter or entry-point, you should add it to docs and `sh_generate_project.sh` files for generated code tests.
- [ ] If the pull request has changed structural files, you have implemented an UpgradeAction according to the [guide](https://github.com/bancolombia/scaffold-clean-architecture/wiki/Contributing#upgradeaction)
- [ ] If the pull request has a new Gradle Task, you should add `Analytics` according to the [guide](https://github.com/bancolombia/scaffold-clean-architecture/wiki/Contributing#analytics)
- [ ] If the pull request has changed structural files, you have implemented an UpgradeAction according to the [guide](http://localhost:3000/scaffold-clean-architecture/docs/contributing#more-on-pull-requests)
- [ ] If the pull request has a new Gradle Task, you should add `Analytics` according to the [guide](http://localhost:3000/scaffold-clean-architecture/docs/contributing)
2 changes: 1 addition & 1 deletion docs/docs/2-getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ gradle tasks
---
You can follow one of the next steps to create a quick start project with commands

# Quick Start
## Quick Start

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Expand Down
414 changes: 414 additions & 0 deletions docs/docs/5-contributing.md

Large diffs are not rendered by default.

239 changes: 239 additions & 0 deletions docs/docs/advanced/1-arch-unit-analysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
---
sidebar_position: 1
---

# ArchUnit Analysis

This document describes how we use ArchUnit to enforce architectural constraints in your project.

## Predefined Architecture Rules

### Rule_1.5: Reactive flows should use aws async clients

![Static Badge](https://img.shields.io/badge/kind-Reactive%20Programming-blue)

This rule try to enforce the usage of AsyncClient variants of AWS SDK, for example the usage of `kmsAsyncClient` instead
of `kmsClient` in reactive flows using the `Mono.fromFuture` method.

### Rule_2.2: Domain classes should not be named with technology suffixes

![Static Badge](https://img.shields.io/badge/kind-Clean%20Architecture-blue)

This rule is intended to avoid the technical names usage in domain entities. We avoid UserDTO name instead of simply
define as User.

you can use the `gradle.properties` file to set the forbidden suffixes, by default is:

```properties
arch.unit.forbiddenDomainSuffixes=dto,request,response
```

Note that plugin will treat `dto` suffix also like `Dto` and `DTO`

> ❌ No Compliant
```java
package co.com.bancolombia.model.userrequest;

public class UserRequest {
private String name;
private String email;
}
```

> ✅ Compliant
```java
package co.com.bancolombia.model.user;

public class User {
private String name;
private String email;
}
```

### Rule_2.4: Domain classes should not be named with technology names

![Static Badge](https://img.shields.io/badge/kind-Clean%20Architecture-blue)

This rule is intended to avoid the technical names usage in domain entities, gateways and use cases. We avoid
DynamoUserGateway name instead of simply define as UserGateway.

you can use the `gradle.properties` file to set the forbidden partial class names, by default is:

```properties
arch.unit.forbiddenDomainClassNames=rabbit,sqs,sns,ibm,dynamo,aws,mysql,postgres,redis,mongo,rsocket,r2dbc,http,kms,s3,graphql,kafka
```

Note that plugin will treat `rabbit` suffix also like `Rabbit` and `RABBIT`

> ❌ No Compliant
```java
package co.com.bancolombia.model.rabbitmessage;

public class RabbitMessage {
private String contentType;
private byte[] content;
}
```

> ✅ Compliant
```java
package co.com.bancolombia.model.message;

public class Message {
private String contentType;
private byte[] content;
}
```

### Rule_2.7: Domain classes should not have fields named with technology names

![Static Badge](https://img.shields.io/badge/kind-Clean%20Architecture-blue)

The same purpose of `Rule_2.4` but applied to domain model fields or use case fields.

you can use the `gradle.properties` file to set the forbidden field names, by default is the same that `Rule_2.4`, and
can be override with the same property.

> ❌ No Compliant
```java
package co.com.bancolombia.model.message;

public class Message {
private String rabbitContentType;
private byte[] content;
}
```

> ✅ Compliant
```java
package co.com.bancolombia.model.message;

public class Message {
private String contentType;
private byte[] content;
}
```

### Rule_2.5: UseCases should only have final attributes to avoid concurrency issues

![Static Badge](https://img.shields.io/badge/kind-Concurrency%20Safe%20Code-blue)

This rule is designed to avoid the shared resources in concurrency, all dependencies of a Use Case should be immutable,
and each context call should have their own resources.

> ❌ No compliant
```java
package co.com.bancolombia.usecase.notifyusers;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class NotifyUsersUseCase {
private NotificationGateway notifier; // No Compliant
private User user; // No Compliant


public void notify(User user) {
this.user = user;
// some other business logic
this.sendMessage()
}

private void sendMessage() {
// send message througth class instance of user
notifier.send("notification", user.getEmail())
}
}
```

> ✅ Compliant
```java
package co.com.bancolombia.usecase.notifyusers;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class NotifyUsersUseCase {
private final NotificationGateway notifier; // Compliant

public void notify(User user) {
// some other business logic
this.sendMessage(user)
}

private void sendMessage(User user) {
// send message througth input instance of user
notifier.send("notification", user.getEmail())
}
}
```

### Rule_2.7: Beans classes should only have final attributes (injection by constructor) to avoid concurrency issues

![Static Badge](https://img.shields.io/badge/kind-Concurrency%20Safe%20Code-blue)

This rule is designed to avoid the shared resources in concurrency, all dependencies of a Bean should be immutable, and
each context call should have their own resources. We promote the dependencies injection through constructor over the
@Value annotated fields injection.

> ❌ No Compliant
```java

@Component
public class MyService {
@Value("${external-service.endpoint}")
private String endpoint; // No Compliant

public void someFunction(SomeObject domainObject) {
// ... logic that uses endpoint
}
}
```

> ✅ Compliant
```java

@Component
public class MyService {
private final String endpoint; // Compliant

public MyService(@Value("${external-service.endpoint}") String endpoint) {
this.endpoint = endpoint;
}

public void someFunction(SomeObject domainObject) {
// ... logic that uses endpoint
}
}
```

## Skip Rules

If you want to skip Arch Unit rules validation, you can use the `gradle.properties` file to add
`arch.unit.ski=true`.

We recommend not to skip the rules, but if you need to do it, you can add the property to the `gradle.properties` file.

For example:

```properties
package=co.com.bancolombia
systemProp.version=3.17.22
reactive=true
lombok=true
metrics=true
language=java
org.gradle.parallel=true
systemProp.sonar.gradle.skipCompile=true
arch.unit.skip=true # Skip Arch Unit rules validation
```
30 changes: 30 additions & 0 deletions docs/docs/advanced/2-use-as-updater.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
sidebar_position: 2
---

# Dependency Updater

We have many open source java projects, so we try to keep dependencies updated, for this purpose whe have enabled the
plugin to be used as a dependency updater. This is not the `updateCleanArchitecture` task, we have a different task for
this.

## Internal Task

This task is the created for that, and you can use it by following the next steps:

1. Add plugin to your `build.gradle` project file as described in the [Getting Started](/docs/2-getting-started.md)
section.
2. Add the following property to your `gradle.properties` file
like [commons-jms](https://github.com/bancolombia/commons-jms) project

```properties
onlyUpdater=true
```

3. Now you can run the task `internalTask` or alias `it` to update the dependencies of your project.

```bash
./gradlew it --action UPDATE_DEPENDENCIES
```

This tas will update gradle dependencies and gradle plugin versions.
8 changes: 8 additions & 0 deletions docs/docs/advanced/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"label": "Advanced Options",
"position": 4,
"link": {
"type": "generated-index",
"description": "Some specific settings and tasks."
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package co.com.bancolombia.exceptions;

public class CleanDomainException extends CleanUncheckedException {
public CleanDomainException(String message) {
super(message);
}
}
Loading

0 comments on commit 6d80baf

Please sign in to comment.