Skip to content

Java Library for Developing Reactive Backend Systems with Keycloak Authentication, Minio Storage, OAuth2 Security, Caching, and Trace Logging Integration ...

License

Notifications You must be signed in to change notification settings

hoangtien2k3/reactify-core

Repository files navigation

Reactify a commons Java lib with spring boot framework, Supports using keycloak, filter, trace log, cached, minio server, exception handler, validate and call API with webclient

This README provides quickstart instructions on running reactify on bare metal project spring boot.

SonarCloud

CircleCI Quality Gate Status Lines of Code GitHub Release License OpenSSF Best Practices Build status

Getting Started

Gradle is the only supported build configuration, so just add the dependency to your project build.gradle file:

⬇️ Download Gradle and Maven

dependencies {
    implementation("io.github.hoangtien2k3:reactify-core:1.1.7")
}
<dependency>
   <groupId>io.github.hoangtien2k3</groupId>
   <artifactId>reactify-core</artifactId>
   <version>1.1.7</version>
</dependency>

The latest reactify version is: GitHub Release

The latest stable lib reactify version is: latestVersion Click here for more information on reactify.

  1. Correct and complete setup to start the program application.yml or application.properties with CONFIG

  2. The reference documentation includes detailed installation instructions as well as a comprehensive getting started guide.

Here is a quick teaser of a complete Spring Boot application in Java:

Start Using reactify-core

@SpringBootApplication
@ComponentScan(basePackages = {
        "com.reactify.*",
        "com.example.myproject"
})
public class Example {

    @RequestMapping("/")
    String home() {
        return "Hello World!";
    }

    public static void main(String[] args) {
        SpringApplication.run(Example.class, args);
    }
}

Using Lib Reactify-Core Demo:

  1. LocalCache
@LocalCache(durationInMinute = 30, maxRecord = 10000, autoCache = true)
public Mono<List<OptionSetValue>> findByOptionSetCode(String optionSetCode) {
    return optionSetValueRepository.findByOptionSetCode(optionSetCode).collectList();
}
  1. Keycloak

application.yml

spring:
  security:
    oauth2:
      client:
        provider:
          oidc:
            token-uri: ${keycloak.serverUrl}/realms/${keycloak.realm}/protocol/openid-connect/token
        registration:
          oidc:
            client-id: ${keycloak.clientId}
            client-secret: ${keycloak.clientSecret}
            authorization-grant-type: ${keycloak.grantType} #password || #client_credentials
      resourceserver:
        jwt:
          jwk-set-uri: ${keycloak.serverUrl}/realms/${keycloak.realm}/protocol/openid-connect/certs
      keycloak:
        client-id: ${keycloak.clientId}
@Override
public Mono<Optional<AccessToken>> getToken(LoginRequest loginRequest) {
    MultiValueMap<String, String> formParameters = new LinkedMultiValueMap<>();
    formParameters.add(OAuth2ParameterNames.GRANT_TYPE, OAuth2ParameterNames.PASSWORD);
    formParameters.add(OAuth2ParameterNames.USERNAME, loginRequest.getUsername());
    formParameters.add(OAuth2ParameterNames.PASSWORD, loginRequest.getPassword());
    String clientId = loginRequest.getClientId();
    if (!DataUtil.isNullOrEmpty(clientId)) {
        return keycloakProvider
                .getClientWithSecret(clientId)
                .flatMap(clientRepresentation -> {
                    formParameters.add(OAuth2ParameterNames.CLIENT_ID, clientId);
                    formParameters.add(OAuth2ParameterNames.CLIENT_SECRET, clientRepresentation.getSecret());
                    return requestToken(formParameters);
                })
                .switchIfEmpty(Mono.error(new BusinessException(CommonErrorCode.INVALID_PARAMS, "client.id.not.valid")));
    } else {
        formParameters.add(OAuth2ParameterNames.CLIENT_ID, keyCloakConfig.getAuth().clientId());
        formParameters.add(OAuth2ParameterNames.CLIENT_SECRET, keyCloakConfig.getAuth().clientSecret());
    }
    return requestToken(formParameters);
}
  1. Call Api Using BaseRest and BaseSoap Client
public Mono<String> getEmailsByUsername(String username) {
    var payload = new LinkedMultiValueMap<>();
    payload.set("username", username);
    return SecurityUtils.getTokenUser().flatMap(token -> {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + token);
        return baseRestClient
                .get(authClient, "/user/keycloak", headers, payload, String.class)
                .map(response -> {
                    Optional<?> optionalEmail = (Optional<?>) response;
                    return DataUtil.safeToString(optionalEmail.orElse(null));
                });
    });
}

Contributing

If you would like to contribute to the development of this project, please follow our contribution guidelines.

Alt

Star History

Star History Chart

Contributors ✨

License

This project is licensed under the Apache License, Version 2.0

Apache License
Copyright (c) 2024 Hoàng Anh Tiến

Lead to This Project 🌈


Hoàng Anh Tiến

💻 🚧 🤔 🎨 🐛