Thursday, November 23, 2023

Java 9 : JShell

 1. How to run Jshell

    get a command prompt windows key + R --> type cmd

2. Check java version, should be higher than 9

    java -version

3. type "jshell"

4. Now you can write syntax and check validity , edit and play on with this

5. /help --> help command

6. /list   --> will list the command typed/executed

7. edit use edit command with command number, number you can select using /list . Once you use edit, it will prompt with shell to edit.

    /edit 2


Below you I have attached series of commands i tried with all mistakes

----------------------------------------------------------------------------------------------------------------------

Microsoft Windows [Version 10.0.22621.2715]

(c) Microsoft Corporation. All rights reserved.


C:\Users\USR>java -version

openjdk version "21" 2023-09-19

OpenJDK Runtime Environment Zulu21.28+85-CA (build 21+35)

OpenJDK 64-Bit Server VM Zulu21.28+85-CA (build 21+35, mixed mode, sharing)


C:\Users\USR>jshell

|  Welcome to JShell -- Version 21

|  For an introduction type: /help intro


jshell> System.out.println("Hello");

Hello


jshell> /help

|  Type a Java language expression, statement, or declaration.

|  Or type one of the following commands:

|  /list [<name or id>|-all|-start]

|       list the source you have typed

|  /edit <name or id>

|       edit a source entry

|  /drop <name or id>

|       delete a source entry

|  /save [-all|-history|-start] <file>

|       Save snippet source to a file

|  /open <file>

|       open a file as source input

|  /vars [<name or id>|-all|-start]

|       list the declared variables and their values

|  /methods [<name or id>|-all|-start]

|       list the declared methods and their signatures

|  /types [<name or id>|-all|-start]

|       list the type declarations

|  /imports

|       list the imported items

|  /exit [<integer-expression-snippet>]

|       exit the jshell tool

|  /env [-class-path <path>] [-module-path <path>] [-add-modules <modules>] ...

|       view or change the evaluation context

|  /reset [-class-path <path>] [-module-path <path>] [-add-modules <modules>]...

|       reset the jshell tool

|  /reload [-restore] [-quiet] [-class-path <path>] [-module-path <path>]...

|       reset and replay relevant history -- current or previous (-restore)

|  /history [-all]

|       history of what you have typed

|  /help [<command>|<subject>]

|       get information about using the jshell tool

|  /set editor|start|feedback|mode|prompt|truncation|format ...

|       set configuration information

|  /? [<command>|<subject>]

|       get information about using the jshell tool

|  /!

|       rerun last snippet -- see /help rerun

|  /<id>

|       rerun snippets by ID or ID range -- see /help rerun

|  /-<n>

|       rerun n-th previous snippet -- see /help rerun

|

|  For more information type '/help' followed by the name of a

|  command or a subject.

|  For example '/help /list' or '/help intro'.

|

|  Subjects:

|

|  intro

|       an introduction to the jshell tool

|  keys

|       a description of readline-like input editing

|  id

|       a description of snippet IDs and how use them

|  shortcuts

|       a description of keystrokes for snippet and command completion,

|       information access, and automatic code generation

|  context

|       a description of the evaluation context options for /env /reload and /reset

|  rerun

|       a description of ways to re-evaluate previously entered snippets


jshell>

/list


   1 : System.out.println("Hello");


jshell> void printMessage(){

   ...>     System.out.print;n("Hello")

   ...> }

|  Error:

|  not a statement

|      System.out.print;n("Hello")

|      ^--------------^

|  Error:

|  ';' expected

|      System.out.print;n("Hello")

|                                 ^


jshell> printMessage()

|  Error:

|  cannot find symbol

|    symbol:   method printMessage()

|  printMessage()

|  ^----------^


jshell> /lsit

|  Invalid command: /lsit

|  Type /help for help.


jshell> /list


   1 : System.out.println("Hello");


jshell>

        void printMessage(){

   ...>     System.out.print;n("Hello");

   ...> }

|  Error:

|  not a statement

|      System.out.print;n("Hello");

|      ^--------------^

|  Error:

|  cannot find symbol

|    symbol:   method n(java.lang.String)

|      System.out.print;n("Hello");

|                       ^


jshell> void printMessage(){

   ...>     System.out.println("Hello");

   ...> }

|  created method printMessage()


jshell> printMessage

|  Error:

|  cannot find symbol

|    symbol:   variable printMessage

|  printMessage

|  ^----------^


jshell> printMessage()

Hello


jshell> /list


   1 : System.out.println("Hello");

   2 : void printMessage(){

           System.out.println("Hello");

       }

   3 : printMessage()


jshell> edit 2

|  Error:

|  ';' expected

|  edit 2

|      ^

|  Error:

|  cannot find symbol

|    symbol:   variable edit

|  edit 2

|  ^--^


jshell> /edit 2

|  modified method printMessage()


jshell> printMessage()

Hello Edited


jshell>


Java 9

1. REPL Jshell

2.    Collection Factory Method

3. HTTP/2 Client

4. Jigsaw Project /Modularity

5. Other features


https://www.youtube.com/watch?v=NJY-D9JLLdQ


1. Test Jshell

Take a command prompt wind + R -> type "cmd"

2. Check java version, must be above 9

java -version 

3. type "jshell" in command prompt

4. This will help you to test simple syntax

-------------------------------------------------------------------------------------------------

C:\Users\USR>java -version

openjdk version "21" 2023-09-19

OpenJDK Runtime Environment Zulu21.28+85-CA (build 21+35)

OpenJDK 64-Bit Server VM Zulu21.28+85-CA (build 21+35, mixed mode, sharing)


C:\Users\USR>jshell

|  Welcome to JShell -- Version 21

|  For an introduction type: /help intro

jshell> System.out.println("Hello");

Hello

jshell>

Monday, September 25, 2023

API Management

Few things to know

Once you done with development and publishing your APIs, then 

How to secure this APIs

How to analyze usage of these APIs

Scale your APIs

Configure 

to rate limit -> eg: 10 requests per minute


Internal(Private)  and Public (APIs visible to others)

--


Public APIs need more

---

Due to visibility and scrutiny they have

If you have few, you may not bother

you might build embedding them with

security, logging , configuration,  into actual API code


So when more and more requirements coming

Specially where micro service --> where APIs get broken

Note : Micro service are not APIs.


smaller APIs focus with specialized operations

Legacy APIs , what to do


API managment is a process of 

  1. Building
  2. Publishing
  3. Securing
  4. Versioning
  5. Observing
  6. Scaling
  7. Cataloging
  8. Retiring

There can be more in future.....

We need to make a system to manage the lifecycle of APIs, so company can focus on adding value to core business (coding,..)


1. API Gateway

Handles the routing and management of all the APIs 

through policies that apply to individual API or set of APIs

2. Developer portal

serves as self service hub - developers to access API documentation, sdks, and other resources needed for consuming APIs

3. API dashboard

Observe API usage

view key API metrics

manage variety of API analytics

4. Unified API central catalogue

organizing, cataloging, indexing and presenting all the public and Private APIs use in Organization

API management will add Flexibility and Power where

you are managing each API independently, to a Unified system where you are orchestrating a complete set of APIs as  a product.

Create a API strategy align with your Companies goals - will save lot of resources and work efficiently


Thursday, September 21, 2023

Mulesoft Training Public URLs are not working

http://mu.learn.mulesoft.com/delta?wsdl

http://mu.learn.mulesoft.com/united/flights/CLE 


Most of the time you find that, the URLs provided by the Mulesoft is not working or you are working in a company where you have restriction on access.

Solution to these issues is to set up those services running inside your machine.

Solution:

Open the jars folder fromStudents Files zip file where you have already downloaded from course resourses.

Locate "mulesoft-training-services-1.8.8.jar"

Just run this jar

java -jar mulesoft-training-services-1.8.8.jar


You will finally get an output on terminal as below

--------------------------------------------



┌───────────────────────────────────────────────────────────────────────────────────────┐

│ (\_/)          M U L E S O F T    T R A I N I N G   &   C E R T I F I C A T I O N     │

│ /   \          Anypoint Platform Development Fundamentals - Services & APIs           │

└───────────────────────────────────────────────────────────────────────────────────────┘


Starting resources:

- Database started.

- Database tables created.

- Database tables populated.

- JMS message broker started.

- United flights web service started.

- JMS service started.

- American flights RAML API started.

- Banking REST API started.

- Accounts REST API started.

- Delta flights web service started.


Published resources:

- Landing page                   : http://localhost:9090

- JMS message broker URL         : tcp://localhost:61616

- JMS default topic name         : apessentials

- JMS web form                   : http://localhost:9090/jmsform.html

- American flights database URL  : jdbc:derby://localhost:1527/memory:training

- Accounts API                   : http://localhost:9090/accounts/api

- Accounts web form              : http://localhost:9090/accounts/show.html

- American flights REST service  : http://localhost:9090/american/flights

- American flights REST API RAML : http://localhost:9090/american/american-flights-api.raml

- Banking API base URL           : http://localhost:9090/api/...

- Banking API RAML               : http://localhost:9090/api/banking-api.raml

- United flights REST service    : http://localhost:9090/united/flights

- Delta flights SOAP service     : http://localhost:9191/delta

- Delta flights SOAP WSDL        : http://localhost:9191/delta?wsdl


Press CTRL-C to terminate this application...



Monday, August 28, 2023

How to check Wifi password from Windows machine

 It is east to use shell commands to find the password

1. open power shell

2. find all the listed wifis

3. check the password of the selected wifi network


Step 2:

netsh wlan show profile "name=SLT wifi" key=clear

Step 3:

netsh wlan show profile "name=your wifi name" key=clear


3PRnfigqWlCS85vZkZmYa6zS

Saturday, July 8, 2023

Springboot 3.1 - Spring security - Create Basic Oauth2 client - Continue

 Let's continue add security features for the basic application we have built. As you can see, we have used the basic inbuild features of the spring security where default username=user and with generated password.

So let's start configuring.

1. we will create class "SecurityConfig" and let's put that inside "config" package

2. Annotate with @Configuration and @EnableWebSecurity

import org.springframework.context.annotation.Configuration;

import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

3. create new bean with "SecurityFilterChain" with "HttpSecurity"

below is the sample

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.build();
}

So up to now, the full continue code of the "SecurityConfig" class would looks like below.

Note: we need to add Exception

package com.example.danwega.outh2.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.build();
}
}

4. Now let's start adding security features or configure Spring security environment. We will start modifying bean we created "SecurityFilterChain"

let's authorize http requests.

  • we use authorizeHttpRequests
  • with this we use matchers requestMatchers
  •     For home anybody can go -> auth.requestMatchers("/").permitAll()
  •     For any other request use authentication --> auth.anyRequest().authenticated()

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> {
auth.requestMatchers("/").permitAll();
auth.anyRequest().authenticated();
})
.build();
}

5. Now how are you going to login. So for now, let's give a formLogin with defaults

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> {
auth.requestMatchers("/").permitAll();
auth.anyRequest().authenticated();
})
.formLogin(Customizer.withDefaults())
.build();
}

let's change the code to static import for "withDefaults"

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> {
auth.requestMatchers("/").permitAll();
auth.anyRequest().authenticated();
})
.formLogin(withDefaults())
.build();
}

Now user have to log with user name and password to login

6. without just providing a formLogin, we need to provide a oauth2 login as we are using oauth2.

we add auth2Login with defaults for now.

.oauth2Login(withDefaults())
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> {
auth.requestMatchers("/").permitAll();
auth.anyRequest().authenticated();
})
.oauth2Login(withDefaults())
.formLogin(withDefaults())
.build();
}

That's it for now

7. configure properties to say what oauth2 client, providers we provide.

let's use log level just to what's happening inside when we running the code

logging:
level:
org:
springframework:
security: TRACE

here we will try to configure for GitHub and Google. 

let's first try with GitHub

Github

click your top right corner icon showing you --> go to "settings" --> left side go to "developer settings" in left bottom corner --> select "OAuth2 app" in left panel

8. Let's Register new application. you can give your details as needed, below is sample set

Application name: Spring Security OAuth2 client

Homepage url : localhost:8210

Application description : optional for now

Authorization callback url : localhost:8210/login/oauth2/code/github

call back url is set according to documentation. when it is google  final part will be "google", instead of "github"

 localhost:8210/login/oauth2/code/google

Click Register Application to finish the process. This will go to page and show you "client secret" and some other information

9. 





Friday, July 7, 2023

Springboot 3.1 - Spring security - Create Basic Oauth2 client

 Let's try to see what is new and what is the default behavior for spring security with oauth2 client.

Let's create sample springboot web application using https://start.spring.io/

 you can give chose basic configuration as your wish. 

Here I use, Maven - Java 17,pAckaging : jar

dependencies: Web, Oauth2 client

<dependency>

      <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-starter-oauth2-client</artifactId>

    </dependency>

    <dependency>

      <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-starter-web</artifactId>

    </dependency>


Sample POM file would like this


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.danwega</groupId>
<artifactId>outh2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>outh2</name>
<description>Spring security- Oauth2</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

After that you can download the project and I use Idea to open the project.

let's create sample controller name "HelloController" to see the basic features

Below is the sample code

package com.example.danwega.outh2.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HomeController {

@GetMapping("/")
public String home(){
return "Hello - Home";
}

@GetMapping("secured")
public String secured(){
return "Hello - Secured";
}
}

Now you can run the application

we have set the port and name for the application , not needed . if not go with default.

spring:
application:
name: oauth2-client
server:
port: 8210

When you run, application will up in port 8210 as suggested and will have default generated password from spring security, as we have not configured.

Default user name : user

Default password( what ever generated password) : b584e3b2-5840-48a8-a412-f1fbe3dd4b04 

you can test the application with url

http://localhost:8210/secured

http://localhost:8210/

this will pop up for login page with user name and password.

So that's done, basic simple spring security application with oauth2-client


Below is the sample output when you run the main spring boot application class, output may differ

output

"C:\Program Files\Zulu\zulu-18\bin\java.exe" "-javaagent:C:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 2022.3.2\lib\idea_rt.jar=60521:C:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 2022.3.2\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\Project\Tutorial\MicroService\Code\outh2\target\classes;C:\Users\USERNAME\.m2\repository\org\springframework\boot\spring-boot-starter\3.1.1\spring-boot-starter-3.1.1.jar;C:\Users\USERNAME\.m2\repository\org\springframework\boot\spring-boot\3.1.1\spring-boot-3.1.1.jar;C:\Users\USERNAME\.m2\repository\org\springframework\spring-context\6.0.10\spring-context-6.0.10.jar;C:\Users\USERNAME\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\3.1.1\spring-boot-autoconfigure-3.1.1.jar;C:\Users\USERNAME\.m2\repository\org\springframework\boot\spring-boot-starter-logging\3.1.1\spring-boot-starter-logging-3.1.1.jar;C:\Users\USERNAME\.m2\repository\ch\qos\logback\logback-classic\1.4.8\logback-classic-1.4.8.jar;C:\Users\USERNAME\.m2\repository\ch\qos\logback\logback-core\1.4.8\logback-core-1.4.8.jar;C:\Users\USERNAME\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.20.0\log4j-to-slf4j-2.20.0.jar;C:\Users\USERNAME\.m2\repository\org\apache\logging\log4j\log4j-api\2.20.0\log4j-api-2.20.0.jar;C:\Users\USERNAME\.m2\repository\org\slf4j\jul-to-slf4j\2.0.7\jul-to-slf4j-2.0.7.jar;C:\Users\USERNAME\.m2\repository\jakarta\annotation\jakarta.annotation-api\2.1.1\jakarta.annotation-api-2.1.1.jar;C:\Users\USERNAME\.m2\repository\org\springframework\spring-core\6.0.10\spring-core-6.0.10.jar;C:\Users\USERNAME\.m2\repository\org\springframework\spring-jcl\6.0.10\spring-jcl-6.0.10.jar;C:\Users\USERNAME\.m2\repository\org\yaml\snakeyaml\1.33\snakeyaml-1.33.jar;C:\Users\USERNAME\.m2\repository\org\springframework\boot\spring-boot-starter-oauth2-client\3.1.1\spring-boot-starter-oauth2-client-3.1.1.jar;C:\Users\USERNAME\.m2\repository\org\springframework\security\spring-security-config\6.1.1\spring-security-config-6.1.1.jar;C:\Users\USERNAME\.m2\repository\org\springframework\spring-aop\6.0.10\spring-aop-6.0.10.jar;C:\Users\USERNAME\.m2\repository\org\springframework\spring-beans\6.0.10\spring-beans-6.0.10.jar;C:\Users\USERNAME\.m2\repository\org\springframework\security\spring-security-core\6.1.1\spring-security-core-6.1.1.jar;C:\Users\USERNAME\.m2\repository\org\springframework\security\spring-security-crypto\6.1.1\spring-security-crypto-6.1.1.jar;C:\Users\USERNAME\.m2\repository\org\springframework\spring-expression\6.0.10\spring-expression-6.0.10.jar;C:\Users\USERNAME\.m2\repository\io\micrometer\micrometer-observation\1.11.1\micrometer-observation-1.11.1.jar;C:\Users\USERNAME\.m2\repository\io\micrometer\micrometer-commons\1.11.1\micrometer-commons-1.11.1.jar;C:\Users\USERNAME\.m2\repository\org\springframework\security\spring-security-oauth2-client\6.1.1\spring-security-oauth2-client-6.1.1.jar;C:\Users\USERNAME\.m2\repository\org\springframework\security\spring-security-oauth2-core\6.1.1\spring-security-oauth2-core-6.1.1.jar;C:\Users\USERNAME\.m2\repository\org\springframework\security\spring-security-web\6.1.1\spring-security-web-6.1.1.jar;C:\Users\USERNAME\.m2\repository\com\nimbusds\oauth2-oidc-sdk\9.43.3\oauth2-oidc-sdk-9.43.3.jar;C:\Users\USERNAME\.m2\repository\com\github\stephenc\jcip\jcip-annotations\1.0-1\jcip-annotations-1.0-1.jar;C:\Users\USERNAME\.m2\repository\com\nimbusds\content-type\2.2\content-type-2.2.jar;C:\Users\USERNAME\.m2\repository\com\nimbusds\lang-tag\1.7\lang-tag-1.7.jar;C:\Users\USERNAME\.m2\repository\org\springframework\security\spring-security-oauth2-jose\6.1.1\spring-security-oauth2-jose-6.1.1.jar;C:\Users\USERNAME\.m2\repository\com\nimbusds\nimbus-jose-jwt\9.31\nimbus-jose-jwt-9.31.jar;C:\Users\USERNAME\.m2\repository\org\springframework\boot\spring-boot-starter-web\3.1.1\spring-boot-starter-web-3.1.1.jar;C:\Users\USERNAME\.m2\repository\org\springframework\boot\spring-boot-starter-json\3.1.1\spring-boot-starter-json-3.1.1.jar;C:\Users\USERNAME\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.15.2\jackson-databind-2.15.2.jar;C:\Users\USERNAME\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.15.2\jackson-annotations-2.15.2.jar;C:\Users\USERNAME\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.15.2\jackson-core-2.15.2.jar;C:\Users\USERNAME\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.15.2\jackson-datatype-jdk8-2.15.2.jar;C:\Users\USERNAME\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.15.2\jackson-datatype-jsr310-2.15.2.jar;C:\Users\USERNAME\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.15.2\jackson-module-parameter-names-2.15.2.jar;C:\Users\USERNAME\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\3.1.1\spring-boot-starter-tomcat-3.1.1.jar;C:\Users\USERNAME\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\10.1.10\tomcat-embed-core-10.1.10.jar;C:\Users\USERNAME\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\10.1.10\tomcat-embed-el-10.1.10.jar;C:\Users\USERNAME\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\10.1.10\tomcat-embed-websocket-10.1.10.jar;C:\Users\USERNAME\.m2\repository\org\springframework\spring-web\6.0.10\spring-web-6.0.10.jar;C:\Users\USERNAME\.m2\repository\org\springframework\spring-webmvc\6.0.10\spring-webmvc-6.0.10.jar;C:\Users\USERNAME\.m2\repository\org\slf4j\slf4j-api\2.0.7\slf4j-api-2.0.7.jar;C:\Users\USERNAME\.m2\repository\net\minidev\json-smart\2.4.11\json-smart-2.4.11.jar;C:\Users\USERNAME\.m2\repository\net\minidev\accessors-smart\2.4.11\accessors-smart-2.4.11.jar;C:\Users\USERNAME\.m2\repository\org\ow2\asm\asm\9.3\asm-9.3.jar com.example.danwega.outh2.Outh2Application




  .   ____          _            __ _ _


 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \


( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \


 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )


  '  |____| .__|_| |_|_| |_\__, | / / / /


 =========|_|==============|___/=/_/_/_/


 :: Spring Boot ::                (v3.1.1)


2023-07-08T11:30:14.134+05:30  INFO 23896 --- [           main] c.e.danwega.outh2.Outh2Application       : Starting Outh2Application using Java 18.0.1 with PID 23896 (C:\Project\Tutorial\MicroService\Code\outh2\target\classes started by {yourmachineName}in C:\Project\Tutorial\MicroService\Code\outh2)


2023-07-08T11:30:14.137+05:30  INFO 23896 --- [           main] c.e.danwega.outh2.Outh2Application       : No active profile set, falling back to 1 default profile: "default"


2023-07-08T11:30:15.330+05:30  INFO 23896 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8210 (http)


2023-07-08T11:30:15.342+05:30  INFO 23896 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]


2023-07-08T11:30:15.342+05:30  INFO 23896 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.10]


2023-07-08T11:30:15.458+05:30  INFO 23896 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext

2023-07-08T11:30:15.460+05:30  INFO 23896 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1246 ms

2023-07-08T11:30:15.916+05:30  WARN 23896 --- [           main] .s.s.UserDetailsServiceAutoConfiguration : 

Using generated security password: b584e3b2-5840-48a8-a412-f1fbe3dd4b04

This generated password is for development use only. Your security configuration must be updated before running your application in production.

2023-07-08T11:30:16.045+05:30  INFO 23896 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@163042ea, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@11d045b4, org.springframework.security.web.context.SecurityContextHolderFilter@3252747e, org.springframework.security.web.header.HeaderWriterFilter@3234474, org.springframework.security.web.csrf.CsrfFilter@1e692555, org.springframework.security.web.authentication.logout.LogoutFilter@d3f4505, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@73aeef7d, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@2c7db926, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@1fbf088b, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@67022ea, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@2dd8ff1d, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@2bfaba70, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@1943c1f2, org.springframework.security.web.access.ExceptionTranslationFilter@6ef60295, org.springframework.security.web.access.intercept.AuthorizationFilter@7ddd84b5]


2023-07-08T11:30:16.100+05:30  INFO 23896 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8210 (http) with context path ''


2023-07-08T11:30:16.107+05:30  INFO 23896 --- [           main] c.e.danwega.outh2.Outh2Application       : Started Outh2Application in 2.479 seconds (process running for 2.901)


2023-07-08T11:31:08.174+05:30  INFO 23896 --- [nio-8210-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'


2023-07-08T11:31:08.174+05:30  INFO 23896 --- [nio-8210-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'


2023-07-08T11:31:08.175+05:30  INFO 23896 --- [nio-8210-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms



Tuesday, July 4, 2023

Java Basics - Record

 Record is one of the cool features Java has and below are the difference with normal class Vs Record class and how it will help us to get rid of boilerplate code.

For understanding purpose, we create a simple class with two variables, name and email.

you can see how much code we need to write in legacy class to deal with just to deal with a record/object with two variables

  • two variables
  • Getters and setter
  • Constructor
  • equals and hashcode
  • toString() Method

In Record

    just the class name with variables inside parenthesis


Record

variables are final - so no setters

Record will create a canonocal constructor - with parametrs you have given, where in class it will create only default constructor without paramters

Can have instance methods.

Can have static methods

Static variables, cannot create instance variables - why , by default, Record is a final

Get the value of variables using the name and paranthesis eg:varibaleName()

Record has by default toString method

Cannot extend any class cause By default it extends Record class, But you can implement any interface

Has a compact constructor

Can have validations here

name of the record is enough to declare constructor with "public" access

eg: 

public record SampleRecord(String name, String email) {
 public SampleRecord {
if (name.isBlank()) {
throw new IllegalArgumentException("Name cannot be blank.");
}
}

}


Below are sample code blocks

package com.example.demo.records;

import java.util.Objects;

public class SampleClass {
private String name;
private String email;

public SampleClass(String name, String email) {
this.name = name;
this.email = email;
}

public String getName() {
return name;
}

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

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

@Override
public String toString() {
return "SampleClass{" +
"name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SampleClass that = (SampleClass) o;
return name.equals(that.name) && email.equals(that.email);
}

@Override
public int hashCode() {
return Objects.hash(name, email);
}
}
package com.example.demo.records;

public record SampleRecord(String name, String email) {

public static String STATIC_VARIABLE = "static_variable";
// Instance variables are not allowed as by default variables are final cause of Record
//public String instanceVarible ="instanceVairableNot Allowed";
public String instanceMethod() {
return name();
}

public static void staticMethod() {
System.out.println("From static method");
}


public SampleRecord {
if (name.isBlank()) {
throw new IllegalArgumentException("Name cannot be blank.");
}
}

}
package com.example.demo.records;

public class TestSampleRecord {
public static void main(String[] args) {
SampleClass sampleClass = new SampleClass("Roshan", "roshan@email.com");
System.out.println(sampleClass);

SampleRecord sampleRecord = new SampleRecord("Mahanama", "mahanama@email.com");
System.out.println("default toString method in Record");
System.out.println(sampleRecord);
System.out.println("From instance method :" + sampleRecord.instanceMethod());
SampleRecord.staticMethod();
System.out.println(new SampleRecord("", ""));
}
}

 Output

SampleClass{name='Roshan', email='roshan@email.com'}

default toString method in Record

SampleRecord[name=Mahanama, email=mahanama@email.com]

From instance method :Mahanama

From static method

Exception in thread "main" java.lang.IllegalArgumentException: Name cannot be blank.

at com.example.demo.records.SampleRecord.<init>(SampleRecord.java:16)

at com.example.demo.records.TestSampleRecord.main(TestSampleRecord.java:13)



Thursday, June 29, 2023

Springboot - Maven - Issues with downloading dependencies

 Due to various reason, your dependencies might not downloaded. There is no exact answer as it depends on the issue comes with that situation.

Below is one solution you can try.


<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>


Tuesday, June 27, 2023

MS - chapter 4 - Create Config server - Problem with *

 Error


org.springframework.cloud.config.server.environment.FailedToConstructEnvironmentException: Could not construct context for config=student profile=default label=null includeOrigin=true; nested exception is while scanning an alias

 in 'reader', line 33, column 18:

            include: *

                     ^

unexpected character found  (0)

 in 'reader', line 33, column 19:

            include: *

                      ^


at org.springframework.cloud.config.server.environment.NativeEnvironmentRepository.findOne(NativeEnvironmentRepository.java:165) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at org.springframework.cloud.config.server.environment.CompositeEnvironmentRepository.findOne(CompositeEnvironmentRepository.java:82) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at org.springframework.cloud.config.server.environment.ObservationEnvironmentRepositoryWrapper.lambda$findOne$3(ObservationEnvironmentRepositoryWrapper.java:75) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at io.micrometer.observation.Observation.lambda$observe$4(Observation.java:544) ~[micrometer-observation-1.11.1.jar:1.11.1]

at io.micrometer.observation.Observation.observeWithContext(Observation.java:603) ~[micrometer-observation-1.11.1.jar:1.11.1]

at io.micrometer.observation.Observation.observe(Observation.java:544) ~[micrometer-observation-1.11.1.jar:1.11.1]

at org.springframework.cloud.config.server.environment.ObservationEnvironmentRepositoryWrapper.findOne(ObservationEnvironmentRepositoryWrapper.java:75) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at org.springframework.cloud.config.server.environment.EnvironmentEncryptorEnvironmentRepository.findOne(EnvironmentEncryptorEnvironmentRepository.java:64) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at org.springframework.cloud.config.server.environment.EnvironmentController.getEnvironment(EnvironmentController.java:134) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at org.springframework.cloud.config.server.environment.EnvironmentController.defaultLabelIncludeOrigin(EnvironmentController.java:116) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]

at java.base/java.lang.reflect.Method.invoke(Method.java:577) ~[na:na]

at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:281) ~[spring-core-6.0.10.jar:6.0.10]

at org.springframework.cloud.context.scope.GenericScope$LockedScopedProxyFactoryBean.invoke(GenericScope.java:482) ~[spring-cloud-context-4.0.3.jar:4.0.3]

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.0.10.jar:6.0.10]

at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:756) ~[spring-aop-6.0.10.jar:6.0.10]

at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) ~[spring-aop-6.0.10.jar:6.0.10]

at org.springframework.cloud.config.server.environment.EnvironmentController$$SpringCGLIB$$0.defaultLabelIncludeOrigin(<generated>) ~[spring-cloud-config-server-4.0.3.jar:4.0.3]

at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]

at java.base/java.lang.reflect.Method.invoke(Method.java:577) ~[na:na]

at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) ~[spring-web-6.0.10.jar:6.0.10]

at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) ~[spring-web-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[spring-webmvc-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) ~[spring-webmvc-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.10.jar:6.0.10]

at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.0.10.jar:6.0.10]

at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.10.jar:6.0]

at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.10.jar:6.0.10]

at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.10.jar:6.0]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.10.jar:10.1.10]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.10.jar:6.0.10]

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.10.jar:6.0.10]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.10.jar:6.0.10]

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.10.jar:6.0.10]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.10.jar:6.0.10]

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.10.jar:6.0.10]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.10.jar:10.1.10]

at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

Caused by: org.yaml.snakeyaml.scanner.ScannerException: while scanning an alias

 in 'reader', line 33, column 18:

            include: *

                     ^

unexpected character found  (0)

 in 'reader', line 33, column 19:

            include: *

                      ^

Reason

Problem with * character in the yaml file. 

#Enable actuator and all
management:
endpoints:
web:
exposure:
include: *

Here we give * 

solution

give the star character inside the quotes

#Enable actuator and all
management:
endpoints:
web:
exposure:
include: "*"




MS - chapter 4 - Create Config server

 Let's create config server to keep all the configurations and get the configurations from it.

Up to now, we have kept all the configurations in the same service. Here we are going to create a separate service to keep only the configurations.

Below are the steps

1. create spring boot application adding "config server" dependency

        <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency

2. add @EnableConfigServer annotation in the main class

3. create a "config" directory inside resources folder. After that create files with each service name

eg: student.yaml

copy all the configurations from service, here student service

4. Go to respective service (student service) and add the link to configuration server.

you can keep the service name in the respective property files inside each service.

As you shown client service to import details from config server , now student service can take properties from config server

spring:
application:
name: student
config:
import: optional:configserver:http://localhost:8088
cloud:
config:
server:
bootstrap: true

5. Not enough, you need to add the config server client dependency to the student service.

<!--config server client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>

6. 


   

Below is the total code samples for Config server

main class

package com.demo.micro.configserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {

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

}


Student .yaml file inside "config" directory

server:
port: 8203
spring:
datasource:
url: jdbc:mysql://localhost:3306/student_mgt
username: root
password: root

# for Spring Boot 2
# spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect
# for Spring Boot 3
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.MySQLDialect
show-sql: false
generate-ddl: true
# Hibernate ddl auto (create, create-drop, validate, update)
hibernate:
ddl-auto: update
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
#Enable actuator and all
management:
endpoints:
web:
exposure:
include: "*"


application.yaml

server:
port: 8088
spring:
profiles:
active: native

POM 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo.micro</groupId>
<artifactId>config-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>config-server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2022.0.3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

Student Service - application.yaml

spring:
application:
name: student
config:
import: optional:configserver:http://localhost:8088
cloud:
config:
server:
bootstrap: true



Monday, June 26, 2023

Spring Security - Step4 - Sample Spring Security application - Take User Info from database

Before we have hard coded user details inside the "SecurityConfig" and loaded using "InMemoryUserDetailsManager"
Now let's take those details from database
To do that we need
1. create a entity/model class to map the database table --> UserInfo
2. Repository class --> UserInfoRepository
3. UserController class to save the details of new user
4. UserService class to connect Repository class
5.  UserInfoUserDetails config class which implements UserDetails class for configurations

Below is the code

SecurityConfig

package com.example.springsecurityjavaTechie.config;

import com.example.springsecurityjavaTechie.service.UserInfoUserDetailsService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;


@RequiredArgsConstructor
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {

@Bean
UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
// authentication
// UserDetails admin = User.withUsername("Alex")
// .password(passwordEncoder.encode("Pwd1"))
// .roles("ADMIN")
// .build();
// UserDetails user = User.withUsername("John")
// .password(passwordEncoder().encode("Pwd2"))
// .roles("USER")
// .build();
// return new InMemoryUserDetailsManager(admin, user);
return new UserInfoUserDetailsService();
}

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/products/welcome", "/users/new").permitAll()//just let any one access
.and()
.authorizeHttpRequests().requestMatchers("/products/**")
.authenticated().and().formLogin().and().build();

}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}

package com.example.springsecurityjavaTechie.config;

import com.example.springsecurityjavaTechie.model.UserInfo;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

public class UserInfoUserDetails implements UserDetails {

private String name;
private String password;
private List<GrantedAuthority> authorities;

public UserInfoUserDetails(UserInfo userInfo){
this.name = userInfo.getName();
this.password = userInfo.getPassword();
this.authorities = Arrays.stream(userInfo.getRoles().split(","))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}

@Override
public String getPassword() {
return password;
}

@Override
public String getUsername() {
return name;
}

@Override
public boolean isAccountNonExpired() {
return true;
}

@Override
public boolean isAccountNonLocked() {
return true;
}

@Override
public boolean isCredentialsNonExpired() {
return true;
}

@Override
public boolean isEnabled() {
return true;
}
}

Controllers

package com.example.springsecurityjavaTechie.controller;

import com.example.springsecurityjavaTechie.model.Product;
import com.example.springsecurityjavaTechie.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/products")
public class ProductController {

@Autowired
private ProductService service;

@GetMapping("/welcome")
public String welcome() {
return "Welcome this endpoint is not secure";
}


@GetMapping("/all")
@PreAuthorize("hasAuthority('ROLE_ADMIN')")
public List<Product> getAllTheProducts() {
return service.getProducts();
}

@GetMapping("/{id}")
@PreAuthorize("hasAuthority('ROLE_USER')")
public Product getProductById(@PathVariable int id) {
return service.getProduct(id);
}
}
package com.example.springsecurityjavaTechie.controller;

import com.example.springsecurityjavaTechie.model.UserInfo;
import com.example.springsecurityjavaTechie.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/users")
public class UserController {

@Autowired
UserService userService;

@PostMapping("/new")
public String addNewUser(@RequestBody UserInfo userInfo) {
return userService.addUser(userInfo);
}
}

Model

package com.example.springsecurityjavaTechie.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Product {

private int productId;
private String name;
private int qty;
private double price;
}

package com.example.springsecurityjavaTechie.model;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserInfo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String email;
private String password;
private String roles;
}


Repository

package com.example.springsecurityjavaTechie.repository;


import com.example.springsecurityjavaTechie.model.UserInfo;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface UserInfoRepository extends JpaRepository<UserInfo, Integer> {
Optional<UserInfo> findByName(String username);

}
Service classes

package com.example.springsecurityjavaTechie.service;

import com.example.springsecurityjavaTechie.model.Product;
import com.example.springsecurityjavaTechie.model.UserInfo;
import com.example.springsecurityjavaTechie.repository.UserInfoRepository;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service
public class ProductService {

List<Product> productList = null;

// @Autowired
// private UserInfoRepository repository;
//
// @Autowired
// private PasswordEncoder passwordEncoder;

@PostConstruct
public void loadProductsFromDB() {
productList = IntStream.rangeClosed(1, 100)
.mapToObj(i -> Product.builder()
.productId(i)
.name("product " + i)
.qty(new Random().nextInt(10))
.price(new Random().nextInt(5000)).build()
).collect(Collectors.toList());
}


public List<Product> getProducts() {
return productList;
}

public Product getProduct(int id) {
return productList.stream()
.filter(product -> product.getProductId() == id)
.findAny()
.orElseThrow(() -> new RuntimeException("product " + id + " not found"));
}



}

package com.example.springsecurityjavaTechie.service;

import com.example.springsecurityjavaTechie.config.UserInfoUserDetails;
import com.example.springsecurityjavaTechie.model.UserInfo;
import com.example.springsecurityjavaTechie.repository.UserInfoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.Optional;

public class UserInfoUserDetailsService implements UserDetailsService {

@Autowired
UserInfoRepository userInfoRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional<UserInfo> userInfo = userInfoRepository.findByName(username);
return userInfo.map(UserInfoUserDetails::new)
.orElseThrow(()-> new UsernameNotFoundException("user not found "+username));
}
}

package com.example.springsecurityjavaTechie.service;

import com.example.springsecurityjavaTechie.model.UserInfo;
import com.example.springsecurityjavaTechie.repository.UserInfoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
public class UserService {

@Autowired
PasswordEncoder passwordEncoder;

@Autowired
UserInfoRepository userInfoRepository;

public String addUser(UserInfo userInfo) {
userInfo.setPassword(passwordEncoder.encode(userInfo.getPassword()));
userInfoRepository.save(userInfo);
return "user added to system ";
}
}

Main class

package com.example.springsecurityjavaTechie;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringSecurityJavaTechieApplication {

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

}

References