Skip to content

Commit

Permalink
other endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
Peva Blanchard committed Nov 27, 2024
1 parent c050468 commit c690bc2
Show file tree
Hide file tree
Showing 13 changed files with 789 additions and 105 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.cloud_assess.controller

import org.cloud_assess.api.ComputeResourcesApi
import org.cloud_assess.dto.ComputeResourceListAssessmentDto
import org.cloud_assess.dto.ComputeResourceListDto
import org.cloud_assess.service.ComputeResourceService
import org.cloud_assess.service.MapperService
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.RestController

@RestController
class ComputeResourcesController(
private val computeResourceService: ComputeResourceService,
private val mapperService: MapperService,
) : ComputeResourcesApi {
override fun assessComputeResources(computeResourceListDto: ComputeResourceListDto): ResponseEntity<ComputeResourceListAssessmentDto> {
val analysis = computeResourceService.analyze(computeResourceListDto)
val dto = mapperService.map(analysis, computeResourceListDto)
return ResponseEntity.ok(dto)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.cloud_assess.controller

import org.cloud_assess.api.StorageResourcesApi
import org.cloud_assess.dto.StorageResourceListAssessmentDto
import org.cloud_assess.dto.StorageResourceListDto
import org.cloud_assess.service.MapperService
import org.cloud_assess.service.StorageResourceService
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.RestController

@RestController
class StorageResourcesController(
private val storageResourceService: StorageResourceService,
private val mapperService: MapperService,
) : StorageResourcesApi {
override fun assessStorageResources(storageResourceListDto: StorageResourceListDto): ResponseEntity<StorageResourceListAssessmentDto> {
val analysis = storageResourceService.analyze(storageResourceListDto)
val dto = mapperService.map(analysis, storageResourceListDto)
return ResponseEntity.ok(dto)
}
}
40 changes: 40 additions & 0 deletions src/main/kotlin/org/cloud_assess/service/AnalysisJobRunner.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.cloud_assess.service

import ch.kleis.lcaac.core.assessment.ContributionAnalysisProgram
import ch.kleis.lcaac.core.lang.evaluator.Evaluator
import ch.kleis.lcaac.core.lang.expression.EProcessTemplateApplication
import ch.kleis.lcaac.core.math.basic.BasicNumber
import org.cloud_assess.dto.QuantityTimeDto
import org.cloud_assess.model.ProductMatcher
import org.cloud_assess.model.ResourceAnalysis

class AnalysisJobRunner(
private val jobSize: Int,
private val productMatcher: (String) -> ProductMatcher,
private val periodDto: QuantityTimeDto,
private val evaluator: Evaluator<BasicNumber>,

) {
fun run(cases: Map<String, EProcessTemplateApplication<BasicNumber>>): Map<String, ResourceAnalysis> {
return cases.entries
.chunked(jobSize)
.parallelStream()
.map { job ->
job.map {
val trace = evaluator.with(it.value.template).trace(it.value.template, it.value.arguments)
val systemValue = trace.getSystemValue()
val entryPoint = trace.getEntryPoint()
val program = ContributionAnalysisProgram(systemValue, entryPoint)
val rawAnalysis = program.run()
mapOf(
it.key to ResourceAnalysis(
productMatcher(it.key),
periodDto,
rawAnalysis
)
)
}.fold(emptyMap<String, ResourceAnalysis>()) { acc, element -> acc.plus(element) }
}.reduce { acc, element -> acc.plus(element) }
.orElse(emptyMap())
}
}
111 changes: 111 additions & 0 deletions src/main/kotlin/org/cloud_assess/service/ComputeResourceService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package org.cloud_assess.service

import ch.kleis.lcaac.core.datasource.DefaultDataSourceOperations
import ch.kleis.lcaac.core.datasource.in_memory.InMemoryConnector
import ch.kleis.lcaac.core.datasource.in_memory.InMemoryConnectorKeys
import ch.kleis.lcaac.core.datasource.in_memory.InMemoryDatasource
import ch.kleis.lcaac.core.lang.SymbolTable
import ch.kleis.lcaac.core.lang.evaluator.Evaluator
import ch.kleis.lcaac.core.lang.expression.EProcessTemplateApplication
import ch.kleis.lcaac.core.lang.register.DataKey
import ch.kleis.lcaac.core.lang.value.RecordValue
import ch.kleis.lcaac.core.math.basic.BasicNumber
import ch.kleis.lcaac.core.math.basic.BasicOperations
import org.cloud_assess.dto.ComputeResourceListDto
import org.cloud_assess.model.ProductMatcher
import org.cloud_assess.model.ResourceAnalysis
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service

@Service
class ComputeResourceService(
@Value("\${COMPUTE_JOB_SIZE:100}")
private val jobSize: Int,
private val parsingService: ParsingService,
private val defaultDataSourceOperations: DefaultDataSourceOperations<BasicNumber>,
private val symbolTable: SymbolTable<BasicNumber>,
) {
private val overrideTimeWindowParam = "timewindow"
private val overriddenDataSourceName = "compute_inventory"
private val helper = Helper(
defaultDataSourceOperations,
symbolTable,
)


fun analyze(computeResources: ComputeResourceListDto): Map<String, ResourceAnalysis> {
val period = with(helper) {
computeResources.period.toDataExpression()
}
val cases = cases(computeResources)
val computeResourcesConnector = inMemoryConnector(computeResources)
val sourceOps = defaultDataSourceOperations.overrideWith(computeResourcesConnector)
val evaluator = Evaluator(
symbolTable.copy(
data = symbolTable.data.override(
DataKey(overrideTimeWindowParam),
period,
)
),
BasicOperations,
sourceOps,
)
val jobRunner = AnalysisJobRunner(
jobSize = jobSize,
productMatcher = { id ->
ProductMatcher(
name = "compute",
process = "compute_fn",
arguments = mapOf("id" to id)
)
},
periodDto = computeResources.period,
evaluator = evaluator,
)
val analysis = jobRunner.run(cases)
return analysis
}

private fun inMemoryConnector(
computeResources: ComputeResourceListDto,
): InMemoryConnector<BasicNumber> {
val records = with(helper) {
computeResources.computeResources
.map { computeResource ->
RecordValue(
mapOf(
"id" to localEval(computeResource.id.toDataExpression()),
"pool_id" to localEval(computeResource.poolId.toDataExpression()),
"vcpu_size" to localEval(computeResource.vcpu.toDataExpression()),
"quantity" to localEval(computeResource.quantity.toDataExpression()),
)
)
}
}
val content = mapOf(
overriddenDataSourceName to InMemoryDatasource(records)
)
return InMemoryConnector(
config = InMemoryConnectorKeys.defaultConfig(cacheEnabled = true, cacheSize = 1024),
content = content,
)
}

private fun cases(computeResources: ComputeResourceListDto): Map<String, EProcessTemplateApplication<BasicNumber>> {
val period = with(helper) { computeResources.period.toLcaac() }
val cases = computeResources.computeResources.associate {
val content = """
process __main__ {
products {
1 u __main__
}
inputs {
$period compute from compute_fn(id = "${it.id}")
}
}
""".trimIndent()
it.id to parsingService.processTemplateApplication(content)
}
return cases
}
}
67 changes: 67 additions & 0 deletions src/main/kotlin/org/cloud_assess/service/Helper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package org.cloud_assess.service

import ch.kleis.lcaac.core.datasource.DefaultDataSourceOperations
import ch.kleis.lcaac.core.lang.SymbolTable
import ch.kleis.lcaac.core.lang.evaluator.ToValue
import ch.kleis.lcaac.core.lang.evaluator.reducer.DataExpressionReducer
import ch.kleis.lcaac.core.lang.expression.DataExpression
import ch.kleis.lcaac.core.lang.expression.EDataRef
import ch.kleis.lcaac.core.lang.expression.EQuantityScale
import ch.kleis.lcaac.core.lang.expression.EStringLiteral
import ch.kleis.lcaac.core.lang.register.DataSourceRegister
import ch.kleis.lcaac.core.lang.value.DataValue
import ch.kleis.lcaac.core.math.basic.BasicNumber
import ch.kleis.lcaac.core.math.basic.BasicOperations
import org.cloud_assess.dto.*

class Helper(
defaultDataSourceOperations: DefaultDataSourceOperations<BasicNumber>,
symbolTable: SymbolTable<BasicNumber>,
) {
private val dataReducer = DataExpressionReducer(
dataRegister = symbolTable.data,
dataSourceRegister = DataSourceRegister.empty(),
ops = BasicOperations,
sourceOps = defaultDataSourceOperations,
)

fun localEval(expression: DataExpression<BasicNumber>): DataValue<BasicNumber> {
val data = dataReducer.reduce(expression)
return with(ToValue(BasicOperations)) {
data.toValue()
}
}

fun QuantityTimeDto.toDataExpression(): DataExpression<BasicNumber> {
return when (this.unit) {
TimeUnitsDto.hour -> EQuantityScale(BasicNumber(this.amount), EDataRef("hour"))
}
}

fun QuantityTimeDto.toLcaac(): String {
return when (this.unit) {
TimeUnitsDto.hour -> "${this.amount} hour"
}
}

fun String.toDataExpression(): DataExpression<BasicNumber> = EStringLiteral(this)

fun QuantityMemoryDto.toDataExpression(): DataExpression<BasicNumber> {
return when (this.unit) {
MemoryUnitsDto.gB -> EQuantityScale(BasicNumber(this.amount), EDataRef("GB"))
MemoryUnitsDto.tB -> EQuantityScale(BasicNumber(this.amount), EDataRef("TB"))
}
}

fun QuantityVCPUDto.toDataExpression(): DataExpression<BasicNumber> {
return when (this.unit) {
VCPUUnitsDto.vCPU -> EQuantityScale(BasicNumber(this.amount), EDataRef("vCPU"))
}
}

fun QuantityDimensionlessDto.toDataExpression(): DataExpression<BasicNumber> {
return when (this.unit) {
DimensionlessUnitsDto.u -> EQuantityScale(BasicNumber(this.amount), EDataRef("u"))
}
}
}
29 changes: 29 additions & 0 deletions src/main/kotlin/org/cloud_assess/service/MapperService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,22 @@ class MapperService {
}.toList()
}

fun map(
analysis: Map<String, ResourceAnalysis>,
dto: ComputeResourceListDto,
): ComputeResourceListAssessmentDto {
return ComputeResourceListAssessmentDto(
dto.computeResources.map {
val computeResourceAnalysis = analysis[it.id] ?: throw IllegalStateException("Unknown compute_resource '${it.id}'")
ComputeResourceAssessmentDto(
period = dto.period,
request = it,
impacts = impactsDto(computeResourceAnalysis)
)
}
)
}

fun map(
analysis: Map<String, ResourceAnalysis>,
dto: PoolListDto
Expand Down Expand Up @@ -182,4 +198,17 @@ class MapperService {
IR = impactDto(analysis, Indicator.IR),
)
}

fun map(analysis: Map<String, ResourceAnalysis>, dto: StorageResourceListDto): StorageResourceListAssessmentDto {
return StorageResourceListAssessmentDto(
dto.storageResources.map {
val storageResourceAnalysis = analysis[it.id] ?: throw IllegalStateException("Unknown storage_resource '${it.id}'")
StorageResourceAssessmentDto(
period = dto.period,
request = it,
impacts = impactsDto(storageResourceAnalysis),
)
}
)
}
}
9 changes: 5 additions & 4 deletions src/main/kotlin/org/cloud_assess/service/PoolService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import ch.kleis.lcaac.core.lang.expression.EProcessTemplateApplication
import ch.kleis.lcaac.core.math.basic.BasicNumber
import ch.kleis.lcaac.core.math.basic.BasicOperations
import org.cloud_assess.dto.PoolListDto
import org.cloud_assess.dto.TimeUnitsDto
import org.cloud_assess.model.ProductMatcher
import org.cloud_assess.model.ResourceAnalysis
import org.springframework.stereotype.Service
Expand All @@ -19,6 +18,10 @@ class PoolService(
private val defaultDataSourceOperations: DefaultDataSourceOperations<BasicNumber>,
private val symbolTable: SymbolTable<BasicNumber>,
) {
private val helper = Helper(
defaultDataSourceOperations,
symbolTable,
)

@Suppress("DuplicatedCode")
fun analyze(pools: PoolListDto): Map<String, ResourceAnalysis> {
Expand Down Expand Up @@ -50,9 +53,7 @@ class PoolService(
private fun cases(
pools: PoolListDto,
): Map<String, EProcessTemplateApplication<BasicNumber>> {
val period = when (pools.period.unit) {
TimeUnitsDto.hour -> "${pools.period.amount} hour"
}
val period = with(helper) { pools.period.toLcaac() }
val cases = pools.pools.associate {
val content = """
process __main__ {
Expand Down
Loading

0 comments on commit c690bc2

Please sign in to comment.