Skip to content

Commit

Permalink
Merge pull request #8 from nenadjakic/improvement/security-config-ent…
Browse files Browse the repository at this point in the history
…ity-model

Security configuration etc.
  • Loading branch information
nenadjakic authored Sep 27, 2024
2 parents c1e5581 + 6d06da6 commit ac58074
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 11 deletions.
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ plugins {
id("application")
id("org.springframework.boot") version "3.3.2"
id("io.spring.dependency-management") version "1.1.6"
id("org.springdoc.openapi-gradle-plugin") version "1.9.0"
}

group = "com.github.nenadjakic.ocr.studio"
Expand All @@ -29,6 +30,7 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.modelmapper:modelmapper:3.2.1")
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0")
implementation("net.sourceforge.tess4j:tess4j:5.12.0")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.github.nenadjakic.ocr.studio.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
import org.springframework.web.cors.CorsConfiguration
import org.springframework.web.cors.CorsConfigurationSource
import org.springframework.web.cors.UrlBasedCorsConfigurationSource


@Configuration
@EnableWebSecurity
class SecurityConfig {

@Bean
fun filterChain(httpSecurity: HttpSecurity): SecurityFilterChain {
httpSecurity.cors { it.configurationSource(corsConfigurationSource()) }
httpSecurity.authorizeHttpRequests { it.anyRequest().permitAll() }
return httpSecurity.build()
}

fun corsConfigurationSource(): CorsConfigurationSource {
val configuration = CorsConfiguration()
configuration.allowedOrigins = listOf("*")
configuration.allowedMethods = listOf("*")
configuration.allowedHeaders = listOf("*")
val source = UrlBasedCorsConfigurationSource()
source.registerCorsConfiguration("/**", configuration)
return source
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.github.nenadjakic.ocr.studio.controller

import com.github.nenadjakic.ocr.studio.dto.StatusCount
import com.github.nenadjakic.ocr.studio.service.AnalyticsService
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.responses.ApiResponse
import io.swagger.v3.oas.annotations.responses.ApiResponses
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@Tag(name = "Analytics controller", description = "API endpoints for analytics.")
@RestController
@RequestMapping("/analytics")
class AnalyticsController(private val analyticsService: AnalyticsService) {

@Operation(
operationId = "getCountByStatus",
summary = "Get count by status.",
description = "Returns count by status information.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "Successfully retrieved count by status.")
]
)
@GetMapping(value = ["/count-by-status"], produces = [org.springframework.http.MediaType.APPLICATION_JSON_VALUE])
fun getCountByStatus(): ResponseEntity<List<StatusCount>> = ResponseEntity.ok(analyticsService.getCountByStatus())

@Operation(
operationId = "getAverageInDocuments",
summary = "Get average count across inDocuments.",
description = "Returns average count across inDocuments.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "Successfully retrieved average count across inDocuments.")
]
)
@GetMapping(value = ["/average-in-documents"], produces = [org.springframework.http.MediaType.APPLICATION_JSON_VALUE])
fun getAverageInDocuments(): ResponseEntity<Long> = ResponseEntity.ok(analyticsService.getAverageInDocuments())
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.github.nenadjakic.ocr.studio.dto

import java.time.ZonedDateTime
import java.time.LocalDateTime

data class SchedulerConfigRequest(var startDateTime: ZonedDateTime? = null)
data class SchedulerConfigRequest(var startDateTime: LocalDateTime? = null)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.github.nenadjakic.ocr.studio.dto

import com.github.nenadjakic.ocr.studio.entity.Status

data class StatusCount(
val status: Status,
val count: Long
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.nenadjakic.ocr.studio.entity

import java.time.ZonedDateTime
import java.time.LocalDateTime

class SchedulerConfig(
var startDateTime: ZonedDateTime? = null
var startDateTime: LocalDateTime? = null
)
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.github.nenadjakic.ocr.studio.executor

import java.time.ZonedDateTime
import java.time.LocalDateTime
import java.util.UUID

interface Executor : Runnable {
val id: UUID
val startDateTime: ZonedDateTime?
val startDateTime: LocalDateTime?
val progressInfo: ProgressInfo
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ import org.apache.pdfbox.rendering.PDFRenderer
import org.slf4j.LoggerFactory
import java.io.*
import java.nio.file.Path
import java.time.ZonedDateTime
import java.time.LocalDateTime
import java.util.*
import javax.imageio.ImageIO
import javax.xml.parsers.SAXParserFactory

class OcrExecutor(
override val id: UUID,
override val startDateTime: ZonedDateTime?,
override val startDateTime: LocalDateTime?,
private val ocrProperties: OcrProperties,
private val tesseract: ITesseract,
private val taskRepository: TaskRepository,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import com.github.nenadjakic.ocr.studio.exception.ConfigurationException
import org.springframework.scheduling.TaskScheduler
import org.springframework.stereotype.Service
import java.time.Instant
import java.time.ZonedDateTime
import java.time.LocalDateTime
import java.time.ZoneOffset
import java.util.*
import java.util.concurrent.ScheduledFuture

Expand All @@ -16,12 +17,12 @@ class ParallelizationManagerImpl(
private val futures: MutableMap<UUID, ScheduledFuture<*>> = mutableMapOf()

override fun schedule(executor: Executor) {
if (executor.startDateTime?.isBefore(ZonedDateTime.now()) == true) {
if (executor.startDateTime?.isBefore(LocalDateTime.now()) == true) {
throw ConfigurationException("Start time is wrong. Cannot schedule task.")
}

val future: ScheduledFuture<out Any> = if (executor.startDateTime != null) {
taskScheduler.schedule({ executor.run() }, executor.startDateTime!!.toInstant())
taskScheduler.schedule({ executor.run() }, executor.startDateTime!!.toInstant(ZoneOffset.UTC))
} else {
taskScheduler.schedule({ executor.run() }, Instant.now().plusSeconds(30L))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.github.nenadjakic.ocr.studio.repository

import com.github.nenadjakic.ocr.studio.dto.StatusCount
import com.github.nenadjakic.ocr.studio.entity.OcrConfig
import com.github.nenadjakic.ocr.studio.entity.SchedulerConfig
import com.github.nenadjakic.ocr.studio.entity.Task
import org.springframework.data.mongodb.repository.Aggregation
import org.springframework.data.mongodb.repository.MongoRepository
import org.springframework.data.mongodb.repository.Query
import org.springframework.data.mongodb.repository.Update
Expand All @@ -21,4 +23,17 @@ interface TaskRepository : MongoRepository<Task, UUID> {
@Query(value = "{ 'id': ?0 }")
@Update("{ 'ocrConfig.language': ?1 }")
fun updateLanguageById(id: UUID, language: String): Int

@Aggregation(pipeline = [
"{ '\$group': { '_id': '\$ocrProgress.status', 'count': { '\$sum': 1 } } }",
"{ '\$project': { 'status': '\$_id', 'count': 1, '_id': 0 } }"
])
fun countTasksByStatus(): List<StatusCount>

@Aggregation(pipeline = [
"{ '\$project': { 'numInDocuments': { '\$size': '\$inDocuments' } } }",
"{ '\$group': { '_id': null, 'averageCount': { '\$avg': '\$numInDocuments' } } }",
"{ '\$project': { '_id': 0, 'averageCount': 1 } }"
])
fun averageInDocuments(): Long
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.github.nenadjakic.ocr.studio.service

import com.github.nenadjakic.ocr.studio.dto.StatusCount
import com.github.nenadjakic.ocr.studio.repository.TaskRepository
import org.springframework.stereotype.Service

@Service
class AnalyticsService(
private val taskRepository: TaskRepository
) {
fun getCountByStatus(): List<StatusCount> = taskRepository.countTasksByStatus()

fun getAverageInDocuments(): Long = taskRepository.averageInDocuments()
}

0 comments on commit ac58074

Please sign in to comment.