Friday, March 4, 2022

Quarkus Spring Data API PostgreSQL CRUD

Quarkus A Kubernetes Native Java stack tailored for OpenJDK HotSpot and GraalVM, crafted from the best of breed Java libraries and standards.

CREATING A Quarkus APPLICATION

In this example we're integration Quarkus + Spring Data API + PostgreSQL.

  • Configuration Quarkus, Spring Data and PostgreSQL.
  • Define Datas models, Repository and Services.
  • Quarkus Resource.

Quarkus Rest  CRUD API 

These are APIs that we need to provide:

Methods Urls
GET /users
GET /users/age/{age}
POST /users/name/{name}/age/{age}
PUT /users/id/{id}/age/{age}
DELETE /users/{id}

Technology

  • Java 17
  • Quarkus 2.7.3.Final
  • PostgreSQL 14.1 
  • Maven 
  • Postman v9.0.8
  • IntelliJ IDEA 2021.2.3 
  • Docker

Project Structure


























Configuration  Quarkus Spring Data PostgreSQL


pom.xml


<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.henry</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<compiler-plugin.version>3.8.1</compiler-plugin.version>
<failsafe.useModulePath>false</failsafe.useModulePath>
<maven.compiler.release>11</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>2.7.3.Final</quarkus.platform.version>
<surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>JBoss repository</id>
<url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>2.2.1.GA</version>
</dependency>

<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>2.2.0.GA</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>3.6.2.Final</version>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-spring-data-jpa</artifactId>
</dependency>


<!-- JDBC driver dependencies -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>
org.jboss.logmanager.LogManager
</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>
${project.build.directory}/${project.build.finalName}-runner
</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager
</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>
  

application.properties


quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=quarkus_test
quarkus.datasource.password=quarkus_test
quarkus.datasource.jdbc.url=jdbc:postgresql:quarkus_test
quarkus.datasource.jdbc.max-size=8
quarkus.datasource.jdbc.min-size=2
quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.http.port=9000

Set up PostgreSQL


docker run -it --rm=true --name quarkus_test -e POSTGRES_USER=quarkus_test -e POSTGRES_PASSWORD=quarkus_test -e POSTGRES_DB=quarkus_test -p 5432:5432 postgres:14.1

Data class model


package com.henry.model;

import javax.persistence.*;

@Entity
@Table(name="USERS")
public class User {

@Id
@SequenceGenerator(name = "USERS_id", sequenceName = "USERS_id", initialValue = 1, allocationSize = 1)
@GeneratedValue(generator = "USERS_id")
private Long id;

private String name;
private Integer age;

public User(){}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}
}

Repository Interface


package com.henry.repository;

import com.henry.model.User;
import org.springframework.data.repository.CrudRepository;

import java.util.List;

public interface UserRepository extends CrudRepository<User, Long> {

List<User> findByAge(Integer age);
}

Service Interface



package com.henry.service;

import com.henry.model.User;

import java.util.List;
import java.util.Optional;

public interface UserService {

public Iterable<User> findAll();
public Optional<User> findById(long id);
public void delete(long id);
public User create(String name,Integer age);
public User changeAge(Long id,Integer age);
public List<User> findByAge(Integer age);
}

Service Class

package com.henry.service.impl;

import com.henry.model.User;
import com.henry.repository.UserRepository;
import com.henry.service.UserService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class UserServiceImpl implements UserService {

private final UserRepository userRepository;

public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}

@Override
public Iterable<User> findAll() {
return userRepository.findAll();
}

@Override
public Optional<User> findById(long id) {
return userRepository.findById(id);
}

@Override
public void delete(long id) {
userRepository.deleteById(id);
}

@Override
public User create(String name, Integer age) {
return userRepository.save(new User(name, age));
}

@Override
public User changeAge(Long id, Integer age) {
Optional<User> optional = userRepository.findById(id);
if (optional.isPresent()) {
User user = optional.get();
user.setAge(age);
return userRepository.save(user);
}

throw new IllegalArgumentException("No User with id " + id + " exists");
}

@Override
public List<User> findByAge(Integer age) {
return userRepository.findByAge(age);
}
}

Quarkus Rest APIs Resource


package com.henry.resource;

import com.henry.model.User;
import com.henry.service.UserService;
import org.jboss.resteasy.annotations.jaxrs.PathParam;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;

@Path("/users")
public class UserResource {

private final UserService userService;

public UserResource(UserService userService) {
this.userService = userService;
}

@GET
@Produces(MediaType.APPLICATION_JSON)
public Iterable<User> findAll() {
return userService.findAll();
}


@DELETE
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public void delete(@PathParam long id) {
userService.delete(id);
}

@POST
@Path("/name/{name}/age/{age}")
@Produces(MediaType.APPLICATION_JSON)
public User create(@PathParam String name, @PathParam Integer age) {

return userService.create(name, age);
}

@PUT
@Path("/id/{id}/age/{age}")
@Produces(MediaType.APPLICATION_JSON)
public User changeAge(@PathParam Long id, @PathParam Integer age) {
return userService.changeAge(id, age);
}

@GET
@Path("/age/{age}")
@Produces(MediaType.APPLICATION_JSON)
public List<User> findByAge(@PathParam Integer age) {

return userService.findByAge(age);
}
}

Run & Test


Run Quarkus application with next maven command :
./mvnw compile quarkus:dev or ./mvnw test (Run test class) by console or IntelliJ.




GET.










 














GET.



























POST.


























PUT.






















DELETE.























Source Code


Here on Github.



References.



https://quarkus.io/guides/spring-data-jpa














Tuesday, January 25, 2022

Template Driven and Reactive Forms Datepicker Angular Material 12

Template Driven and Reactive Forms Datepicker Angular Material 12



In this post, we will learn how to use the Angular Forms API with Datepicker, also we will learn with Template Driven Forms (ngModel).

Let's start.

We will work with Angular forms. You will have the next advantages, reactive por example is Explicit, Created in component class, Structured and immutable, Synchronous and form validation through functions.

We will work with Template Driven. You will have the next advantages,  is implicit, created by directives, unstructured and mutable, Asynchronous  and form validation through directives.

In my case both are useful however it depends on what will be done in your application.

If you want more documentacion go to Angular documentacion.


In this post. I will give two basic examples.

Case: we will have two calendars from the first Datepicker to update second Datepicker, with Angular Forms and Template Driven. ok let go. 


In both examples I used moment js for format date.

Run both examples on Stackbliz.


Angular Forms


Ts class.

import { Component, OnInit, VERSION } from '@angular/core';
import {
FormBuilder,
FormGroup,
FormControl,
Validators,
} from '@angular/forms';

import {
MomentDateAdapter,
MAT_MOMENT_DATE_ADAPTER_OPTIONS,
} from '@angular/material-moment-adapter';
import {
DateAdapter,
MAT_DATE_FORMATS,
MAT_DATE_LOCALE,
} from '@angular/material/core';


import * as _moment from 'moment';

import moment from 'moment';

export const MY_FORMATS = {
parse: {
dateInput: 'DD/MM/YYYY',
},
display: {
dateInput: 'DD/MM/YYYY',
monthYearLabel: 'MMM YYYY',
dateA11yLabel: 'LL',
monthYearA11yLabel: 'MMMM YYYY',
},
};

@Component({
selector: 'app-fdatepicker',
templateUrl: './fdatepicker.component.html',
styleUrls: ['./fdatepicker.component.css'],
providers: [
// `MomentDateAdapter` can be automatically provided by importing `MomentDateModule` in your
// application's root module. We provide it at the component level here, due to limitations of
// our example generation script.
{
provide: DateAdapter,
useClass: MomentDateAdapter,
deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS],
},

{ provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
],
})
export class fdatepickerComponent implements OnInit {
constructor(private fb: FormBuilder) {}

formPopPup: any;

date1 = new FormControl(moment());
date2 = new FormControl(moment());

ngOnInit() {
this.formPopPup = new FormGroup({
firstDate: new FormControl(),
secondDate: new FormControl(),
});

this.formPopPup = this.fb.group({
firstDate: [null, Validators.required],
secondDate: [null, Validators.required],
});
}

OnDateChange(e: any) {
var new_date = moment(e, 'DD-MM-YYYY').add(0, 'days').add(2, 'months');

this.formPopPup.get('secondDate').setValue(new_date);
}
}




Html

<p>Angular Forms Example</p>
<mat-sidenav-container>
<form [formGroup]="formPopPup">
<table>
<tr>
<td>
<mat-form-field>
<input
matInput
[matDatepicker]="fi"
formControlName="firstDate"
#firstDate
[formControl]="date1"
(dateInput)="OnDateChange($event.value)"
/>
<mat-datepicker-toggle matSuffix [for]="fi"></mat-datepicker-toggle>
<mat-datepicker #fi> </mat-datepicker>
</mat-form-field>
</td>
<td>
<mat-form-field>
<input
matInput
[matDatepicker]="se"
formControlName="secondDate"
[formControl]="date2"
/>
<mat-datepicker-toggle matSuffix [for]="se"></mat-datepicker-toggle>
<mat-datepicker #se> </mat-datepicker>
</mat-form-field>
</td>
</tr>
</table>
</form>
</mat-sidenav-container>




Template Driven


Ts class.


import { Component, VERSION } from '@angular/core';

import * as _moment from 'moment';

import moment from 'moment';

@Component({
selector: 'app-tdatepicker',
templateUrl: './tdatepicker.component.html',
styleUrls: ['./tdatepicker.component.css'],
})
export class tdatepickerComponent {
date1: any;
date2: any;

dateChangeHandler(e: any) {
var new_date = moment(new Date(this.date1), "DD-MM-YYYY").add(0, 'days').add(3, 'months');
this.date2 = new_date;
}
}


Html

<p>Template driven</p>
<mat-sidenav-container>
<table>
<tr>
<td>
<mat-form-field>
<input
matInput
[matDatepicker]="d1"
(dateChange)="dateChangeHandler($event)"
[(ngModel)]="date1"
/>
<mat-datepicker-toggle matSuffix [for]="d1"></mat-datepicker-toggle>
<mat-datepicker #d1> </mat-datepicker>
</mat-form-field>
</td>
<td>
<mat-form-field>
<input
matInput
[matDatepicker]="d2"
[(ngModel)]="date2"
/>
<mat-datepicker-toggle matSuffix [for]="d2"></mat-datepicker-toggle>
<mat-datepicker #d2> </mat-datepicker>
</mat-form-field>
</td>
</tr>
</table>
</mat-sidenav-container>




In both cases will be the same and add three months to the second calendar however the angular forms using FormControl in reactive way, whereas  Template is driven using ngModel.







References: https://material.angular.io/




Monday, January 17, 2022

Deploy Spring Boot 2 Kotlin Java 11 on Heroku

Deploy Spring Boot 2  Kotlin  Java 11 on Heroku.

Heroku concepts is extract from Heroku is a cloud platform that lets companies build, deliver, Monitor and scale apps, we are the fastest way to go from idea to URL, by passing all those infrastructure headches.


we will create a free account from deploy your apps. in next link, this way, 




















Next to will be do login. and will have the next page.









Click right corner -> New -> Create new app. set name the app. This way.
















Click on button Create app. and will have the next page.



















In this case I used Heroku Cli, check the link for install Heroku Cli. and the next just follow steps, Heroku provide.

$ heroku login -i


Eg:






Create a new Git repository


Initialize a git repository in a new or existing directory

$ cd my-project/
$ git init
$ heroku git:remote -a backend-eg


Deploy your application
Commit your code to the repository and deploy it to Heroku using Git.

$ git add .
$ git commit -am "make it better"
$ git push heroku master



Succes install.








Public URL, for access my webservice.

https://backend-eg.herokuapp.com/services/hello
https://backend-eg.herokuapp.com/services/hello/henry






Source code.

Here on GitHub.









🔐AWS → Google Cloud Workload Identity Federation with Terraform

  Eliminating Service Account Keys for Cross-Cloud Workloads Managing identities across cloud providers is often more challenging than manag...