Logging in Java

  • SLF4J: SLF4J stands for Simple Facade For Java. It is nothing but only a facade for logging system. It doesn’t do the logging implementation work. It is logging design pattern.

If you only include SLF4J.jar in your project, what messages will you get? Here is very simple and easy understanding example from SLF4J. You will get those warning messages:

<!-- wp:shortcode -->
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
<!-- /wp:shortcode -->

Simply because there is no logger implementation component.

  • Log4J / Logback:

Logger4J or Logback are Java logging Framework who implementation SLF4J.

Here is every good picture from SLF4J manual: to help you understand the layers between log4j/logback/ other framework and SLF4J.

  • Use Cases:

When you design a Java Library which will be included and used by other project, you should only include SLF4J in this library and you give the chances to the using projects who choice the Java Logging Framework.

If you written a Service and Application, you should use SLF4J + Log4j or SLF4J + Logback etc.

In short, libraries and other embedded components should consider SLF4J for their logging needs because libraries cannot afford to impose their choice of logging framework on the end-user. On the other hand, it does not necessarily make sense for stand-alone applications to use SLF4J. Stand-alone applications can invoke the logging framework of their choice directly. In the case of logback, the question is moot because logback exposes its logger API via SLF4J.

From slf4j FAQ

AWS Cognito + MP JWT RBAC + Quarkus

In this blog, we will try to build a Role-Based-Access-Control (RBAC) with Quarkus, MicroProile JWT RBAC and AWS Cognito.

AWS Cognito will create JWT token and RSA Public Key Distribution. Quarkus is responsible for Java Server-side API endpoints.

Useful links:

Eclipse MicroProfile – JWT RBAC Security (MP-JWT)

QUARKUS – USING JWT RBAC

  • Create AWS Cognito User Pool and then in this User Pool create a User and Group. Here we use “Cognito Groups” as “User Roles”.
  • Create an AWS Cognito Identity Pool and get an identity pool Id , eg "eu-central-1_xxxxx". This Cognito Identity Pool will be the JWT Issuer and we could find the RSA Publicy Key under "https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_xxxxx/.well-known/jwks.json"
  • Create the endpoint by using Quarkus, for example:
@Path("/orders")
@RequestScoped
public class OrderResource {

    @GET
    @RolesAllowed({"USER", "ADMIN"})
    @Produces(MediaType.APPLICATION_JSON)
    public Response list(){
        return Response.ok(Arrays.asList("Order1", "Order2")).build();
    }
}

Most important since the default group claim in MP-JWT is “groups” but the Cognito group claim is “cognito:groups” so we need config a mapping.

smallrye.jwt.path.groups=cognito:groups

Other necessary configs:

mp.jwt.verify.publickey.location=https://cognito-idp.eu-central-1.amazonaws.com/eu-central-xxxxx.well-known/jwks.json

mp.jwt.verify.issuer=https://cognito-idp.eu-central-1.amazonaws.com/eu-central-xxxxx

quarkus.smallrye-jwt.enabled=true
quarkus.smallrye-jwt.auth-mechanism=MP-JWT
quarkus.smallrye-jwt.realm-name=Quarkus-JWT

For testing and getting a cognito jwt token you could try aws cli:

aws cognito-idp admin-initiate-auth --region eu-central-1 --cli-input-json file://auth.json

Then you put that token in the HTTP header “Authorization” and begins with “Bearer ” for example:

curl -X GET \
https://example/orders \
-H 'Authorization: Bearer YOUR_JWT_TOKEN' \

There you are the integration Quarkus + MP JWT and AWS Cognito. Enjoy!

AWS S3 SDK Java Feedback

  • Verify if Bucket already exists

call the doesBucketExist method

  • Create Subdirectory (folder): using key


PutObjectRequest request = new PutObjectRequest(bucketName, "folder/", new File(fileName));

  • Remove all the files under folder:

    using key like : folder/

  • Using Presigned Url to share object (public url)

Often we need upload a file (image) to S3 and get a tempory public URL of this object. (Be careful, you should always set private-access to this object)

We could use Presigned-url with an expiration period.

Code Example

Build Reactive Restful API Using Spring 5 (WebFlux), Springboot

1. Spring 5 WebFlux

Spring 5 includes a new reactive module called WebFlux. It builds on the reactive streams. (Key Spring Doc)

WebFlux support two programming models: one is traditional based@controller, the other is functional Java 8 lambda style routing and handling.  Here we will take a look at the second one.

In general, the second WebFlux model takes incoming http request, handed by the HandlerFunction , then http request body transforms to as Flux or Mono;

Flux and Mono come from the reactor (doc). A Flux object represents a reactive sequence of 0..N items, while a Monoobject represents a single-value-or-empty (0..1) result.

2. Code example

2.1 Create a handler:


@Component
public class UserHandler {

    public Mono<serverresponse> getUser(ServerRequest request){
            try{
                String uuid = request.pathVariable("uuid");
                return ServerResponse
                        .ok()
                        .contentType(MediaType.APPLICATION_JSON)
                        .body(BodyInserters.fromObject(new UserJson(uuid, "bob")));
            }catch (IllegalArgumentException i){
                return ServerResponse.badRequest()
                        .contentType(MediaType.TEXT_PLAIN)
                        .body(BodyInserters.fromObject(i.getMessage()));
            }
    }
}
</serverresponse>

2.2 Create a route:


@Configuration
public class UserRouter {

    @Bean
    public RouterFunction<serverresponse> route(UserHandler userHandler){
        return RouterFunctions.route(RequestPredicates.GET("/users/{uuid}").
                and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
                userHandler::getUser);
    }
}
</serverresponse>

Source Code example Github

 

Building Restful API using Springboot

1.Create Spring-boot project

IntelliJ IDEA CE doesn’t support “spring initializr” plugin, so we should initial a SpringBoot project using https://start.spring.io/

Download and unzip project, import it into IntelliJ.

2. Coding
  • Using  @RestController annotation which equals :  @controller + @ResponseBody
  •  Springboot main class should be in the same package with controllers and it should be in the root.

  • Code Controller:

@RestController
public class UserController {

    @RequestMapping(value = "/users/{uuid}", method = RequestMethod.GET)
    public ResponseEntity getUser(@PathVariable("uuid") String uuid) {
        UserJson userJson = new UserJson(uuid, "bob");
        return new ResponseEntity<>(userJson, HttpStatus.OK);
    }
}
  • Code Entity:

public class UserJson {

    @JsonProperty(value = "uuid")
    private String uuid;

    @JsonProperty(value = "name")
    private String name;

    public UserJson(String uuid, String name) {
        this.uuid = uuid;
        this.name = name;
    }
}
  • Run project

Configration Context and Port (Modifiy application.properties)


./gradlew build bootRun

Source Code Github

play framework (filter, action)

1. KeY concepts of http architect in Play framework

In core play2, the handling of HTTP is :


RequestHeader -&gt; Array[Byte] -&gt; Result 
RequestHeader -&gt; Iteratee[Array[Byte],Result]

The above computation takes the request header RequestHeader, then takes the request body as Array[Byte] and produces a Result. (play doc)

2. action and filter

Most of the requests received by a Play application are handled by an Action.

A play.api.mvc.Action is basically a (play.api.mvc.Request => play.api.mvc.Result) function that handles a request and generates a result to be sent to the client.

A Controller is nothing more than a singleton object that generates Action values. (play doc)

The Filter is applying global filters to each request.

3. Using Filter and action

The filter is used for all the routes. Action can be customized for certain route (on a specific controller)

Using Filter for creating global ratelimter for the API:


public class GlobalRatelimitFilter extends Filter {

    private static final long MAX_REQUESTS = 10;
    private static final long PERIOD = 60;
    private AtomicLong remainingRequests;
    private Instant expirationTime;

    @Inject
    public GlobalRatelimitFilter(Materializer mat) {
        super(mat);
        this.remainingRequests = new AtomicLong(MAX_REQUESTS);
        this.expirationTime = Instant.now().plusSeconds(PERIOD);
    }

    @Override
    public CompletionStage apply(Function&lt;Http.RequestHeader, CompletionStage&gt; next, Http.RequestHeader rh) {

        if (Instant.now().isAfter(this.expirationTime)) {
            this.remainingRequests = new AtomicLong(MAX_REQUESTS);
            this.expirationTime = Instant.now().plusSeconds(PERIOD);
        }
        if (this.remainingRequests.get() &gt; 0L) {
            this.remainingRequests.getAndDecrement();
            return next.apply(rh).thenApply(result -&gt; result.withHeader("X-Remaining-Ratelimit", String.valueOf(this.remainingRequests.get())));
        } else {
            return CompletableFuture.completedFuture(Results.status(429, "too many requests globally"));
        }
    }
}

code github

Using action for creating specific ratelimiter for certain routes:


public class RatelimitAction extends Action {

    private static final String USER_ENDPOINT_RATELIMIT = "user-endpoint-ratelimit";

    @Inject
    @NamedCache("ratelimit-cache")
    private SyncCacheApi cache;

    @Override
    public CompletionStage call(Http.Context ctx) {
        int limit = configuration.limit();
        int period = configuration.period();
        Ratelimit ratelimit = cache.getOrElseUpdate(USER_ENDPOINT_RATELIMIT, () -&gt; new Ratelimit(limit, period));

        if (ratelimit.expired()) {
            ratelimit = new Ratelimit(limit, period);
            cache.set(USER_ENDPOINT_RATELIMIT, ratelimit);
        }
        ratelimit.decrease();

        if (ratelimit.reached()) {
            return CompletableFuture.completedFuture(Results.status(429, "too may requests for /users endpoint"));
        }

        return delegate.call(ctx);
    }
}

Using Action to control the API, Security, verify the requests before it calling the controller.


public class IPStrictAction extends Action {

    @Override
    public CompletionStage call(Http.Context ctx) {

        String[] whiteListIPs = configuration.whiteListIPs();

        String clientHost = ctx.request().host().split(":")[0];

        if(!iPwhitelisted(whiteListIPs, clientHost)){
            CompletableFuture.completedFuture(Results.status(403, "IP not allowed"));
        }

        return delegate.call(ctx);
    }

    private boolean iPwhitelisted(String[] whiteListIPs, String clientHost) {
        return Arrays.asList(whiteListIPs).contains(clientHost);
    }
}

Code Github

 

 

Java – Exception

Exception:

Definition: An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program’s instructions.

Three Kinds of exception:
  • Checked Exception: These are exceptional conditions that a well-written application should anticipate and recover from.

NoSuchFieldException, IOException etc.

  • Errors (Unchecked exception): These are exceptional conditions that are external to the application, and that the application usually cannot anticipate or recover from.

An application might choose to catch this exception, in order to notify the user of the problem — but it also might make sense for the program to print a stack trace and exit.

  • Runtime exception (Unchecked exception): These are exceptional conditions that are internal to the application, and that the application usually cannot anticipate or recover from.The application can catch this exception, but it probably makes more sense to eliminate the bug that caused the exception to occur.

IndexOutOfBoundsException, IllegalArgumentException etc.

Password Store Best practice – Security Hash in Java

In Developement we often encounter the case when we have to store the user’s password. Obversely, we should never store the real, raw password. Instead we store the hash value of the password.

There are some advanced Hashing secure one-way functions compute a one-way (irreversible) transform.  Owasp

Today we will introduce two widely used hash methods:

  • PBKDF2WithHmacSHA512:

PBKDF2 (Password-Based Key Derivation Function 2)
SHA (Secure Hash Algorithm )

Java implementation code

  • Bcrypt:

bcrypt is a password hashing function based on the Blowfish cipher.

Java implementation code

Other good articles:

https://howtodoinjava.com/security/how-to-generate-secure-password-hash-md5-sha-pbkdf2-bcrypt-examples/

Java Generics

Why use Generics:

Generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods.

  • Stronger type checks at compile time.
  • Elimination of casts.
  • Enabling programmers to implement generic algorithms.
Generic Types
generic type is a generic class or interface that is parameterized over types.

Java Basic – Keywords

  • transientVariables may be marked transient to indicate that they are not part of the persistent state of an object.
  • volatile: A field may be declared volatile, in which case the Java Memory Model ensures that all threads see a consistent value for the variable.

Java doc