Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 139 additions & 19 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,63 +1,183 @@
<?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">
<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.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
<relativePath/>
</parent>

<groupId>com.coded.spring</groupId>
<artifactId>Ordering</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Kotlin.SpringbootV2</name>
<description>Kotlin.SpringbootV2</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>

<properties>
<java.version>21</java.version>
<kotlin.version>1.9.25</kotlin.version>
</properties>

<dependencies>
<!-- Spring Web & JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<!-- Password encoder -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>

<!-- Database Drivers -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>

<!-- Kotlin support -->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>

<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>

<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>

<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<scope>runtime</scope>
<version>0.11.5</version>
</dependency>

<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<scope>runtime</scope>
<version>0.11.5</version>
</dependency>

<!-- Swagger / OpenAPI -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version>
</dependency>

<!-- Jakarta Inject -->
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
</dependency>

<!-- Hazelcast Cache -->
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>5.5.0</version>
</dependency>

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

<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test-junit5</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>7.11.2</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>7.11.2</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.3.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-path</artifactId>
<version>5.3.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-schema-validator</artifactId>
<version>5.3.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>

</dependencies>

<build>
Expand Down Expand Up @@ -90,4 +210,4 @@
</plugins>
</build>

</project>
</project>
13 changes: 13 additions & 0 deletions src/main/kotlin/com/coded/spring/ordering/AppProperties.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.coded.spring.ordering

import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Configuration

@Configuration
@ConfigurationProperties
class AppProperties {
lateinit var companyName: String
var festiveMode: Boolean = false
var festiveMessage: String = "Eidkom Mubarak Coded"
var festiveDiscount: Int = 20
}
7 changes: 7 additions & 0 deletions src/main/kotlin/com/coded/spring/ordering/Application.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.coded.spring.ordering

import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast
import com.hazelcast.core.HazelcastInstance
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

Expand All @@ -8,4 +11,8 @@ class Application

fun main(args: Array<String>) {
runApplication<Application>(*args)
helloWorldConfig.getMapConfig("pets").setTimeToLiveSeconds(10)
}

val helloWorldConfig = Config("hello-world-cache")
val serverCache: HazelcastInstance = Hazelcast.newHazelcastInstance(helloWorldConfig)
34 changes: 34 additions & 0 deletions src/main/kotlin/com/coded/spring/ordering/InitUserRunner.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.coded.spring.ordering

import com.coded.spring.ordering.models.Roles
import com.coded.spring.ordering.models.User
import com.coded.spring.ordering.repo.UserRepository
import org.springframework.boot.CommandLineRunner
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Bean
import org.springframework.security.crypto.password.PasswordEncoder

@SpringBootApplication
class InitUserRunner {
@Bean
fun initUsers(userRepository: UserRepository, passwordEncoder: PasswordEncoder) = CommandLineRunner {
val user = User(
name = "HelloUser",
username = "testuser",
password = passwordEncoder.encode("Password123@"),
age = 18,
role = Roles.ADMIN
)
if (userRepository.findByUsername(user.username) == null) {
println("Creating user ${user.username}")
userRepository.save(user)
} else {
println("User ${user.username} already exists")
}
}
}

fun main(args: Array<String>) {
runApplication<InitUserRunner>(*args)
}
37 changes: 37 additions & 0 deletions src/main/kotlin/com/coded/spring/ordering/LoggingFilter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.coded.spring.ordering

import jakarta.servlet.FilterChain
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.springframework.stereotype.Component
import org.springframework.web.filter.OncePerRequestFilter
import org.springframework.web.util.ContentCachingRequestWrapper
import org.springframework.web.util.ContentCachingResponseWrapper

@Component
class LoggingFilter: OncePerRequestFilter(){
override fun doFilterInternal(
request: HttpServletRequest,
response: HttpServletResponse,
filterChain: FilterChain
) {
val cachedRequest = ContentCachingRequestWrapper(request)
val cachedResponse = ContentCachingResponseWrapper(response)

filterChain.doFilter(cachedRequest, cachedResponse)

logRequest(cachedRequest)
logResponse(cachedResponse)
cachedResponse.copyBodyToResponse()
}

private fun logRequest(request: ContentCachingRequestWrapper) {
val requestBody = String(request.contentAsByteArray)
logger.info("Request: method=${request.method}, uri=${request.requestURI}, body=$requestBody")
}

private fun logResponse(response: ContentCachingResponseWrapper) {
val responseBody = String(response.contentAsByteArray)
logger.info("Response: status=${response.status}, body=$responseBody")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.coded.spring.ordering.authentication

import org.springframework.security.core.userdetails.*
import com.coded.spring.ordering.repo.UserRepository
import org.springframework.stereotype.Service

@Service
class CustomUserDetailsService(
private val usersRepository: UserRepository) : UserDetailsService {
override fun loadUserByUsername(username: String): UserDetails {
val user = usersRepository.findByUsername(username) ?: throw UsernameNotFoundException("User not found")

return User.builder()
.username(user.username)
.password(user.password)
.roles(user.role.toString())
.build()
}
}
Loading