Skip to content

Commit

Permalink
feat : tweak archunit rules as per latest changes
Browse files Browse the repository at this point in the history
  • Loading branch information
rajadilipkolli committed Jun 19, 2024
1 parent dd05c0e commit f744ce7
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
package com.example.archunit.config;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
@Slf4j
public class Initializer implements CommandLineRunner {

private static final Logger LOGGER = LoggerFactory.getLogger(Initializer.class);

private final ApplicationProperties properties;

@Override
public void run(String... args) {
log.info("Running Initializer.....");
LOGGER.info("Running Initializer.....");
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
package com.example.archunit.config;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.servers.Server;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.servers.Server;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
@OpenAPIDefinition(info = @Info(title = "boot-api-archunit-sample", version = "v1"), servers = @Server(url = "/"))
public class SwaggerConfig {}
public class SwaggerConfig {

@Bean
OpenAPI openApi() {
return new OpenAPI()
.info(new Info()
.title("boot-api-archunit-sample")
.description("Client Service APIs")
.version("v1.0.0")
.contact(new Contact().name("Raja Kolli").email("[email protected]")))
.servers(List.of(new Server().url("/")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@

@Aspect
@Component
public class LoggingAspect {
class LoggingAspect {

private final Logger log = LoggerFactory.getLogger(this.getClass());
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingAspect.class);

private final Environment env;

Expand All @@ -41,7 +41,7 @@ public void applicationPackagePointcut() {
@AfterThrowing(pointcut = "applicationPackagePointcut()", throwing = "e")
public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
if (env.acceptsProfiles(Profiles.of(AppConstants.PROFILE_NOT_PROD))) {
log.error(
LOGGER.error(
"Exception in {}.{}() with cause = '{}' and exception = '{}'",
joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(),
Expand All @@ -50,7 +50,7 @@ public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
e);

} else {
log.error(
LOGGER.error(
"Exception in {}.{}() with cause = {}",
joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(),
Expand All @@ -60,17 +60,17 @@ public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {

@Around("applicationPackagePointcut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
if (log.isTraceEnabled()) {
log.trace(
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(
"Enter: {}.{}()",
joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName());
}
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
long end = System.currentTimeMillis();
if (log.isTraceEnabled()) {
log.trace(
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(
"Exit: {}.{}(). Time taken: {} millis",
joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
@RestController
@RequestMapping("/api/clients")
@RequiredArgsConstructor
public class ClientController {
class ClientController {

private final ClientService clientService;

@GetMapping
public ResponseEntity<PagedResult<ClientResponse>> getAllClients(
ResponseEntity<PagedResult<ClientResponse>> getAllClients(
@RequestParam(defaultValue = AppConstants.DEFAULT_PAGE_NUMBER, required = false) int pageNo,
@RequestParam(defaultValue = AppConstants.DEFAULT_PAGE_SIZE, required = false) int pageSize,
@RequestParam(defaultValue = AppConstants.DEFAULT_SORT_BY, required = false) String sortBy,
Expand All @@ -41,15 +41,15 @@ public ResponseEntity<PagedResult<ClientResponse>> getAllClients(
}

@GetMapping("/{id}")
public ResponseEntity<ClientResponse> getClientById(@PathVariable Long id) {
ResponseEntity<ClientResponse> getClientById(@PathVariable Long id) {
return clientService
.findClientById(id)
.map(ResponseEntity::ok)
.orElseThrow(() -> new ClientNotFoundException(id));
}

@PostMapping
public ResponseEntity<ClientResponse> createClient(@RequestBody @Validated ClientRequest clientRequest) {
ResponseEntity<ClientResponse> createClient(@RequestBody @Validated ClientRequest clientRequest) {
ClientResponse response = clientService.saveClient(clientRequest);
URI location = ServletUriComponentsBuilder.fromCurrentRequest()
.path("/api/clients/{id}")
Expand All @@ -59,13 +59,13 @@ public ResponseEntity<ClientResponse> createClient(@RequestBody @Validated Clien
}

@PutMapping("/{id}")
public ResponseEntity<ClientResponse> updateClient(
ResponseEntity<ClientResponse> updateClient(
@PathVariable Long id, @RequestBody @Valid ClientRequest clientRequest) {
return ResponseEntity.ok(clientService.updateClient(id, clientRequest));
}

@DeleteMapping("/{id}")
public ResponseEntity<ClientResponse> deleteClient(@PathVariable Long id) {
ResponseEntity<ClientResponse> deleteClient(@PathVariable Long id) {
return clientService
.findClientById(id)
.map(client -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,16 @@ static ArchRule privateMethodsAreNotAllowedRule(String packageName) {
.because("Private methods are not allowed in %s".formatted(packageName));
}

static ArchRule publicMethodsAreNotAllowedRule(String packageName) {
return methods()
.that()
.areDeclaredInClassesThat()
.resideInAPackage(packageName)
.should()
.notBePublic()
.because("Public methods are not allowed in %s".formatted(packageName));
}

static ArchRule staticMethodsAreNotAllowedRule(String packageName) {
return methods()
.that()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static com.example.archunit.architecture.CommonRules.fieldsShouldNotBePublic;
import static com.example.archunit.architecture.CommonRules.privateMethodsAreNotAllowedRule;
import static com.example.archunit.architecture.CommonRules.publicConstructorsRule;
import static com.example.archunit.architecture.CommonRules.publicMethodsAreNotAllowedRule;
import static com.example.archunit.architecture.CommonRules.staticMethodsAreNotAllowedRule;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.methods;
Expand Down Expand Up @@ -44,6 +45,14 @@ class ControllerRulesTest {
.because(ANNOTATED_EXPLANATION.formatted(CONTROLLER_SUFFIX, "@RestController")
+ ", and not with @Controller");

@ArchTest
static final ArchRule classes_should_not_be_public = classes()
.that()
.resideInAPackage(CONTROLLER_PACKAGE)
.should()
.bePackagePrivate()
.because("Classes in %s package should be declared package-private");

// Fields
@ArchTest
static final ArchRule fields_should_not_be_public = fieldsShouldNotBePublic(CONTROLLER_PACKAGE);
Expand All @@ -59,13 +68,16 @@ class ControllerRulesTest {
@ArchTest
static final ArchRule private_methods_are_not_allowed = privateMethodsAreNotAllowedRule(CONTROLLER_PACKAGE);

@ArchTest
static final ArchRule public_methods_are_not_allowed = publicMethodsAreNotAllowedRule(CONTROLLER_PACKAGE);

@ArchTest
static final ArchRule static_methods_are_not_allowed = staticMethodsAreNotAllowedRule(CONTROLLER_PACKAGE);

@ArchTest
static final ArchRule methods_should_return_response_entity = methods()
.that()
.arePublic()
.arePackagePrivate()
.and()
.areDeclaredInClassesThat()
.resideInAPackage(CONTROLLER_PACKAGE)
Expand All @@ -76,7 +88,7 @@ class ControllerRulesTest {
@ArchTest
static final ArchRule methods_should_be_annotated_with_valid_annotations = methods()
.that()
.arePublic()
.arePackagePrivate()
.and()
.areDeclaredInClassesThat()
.resideInAPackage(CONTROLLER_PACKAGE)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.example.archunit.architecture;

import static com.example.archunit.architecture.ArchitectureConstants.DEFAULT_PACKAGE;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.fields;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.methods;
import static com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS;
import static com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_THROW_GENERIC_EXCEPTIONS;
import static com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_USE_JAVA_UTIL_LOGGING;
Expand All @@ -10,6 +12,8 @@
import com.tngtech.archunit.junit.AnalyzeClasses;
import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.lang.ArchRule;
import org.slf4j.Logger;
import org.springframework.context.annotation.Bean;

@AnalyzeClasses(packages = DEFAULT_PACKAGE, importOptions = ImportOption.DoNotIncludeTests.class)
class GeneralCodingRulesTest {
Expand All @@ -30,28 +34,35 @@ class GeneralCodingRulesTest {
static final ArchRule noJavaUtilLogging =
NO_CLASSES_SHOULD_USE_JAVA_UTIL_LOGGING.because("Use org.slf4j.Logger instead");

/*
//Fields
// Fields
@ArchTest
static final ArchRule loggersShouldBePrivateStaticAndFinal = fields().that().haveRawType(Logger.class)
.should().bePrivate()
.andShould().beStatic()
.andShould().beFinal()
.andShould().haveName("LOGGER")
static final ArchRule loggersShouldBePrivateStaticAndFinal = fields().that()
.haveRawType(Logger.class)
.should()
.bePrivate()
.andShould()
.beStatic()
.andShould()
.beFinal()
.andShould()
.haveName("LOGGER")
.because("Logger variables should be private, static and final, and it should be named as LOGGER");

/*
@ArchTest
static final ArchRule finalStaticVariablesInUppercase = fields().that().areStatic().and().areFinal()
.and().doNotHaveName("serialVersionUID")
.and().doNotHaveModifier(JavaModifier.SYNTHETIC)
.should().haveNameMatching(".*^[A-Z].*")
.because("Variables with static and final modifiers should be named in uppercase");
//Methods
@ArchTest
static final ArchRule beanMethodsShouldBePublic = methods().that().areAnnotatedWith(Bean.class).should().bePublic()
.because("@Bean annotation does not work in non public methods");
*/

// Methods
@ArchTest
static final ArchRule beanMethodsShouldBePublic = methods()
.that()
.areAnnotatedWith(Bean.class)
.should()
.bePackagePrivate()
.because("@Bean annotation should not be declared as public methods");
}

0 comments on commit f744ce7

Please sign in to comment.