diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1981ac5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.idea
+target
\ No newline at end of file
diff --git a/README.md b/README.md
index b1cd613..62d6a23 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,3 @@
# onecx-parameter-svc
+
OneCx Parameter Management Service
diff --git a/openapi/openapi-internal.yaml b/openapi/openapi-internal.yaml
new file mode 100644
index 0000000..a73ec8f
--- /dev/null
+++ b/openapi/openapi-internal.yaml
@@ -0,0 +1,590 @@
+---
+openapi: 3.0.3
+info:
+ title: onecx-parameters
+ description: OneCx parameters
+ version: "2.0"
+servers:
+- url: http://onecx-parameters-svc:8080/
+tags:
+- name: internal
+paths:
+ /histories:
+ get:
+ tags:
+ - internal
+ description: Find all parameters history
+ operationId: getAllApplicationParametersHistory
+ parameters:
+ - name: applicationId
+ in: query
+ schema:
+ description: The application parameter id.
+ type: string
+ - name: key
+ in: query
+ schema:
+ description: The application parameter key.
+ type: string
+ - name: pageNumber
+ in: query
+ schema:
+ format: int32
+ description: The number of page.
+ default: "0"
+ type: integer
+ - name: pageSize
+ in: query
+ schema:
+ format: int32
+ description: The size of page
+ default: "100"
+ type: integer
+ - name: type
+ in: query
+ schema:
+ description: The application parameter type.
+ type: array
+ items:
+ type: string
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ApplicationParameterHistoryPageResultDTO'
+ "400":
+ description: Bad request
+ "500":
+ description: Internal Server Error
+ /histories/counts:
+ get:
+ tags:
+ - internal
+ description: Get creation dates and counts by criteria
+ operationId: getCountsByCriteria
+ parameters:
+ - name: applicationId
+ in: query
+ schema:
+ description: The application parameter id.
+ type: string
+ - name: key
+ in: query
+ schema:
+ description: The application parameter key.
+ type: string
+ - name: pageNumber
+ in: query
+ schema:
+ format: int32
+ description: The number of page.
+ default: "0"
+ type: integer
+ - name: pageSize
+ in: query
+ schema:
+ format: int32
+ description: The size of page
+ default: "100"
+ type: integer
+ - name: type
+ in: query
+ schema:
+ description: The application parameter type.
+ type: array
+ items:
+ type: string
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/ParameterHistoryCountDTO'
+ "400":
+ description: Bad request
+ "500":
+ description: Internal Server Error
+ /histories/latest:
+ get:
+ tags:
+ - internal
+ description: Find all parameters history latest
+ operationId: getAllApplicationParametersHistoryLatest
+ parameters:
+ - name: applicationId
+ in: query
+ schema:
+ description: The application parameter id.
+ type: string
+ - name: key
+ in: query
+ schema:
+ description: The application parameter key.
+ type: string
+ - name: pageNumber
+ in: query
+ schema:
+ format: int32
+ description: The number of page.
+ default: "0"
+ type: integer
+ - name: pageSize
+ in: query
+ schema:
+ format: int32
+ description: The size of page
+ default: "100"
+ type: integer
+ - name: type
+ in: query
+ schema:
+ description: The application parameter type.
+ type: array
+ items:
+ type: string
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ApplicationParameterHistoryPageResultDTO'
+ "400":
+ description: Bad request
+ "500":
+ description: Internal Server Error
+ /histories/{id}:
+ get:
+ tags:
+ - internal
+ description: Find parameters history by Id
+ operationId: getApplicationParametersHistoryById
+ parameters:
+ - name: id
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ApplicationParameterHistoryDTO'
+ "400":
+ description: Bad request
+ "404":
+ description: Not Found
+ "500":
+ description: Internal Server Error
+ /parameters:
+ get:
+ tags:
+ - internal
+ description: Find all parameters
+ operationId: getAllApplicationParameters
+ parameters:
+ - name: applicationId
+ in: query
+ schema:
+ description: The application parameter id.
+ type: string
+ - name: key
+ in: query
+ schema:
+ description: The application parameter key.
+ type: string
+ - name: name
+ in: query
+ schema:
+ description: The application parameter name.
+ type: string
+ - name: pageNumber
+ in: query
+ schema:
+ format: int32
+ description: The number of page.
+ default: "0"
+ type: integer
+ - name: pageSize
+ in: query
+ schema:
+ format: int32
+ description: The size of page
+ default: "100"
+ type: integer
+ - name: type
+ in: query
+ schema:
+ description: The application parameter type.
+ type: object
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ApplicationParameterPageResultDTO'
+ "400":
+ description: Bad request
+ "500":
+ description: Internal Server Error
+ post:
+ tags:
+ - internal
+ description: Create parameter
+ operationId: createParameterValue
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ApplicationParameterCreateDTO'
+ responses:
+ "204":
+ description: No Content
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/RestExceptionDTO'
+ "404":
+ description: Not Found
+ "500":
+ description: Internal Server Error
+ /parameters/applications:
+ get:
+ tags:
+ - internal
+ description: Find all parameters
+ operationId: getAllApplications
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ApplicationsPageResultDTO'
+ "400":
+ description: Bad request
+ "500":
+ description: Internal Server Error
+ /parameters/keys:
+ get:
+ tags:
+ - internal
+ description: Find all parameters
+ operationId: getAllKeys
+ parameters:
+ - name: applicationId
+ in: query
+ schema:
+ description: The application parameter id.
+ type: string
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/KeysPageResultDTO'
+ "400":
+ description: Bad request
+ "500":
+ description: Internal Server Error
+ /parameters/{id}:
+ get:
+ tags:
+ - internal
+ description: Find parameter by id
+ operationId: getParameterById
+ parameters:
+ - name: id
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ApplicationParameterDTO'
+ "400":
+ description: Bad request
+ "404":
+ description: Not Found
+ "500":
+ description: Internal Server Error
+ put:
+ tags:
+ - internal
+ description: Update parameter
+ operationId: updateParameterValue
+ parameters:
+ - name: id
+ in: path
+ required: true
+ schema:
+ type: string
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ApplicationParameterUpdateDTO'
+ responses:
+ "204":
+ description: No Content
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/RestExceptionDTO'
+ "404":
+ description: Not Found
+ "500":
+ description: Internal Server Error
+ delete:
+ tags:
+ - internal
+ description: Delete parameter
+ operationId: deleteParameter
+ parameters:
+ - name: id
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ "204":
+ description: No Content
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/RestExceptionDTO'
+ "500":
+ description: Internal Server Error
+components:
+ schemas:
+ ApplicationParameterCreateDTO:
+ type: object
+ properties:
+ key:
+ type: string
+ applicationId:
+ type: string
+ value:
+ type: string
+ type:
+ type: string
+ description:
+ type: string
+ unit:
+ type: string
+ rangeFrom:
+ format: int32
+ type: integer
+ rangeTo:
+ format: int32
+ type: integer
+ ApplicationParameterDTO:
+ type: object
+ properties:
+ id:
+ type: string
+ modificationCount:
+ format: int32
+ type: integer
+ creationDate:
+ format: date-time
+ type: string
+ example: 2022-03-10T12:15:50-04:00
+ creationUser:
+ type: string
+ modificationDate:
+ format: date-time
+ type: string
+ example: 2022-03-10T12:15:50-04:00
+ modificationUser:
+ type: string
+ name:
+ type: string
+ description:
+ type: string
+ applicationId:
+ type: string
+ key:
+ type: string
+ setValue:
+ type: string
+ importValue:
+ type: string
+ type:
+ type: string
+ unit:
+ type: string
+ rangeFrom:
+ format: int32
+ type: integer
+ rangeTo:
+ format: int32
+ type: integer
+ ApplicationParameterHistoryDTO:
+ type: object
+ properties:
+ id:
+ type: string
+ modificationCount:
+ format: int32
+ type: integer
+ creationDate:
+ format: date-time
+ type: string
+ example: 2022-03-10T12:15:50-04:00
+ creationUser:
+ type: string
+ modificationDate:
+ format: date-time
+ type: string
+ example: 2022-03-10T12:15:50-04:00
+ modificationUser:
+ type: string
+ applicationId:
+ type: string
+ key:
+ type: string
+ usedValue:
+ type: string
+ defaultValue:
+ type: string
+ type:
+ type: string
+ instanceId:
+ type: string
+ ApplicationParameterHistoryPageResultDTO:
+ type: object
+ properties:
+ totalElements:
+ format: int64
+ description: The total elements in the resource.
+ type: integer
+ number:
+ format: int32
+ type: integer
+ size:
+ format: int32
+ type: integer
+ totalPages:
+ format: int64
+ type: integer
+ stream:
+ type: array
+ items:
+ $ref: '#/components/schemas/ApplicationParameterHistoryDTO'
+ ApplicationParameterPageResultDTO:
+ type: object
+ properties:
+ totalElements:
+ format: int64
+ description: The total elements in the resource.
+ type: integer
+ number:
+ format: int32
+ type: integer
+ size:
+ format: int32
+ type: integer
+ totalPages:
+ format: int64
+ type: integer
+ stream:
+ type: array
+ items:
+ $ref: '#/components/schemas/ApplicationParameterDTO'
+ ApplicationParameterUpdateDTO:
+ type: object
+ properties:
+ value: {}
+ description:
+ type: string
+ unit:
+ type: string
+ rangeFrom:
+ format: int32
+ type: integer
+ rangeTo:
+ format: int32
+ type: integer
+ ApplicationsPageResultDTO:
+ type: object
+ properties:
+ totalElements:
+ format: int64
+ description: The total elements in the resource.
+ type: integer
+ number:
+ format: int32
+ type: integer
+ size:
+ format: int32
+ type: integer
+ totalPages:
+ format: int64
+ type: integer
+ stream:
+ type: array
+ items:
+ type: string
+ KeysPageResultDTO:
+ type: object
+ properties:
+ totalElements:
+ format: int64
+ description: The total elements in the resource.
+ type: integer
+ number:
+ format: int32
+ type: integer
+ size:
+ format: int32
+ type: integer
+ totalPages:
+ format: int64
+ type: integer
+ stream:
+ type: array
+ items:
+ type: string
+ ParameterHistoryCountDTO:
+ type: object
+ properties:
+ creationDate:
+ format: date-time
+ type: string
+ example: 2022-03-10T12:15:50
+ count:
+ format: int64
+ type: integer
+ RestExceptionDTO:
+ type: object
+ properties:
+ errorCode:
+ type: string
+ message:
+ type: string
+ parameters:
+ type: array
+ items: {}
+ namedParameters:
+ type: object
+ additionalProperties: {}
diff --git a/openapi/openapi-v2.yaml b/openapi/openapi-v2.yaml
new file mode 100644
index 0000000..2501391
--- /dev/null
+++ b/openapi/openapi-v2.yaml
@@ -0,0 +1,245 @@
+---
+openapi: 3.0.3
+info:
+ title: onecx-parameters
+ description: OneCx parameters
+ version: "2.0"
+servers:
+- url: http://onecx-parameters-svc:8080/
+tags:
+- name: external
+paths:
+ /v2/booleanParameters:
+ get:
+ tags:
+ - external
+ description: Get application parameter as Boolean by application id and parameter
+ key
+ operationId: getBoolean
+ parameters:
+ - name: applicationId
+ in: query
+ schema:
+ type: string
+ - name: parameterKey
+ in: query
+ schema:
+ type: string
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ type: boolean
+ "400":
+ description: Bad request
+ "404":
+ description: Not Found
+ "500":
+ description: Internal Server Error
+ /v2/integerParameters:
+ get:
+ tags:
+ - external
+ description: Get application parameter as Integer by application id and parameter
+ key
+ operationId: getInteger
+ parameters:
+ - name: applicationId
+ in: query
+ schema:
+ type: string
+ - name: parameterKey
+ in: query
+ schema:
+ type: string
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ format: int32
+ type: integer
+ "400":
+ description: Bad request
+ "404":
+ description: Not Found
+ "500":
+ description: Internal Server Error
+ /v2/longParameters:
+ get:
+ tags:
+ - external
+ description: Get application parameter as Long by application id and parameter
+ key
+ operationId: getLong
+ parameters:
+ - name: applicationId
+ in: query
+ schema:
+ type: string
+ - name: parameterKey
+ in: query
+ schema:
+ type: string
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ format: int64
+ type: integer
+ "400":
+ description: Bad request
+ "404":
+ description: Not Found
+ "500":
+ description: Internal Server Error
+ /v2/parameters:
+ get:
+ tags:
+ - external
+ description: Get application parameter by application id and parameter key
+ operationId: getParameter
+ parameters:
+ - name: applicationId
+ in: query
+ schema:
+ type: string
+ - name: parameterKey
+ in: query
+ schema:
+ type: string
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ApplicationParameterDTOV2'
+ "400":
+ description: Bad request
+ "404":
+ description: Not Found
+ "500":
+ description: Internal Server Error
+ post:
+ tags:
+ - external
+ description: Get all application parameters by application id and/or parameter
+ key
+ operationId: getAllParameters
+ parameters:
+ - name: applicationId
+ in: query
+ schema:
+ type: string
+ requestBody:
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ type: string
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/ApplicationParameterDTOV2'
+ "400":
+ description: Bad request
+ "404":
+ description: Not Found
+ "500":
+ description: Internal Server Error
+ /v2/stringParameters:
+ get:
+ tags:
+ - external
+ description: Get application parameter as String by application id and parameter
+ key
+ operationId: getString
+ parameters:
+ - name: applicationId
+ in: query
+ schema:
+ type: string
+ - name: parameterKey
+ in: query
+ schema:
+ type: string
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ type: string
+ "400":
+ description: Bad request
+ "404":
+ description: Not Found
+ "500":
+ description: Internal Server Error
+components:
+ schemas:
+ ApplicationParameterDTOV2:
+ type: object
+ properties:
+ persisted:
+ type: boolean
+ id:
+ type: string
+ version:
+ format: int32
+ type: integer
+ key:
+ type: string
+ name:
+ type: string
+ value:
+ type: string
+ description:
+ type: string
+ type:
+ $ref: '#/components/schemas/ApplicationParameterTypeDTOV2'
+ applicationId:
+ type: string
+ roleType:
+ $ref: '#/components/schemas/ApplicationParameterRoleTypeDTOV2'
+ unit:
+ type: string
+ valueRangeFrom:
+ format: int32
+ type: integer
+ valueRangeTo:
+ format: int32
+ type: integer
+ ApplicationParameterRoleTypeDTOV2:
+ enum:
+ - BUSINESS
+ - SYSTEM
+ type: string
+ ApplicationParameterTypeDTOV2:
+ enum:
+ - NUMBER
+ - STRING
+ - BOOLEAN
+ - TEXT_PASSWORD
+ - DATE
+ type: string
diff --git a/openapi/openapi-v3.yaml b/openapi/openapi-v3.yaml
new file mode 100644
index 0000000..0109162
--- /dev/null
+++ b/openapi/openapi-v3.yaml
@@ -0,0 +1,96 @@
+---
+openapi: 3.0.3
+info:
+ title: onecx-parameters
+ description: OneCx parameters
+ version: "3.0"
+servers:
+- url: http://onecx-parameters-svc:8080/
+tags:
+- name: external
+paths:
+ /v3/{appId}/history:
+ post:
+ tags:
+ - external
+ description: Update or create parameters for specific application
+ operationId: createOrUpdateParameters
+ parameters:
+ - name: appId
+ in: path
+ required: true
+ schema:
+ type: string
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ParametersBucketDTO'
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ParametersBucketDTO'
+ "400":
+ description: Bad request
+ "404":
+ description: Not Found
+ "500":
+ description: Internal Server Error
+ /v3/{appId}/parameters:
+ get:
+ tags:
+ - external
+ description: Get parameters by application id
+ operationId: getApplicationParameters
+ parameters:
+ - name: appId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema: {}
+ "400":
+ description: Bad request
+ "404":
+ description: Not Found
+ "500":
+ description: Internal Server Error
+components:
+ schemas:
+ ParameterInfoDTO:
+ type: object
+ properties:
+ count:
+ format: int64
+ type: integer
+ type:
+ type: string
+ defaultValue:
+ type: string
+ currentValue:
+ type: string
+ ParametersBucketDTO:
+ type: object
+ properties:
+ parameters:
+ type: object
+ additionalProperties:
+ $ref: '#/components/schemas/ParameterInfoDTO'
+ instanceId:
+ type: string
+ start:
+ format: date-time
+ type: string
+ example: 2022-03-10T12:15:50-04:00
+ end:
+ format: date-time
+ type: string
+ example: 2022-03-10T12:15:50-04:00
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..e48c5be
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,174 @@
+
+
+ 4.0.0
+
+ io.github.onecx
+ onecx-quarkus3-parent
+ 0.9.0
+
+
+ onecx-parameter-svc
+ 999-SNAPSHOT
+
+
+
+
+
+ org.tkit.quarkus.lib
+ tkit-quarkus-data-import
+
+
+ org.tkit.quarkus.lib
+ tkit-quarkus-jpa
+
+
+ org.tkit.quarkus.lib
+ tkit-quarkus-log-cdi
+
+
+ org.tkit.quarkus.lib
+ tkit-quarkus-log-rs
+
+
+ org.tkit.quarkus.lib
+ tkit-quarkus-log-json
+
+
+ org.tkit.quarkus.lib
+ tkit-quarkus-rest
+
+
+
+
+ io.quarkus
+ quarkus-arc
+
+
+ io.quarkus
+ quarkus-scheduler
+
+
+ io.quarkus
+ quarkus-liquibase
+
+
+ io.quarkus
+ quarkus-smallrye-health
+
+
+ io.quarkus
+ quarkus-micrometer-registry-prometheus
+
+
+ io.quarkus
+ quarkus-hibernate-orm
+
+
+ io.quarkus
+ quarkus-resteasy
+
+
+ io.quarkus
+ quarkus-resteasy-jackson
+
+
+ io.quarkus
+ quarkus-jdbc-postgresql
+
+
+ io.quarkus
+ quarkus-smallrye-openapi
+
+
+
+
+ org.projectlombok
+ lombok
+
+
+ org.mapstruct
+ mapstruct
+
+
+
+
+ io.quarkus
+ quarkus-junit5
+ test
+
+
+ io.quarkus
+ quarkus-junit5-mockito
+ test
+
+
+ io.rest-assured
+ rest-assured
+ test
+
+
+ org.tkit.quarkus.lib
+ tkit-quarkus-test-db-import
+ test
+
+
+
+
+
+ openapi
+
+
+
+ io.smallrye
+ smallrye-open-api-maven-plugin
+
+
+ default
+
+ generate-schema
+
+
+ openapi-internal
+ http://onecx-parameters-svc:8080/
+ org.tkit.parameters.rs.internal
+ onecx-parameters
+ OneCx parameters
+ 2.0
+
+
+
+ v2
+
+ generate-schema
+
+
+ openapi-v2
+ http://onecx-parameters-svc:8080/
+ org.tkit.parameters.rs.external.v2
+ onecx-parameters
+ OneCx parameters
+ 2.0
+
+
+
+ v3
+
+ generate-schema
+
+
+ openapi-v3
+ http://onecx-parameters-svc:8080/
+ org.tkit.parameters.rs.external.v3
+ onecx-parameters
+ OneCx parameters
+ 3.0
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/docker/Dockerfile.jvm b/src/main/docker/Dockerfile.jvm
new file mode 100644
index 0000000..818f9b1
--- /dev/null
+++ b/src/main/docker/Dockerfile.jvm
@@ -0,0 +1,13 @@
+FROM registry.access.redhat.com/ubi9/openjdk-17:1.15
+
+ENV LANGUAGE='en_US:en'
+
+COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/
+COPY --chown=185 target/quarkus-app/*.jar /deployments/
+COPY --chown=185 target/quarkus-app/app/ /deployments/app/
+COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/
+
+EXPOSE 8080
+USER 185
+ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
+ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
\ No newline at end of file
diff --git a/src/main/docker/Dockerfile.native b/src/main/docker/Dockerfile.native
new file mode 100644
index 0000000..2cdc686
--- /dev/null
+++ b/src/main/docker/Dockerfile.native
@@ -0,0 +1,11 @@
+FROM registry.access.redhat.com/ubi9/ubi-minimal:9.2
+WORKDIR /work/
+RUN chown 1001 /work \
+ && chmod "g+rwX" /work \
+ && chown 1001:root /work
+COPY --chown=1001:root target/*-runner /work/application
+
+EXPOSE 8080
+USER 1001
+
+CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
\ No newline at end of file
diff --git a/src/main/helm/Chart.yaml b/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..61ae084
--- /dev/null
+++ b/src/main/helm/Chart.yaml
@@ -0,0 +1,18 @@
+apiVersion: v2
+name: onecx-parameter-svc
+version: 0.0.0
+appVersion: 0.0.0
+description: Onecx parameter management
+keywords:
+ - iam
+ - parameters
+sources:
+ - https://github.com/onecx/onecx-parameter-svc
+maintainers:
+ - name: Tkit Developer
+ email: tkit_dev@1000kit.org
+dependencies:
+ - name: helm-quarkus-app
+ alias: app
+ version: ^0
+ repository: oci://ghcr.io/onecx/charts
diff --git a/src/main/helm/values.yaml b/src/main/helm/values.yaml
new file mode 100644
index 0000000..32a6e55
--- /dev/null
+++ b/src/main/helm/values.yaml
@@ -0,0 +1,6 @@
+app:
+ image:
+ repository: "onecx/onecx-parameter-svc"
+ tag: 999-SNAPSHOT
+ db:
+ enabled: true
\ No newline at end of file
diff --git a/src/main/java/io/github/onecx/parameters/domain/criteria/ApplicationParameterHistorySearchCriteria.java b/src/main/java/io/github/onecx/parameters/domain/criteria/ApplicationParameterHistorySearchCriteria.java
new file mode 100644
index 0000000..bd726b0
--- /dev/null
+++ b/src/main/java/io/github/onecx/parameters/domain/criteria/ApplicationParameterHistorySearchCriteria.java
@@ -0,0 +1,30 @@
+package io.github.onecx.parameters.domain.criteria;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * The application parameter search criteria.
+ */
+@Getter
+@Setter
+public class ApplicationParameterHistorySearchCriteria {
+
+ /**
+ * The application ID.
+ */
+ private String applicationId;
+
+ /**
+ * The application parameter key.
+ */
+ private String key;
+
+ private List type;
+
+ private Integer pageNumber;
+
+ private Integer pageSize;
+}
diff --git a/src/main/java/io/github/onecx/parameters/domain/criteria/ApplicationParameterSearchCriteria.java b/src/main/java/io/github/onecx/parameters/domain/criteria/ApplicationParameterSearchCriteria.java
new file mode 100644
index 0000000..cfbc1e8
--- /dev/null
+++ b/src/main/java/io/github/onecx/parameters/domain/criteria/ApplicationParameterSearchCriteria.java
@@ -0,0 +1,32 @@
+package io.github.onecx.parameters.domain.criteria;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * The application parameter search criteria.
+ */
+@Getter
+@Setter
+public class ApplicationParameterSearchCriteria {
+
+ /**
+ * The application ID.
+ */
+ private String applicationId;
+
+ /**
+ * The application parameter key.
+ */
+ private String key;
+
+ private String name;
+
+ private List type;
+
+ private Integer pageNumber;
+
+ private Integer pageSize;
+}
diff --git a/src/main/java/io/github/onecx/parameters/domain/criteria/KeysSearchCriteria.java b/src/main/java/io/github/onecx/parameters/domain/criteria/KeysSearchCriteria.java
new file mode 100644
index 0000000..dfa8d69
--- /dev/null
+++ b/src/main/java/io/github/onecx/parameters/domain/criteria/KeysSearchCriteria.java
@@ -0,0 +1,12 @@
+package io.github.onecx.parameters.domain.criteria;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class KeysSearchCriteria {
+
+ private String applicationId;
+
+}
diff --git a/src/main/java/io/github/onecx/parameters/domain/daos/ApplicationParameterDAO.java b/src/main/java/io/github/onecx/parameters/domain/daos/ApplicationParameterDAO.java
new file mode 100644
index 0000000..4644a38
--- /dev/null
+++ b/src/main/java/io/github/onecx/parameters/domain/daos/ApplicationParameterDAO.java
@@ -0,0 +1,174 @@
+package io.github.onecx.parameters.domain.daos;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.persistence.criteria.*;
+import jakarta.transaction.Transactional;
+
+import org.tkit.quarkus.jpa.daos.AbstractDAO;
+import org.tkit.quarkus.jpa.daos.Page;
+import org.tkit.quarkus.jpa.daos.PageResult;
+import org.tkit.quarkus.jpa.exceptions.DAOException;
+
+import io.github.onecx.parameters.domain.criteria.ApplicationParameterSearchCriteria;
+import io.github.onecx.parameters.domain.criteria.KeysSearchCriteria;
+import io.github.onecx.parameters.domain.models.ApplicationParameter;
+import io.github.onecx.parameters.domain.models.ApplicationParameter_;
+
+@ApplicationScoped
+@Transactional(value = Transactional.TxType.NOT_SUPPORTED, rollbackOn = DAOException.class)
+public class ApplicationParameterDAO extends AbstractDAO {
+
+ // keys in format
+ public Map findApplicationParametersByKeys(Set keys, String separator) {
+ try {
+ CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
+ CriteriaQuery cq = cb.createQuery(ApplicationParameter.class);
+ Root root = cq.from(ApplicationParameter.class);
+
+ // 'app__key' in ( ... )
+ cq.where(cb.concat(
+ cb.concat(root.get(ApplicationParameter_.APPLICATION_ID), separator), root.get(ApplicationParameter_.KEY))
+ .in(keys));
+
+ List params = getEntityManager().createQuery(cq).getResultList();
+ return params.stream().collect(Collectors.toMap(x -> x.getApplicationId() + separator + x.getKey(), x -> x));
+ } catch (Exception e) {
+ throw new DAOException(ErrorKeys.FIND_PARAMETER_BY_APPLICATION_ID_AND_PARAMETER_KEY_FAILED, e);
+ }
+ }
+
+ public List findByApplicationIdAndParameterAndTypeKeys(String applicationId,
+ String parameterKey,
+ String parameterType) {
+ try {
+ CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
+ CriteriaQuery cq = cb.createQuery(ApplicationParameter.class);
+ Root root = cq.from(ApplicationParameter.class);
+ cq.where(cb.and(
+ cb.equal(root.get(ApplicationParameter_.APPLICATION_ID), applicationId),
+ cb.equal(root.get(ApplicationParameter_.KEY), parameterKey),
+ cb.equal(root.get(ApplicationParameter_.TYPE), parameterType)));
+ return getEntityManager().createQuery(cq).getResultList();
+ } catch (Exception e) {
+ throw new DAOException(ErrorKeys.FIND_PARAMETERS_BY_APPLICATION_AND_PARAMETER_KEY_TYPE_FAILED, e);
+ }
+ }
+
+ public List findByApplicationIdAndParameterKeys(String applicationId, List parametersKeys) {
+
+ try {
+ CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
+ CriteriaQuery cq = cb.createQuery(ApplicationParameter.class);
+ Root root = cq.from(ApplicationParameter.class);
+ cq.where(cb.and(
+ cb.equal(root.get(ApplicationParameter_.APPLICATION_ID), applicationId),
+ root.get(ApplicationParameter_.KEY).in(parametersKeys)));
+ return getEntityManager().createQuery(cq).getResultList();
+ } catch (Exception e) {
+ throw new DAOException(ErrorKeys.FIND_PARAMETERS_BY_APPLICATION_AND_PARAMETER_KEYS_FAILED, e);
+ }
+ }
+
+ public Map findAllByApplicationId(String applicationId) {
+ try {
+ CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
+ CriteriaQuery cq = cb.createQuery(ApplicationParameter.class);
+ Root root = cq.from(ApplicationParameter.class);
+ cq.where(cb.and(
+ cb.equal(root.get(ApplicationParameter_.APPLICATION_ID), applicationId),
+ cb.or(
+ cb.isNotNull(root.get(ApplicationParameter_.SET_VALUE)),
+ cb.isNotNull(root.get(ApplicationParameter_.IMPORT_VALUE)))));
+
+ return getEntityManager()
+ .createQuery(cq)
+ .getResultStream()
+ .collect(Collectors.toMap(ApplicationParameter::getKey,
+ p -> p.getSetValue() != null ? p.getSetValue() : p.getImportValue()));
+
+ } catch (Exception e) {
+ throw new DAOException(ErrorKeys.FIND_ALL_PARAMETERS_BY_APPLICATION_ID_FAILED, e);
+ }
+ }
+
+ public PageResult searchByCriteria(ApplicationParameterSearchCriteria criteria) {
+ try {
+ CriteriaQuery cq = criteriaQuery();
+ Root root = cq.from(ApplicationParameter.class);
+ List predicates = new ArrayList<>();
+ CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
+ if (criteria.getApplicationId() != null && !criteria.getApplicationId().isEmpty()) {
+ predicates.add(cb.like(cb.lower(root.get(ApplicationParameter_.APPLICATION_ID)),
+ stringPattern(criteria.getApplicationId())));
+ }
+ if (criteria.getKey() != null && !criteria.getKey().isEmpty()) {
+ predicates.add(cb.like(cb.lower(root.get(ApplicationParameter_.KEY)), stringPattern(criteria.getKey())));
+ }
+ if (criteria.getName() != null && !criteria.getName().isEmpty()) {
+ predicates.add(cb.like(cb.lower(root.get(ApplicationParameter_.NAME)), stringPattern(criteria.getName())));
+ }
+ if (!criteria.getType().isEmpty()) {
+ predicates.add(root.get(ApplicationParameter_.TYPE).in(criteria.getType()));
+ }
+ if (!predicates.isEmpty()) {
+ cq.where(cb.and(predicates.toArray(new Predicate[0])));
+ }
+ return createPageQuery(cq, Page.of(criteria.getPageNumber(), criteria.getPageSize())).getPageResult();
+ } catch (Exception exception) {
+ throw new DAOException(ErrorKeys.FIND_ALL_PARAMETERS_FAILED, exception);
+ }
+ }
+
+ public PageResult searchAllKeys(KeysSearchCriteria criteria) {
+ try {
+ var cb = getEntityManager().getCriteriaBuilder();
+ CriteriaQuery cq = cb.createQuery(String.class);
+ Root root = cq.from(ApplicationParameter.class);
+ cq.select(root.get(ApplicationParameter_.KEY)).distinct(true);
+
+ if (criteria.getApplicationId() != null && !criteria.getApplicationId().isEmpty()) {
+ cq.where(cb.equal(root.get(ApplicationParameter_.APPLICATION_ID), criteria.getApplicationId()));
+ }
+
+ var results = getEntityManager().createQuery(cq).getResultList();
+ return new PageResult<>(results.size(), results.stream(), Page.of(0, 1));
+ } catch (Exception exception) {
+ throw new DAOException(ErrorKeys.FIND_ALL_KEYS_FAILED, exception);
+ }
+ }
+
+ public PageResult searchAllApplications() {
+ try {
+ var cb = getEntityManager().getCriteriaBuilder();
+ CriteriaQuery cq = cb.createQuery(String.class);
+ Root root = cq.from(ApplicationParameter.class);
+ cq.select(root.get(ApplicationParameter_.APPLICATION_ID)).distinct(true);
+ var results = getEntityManager().createQuery(cq).getResultList();
+ return new PageResult<>(results.size(), results.stream(), Page.of(0, 1));
+ } catch (Exception exception) {
+ throw new DAOException(ErrorKeys.FIND_ALL_APPLICATIONS_FAILED, exception);
+ }
+ }
+
+ private static String stringPattern(String value) {
+ return (value.toLowerCase() + "%");
+ }
+
+ public enum ErrorKeys {
+
+ FIND_ALL_PARAMETERS_BY_APPLICATION_ID_FAILED,
+ FIND_PARAMETER_BY_APPLICATION_ID_AND_PARAMETER_KEY_FAILED,
+ FIND_PARAMETERS_BY_APPLICATION_AND_PARAMETER_KEYS_FAILED,
+ FIND_PARAMETERS_BY_APPLICATION_AND_PARAMETER_KEY_TYPE_FAILED,
+ FIND_ALL_APPLICATIONS_FAILED,
+
+ FIND_ALL_KEYS_FAILED,
+ FIND_ALL_PARAMETERS_FAILED;
+ }
+}
diff --git a/src/main/java/io/github/onecx/parameters/domain/daos/ApplicationParameterDataDAO.java b/src/main/java/io/github/onecx/parameters/domain/daos/ApplicationParameterDataDAO.java
new file mode 100644
index 0000000..f72d717
--- /dev/null
+++ b/src/main/java/io/github/onecx/parameters/domain/daos/ApplicationParameterDataDAO.java
@@ -0,0 +1,68 @@
+package io.github.onecx.parameters.domain.daos;
+
+import java.util.List;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.persistence.NoResultException;
+import jakarta.persistence.criteria.CriteriaBuilder;
+import jakarta.persistence.criteria.CriteriaDelete;
+import jakarta.persistence.criteria.CriteriaQuery;
+import jakarta.persistence.criteria.Root;
+import jakarta.transaction.Transactional;
+
+import org.tkit.quarkus.jpa.daos.AbstractDAO;
+import org.tkit.quarkus.jpa.exceptions.DAOException;
+
+import io.github.onecx.parameters.domain.models.ApplicationParameterData;
+import io.github.onecx.parameters.domain.models.ApplicationParameterData_;
+
+@ApplicationScoped
+@Transactional(value = Transactional.TxType.NOT_SUPPORTED, rollbackOn = DAOException.class)
+public class ApplicationParameterDataDAO extends AbstractDAO {
+
+ public ApplicationParameterData findByParameterId(String parameterId) throws DAOException {
+ CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
+ CriteriaQuery cq = cb.createQuery(ApplicationParameterData.class);
+ Root root = cq.from(ApplicationParameterData.class);
+
+ cq.select(root);
+ cq.where(cb.equal(root.get(ApplicationParameterData_.APPLICATION_PARAMETER_GUID), parameterId));
+
+ try {
+ return this.em.createQuery(cq).getSingleResult();
+ } catch (NoResultException e) {
+ return null;
+ }
+ }
+
+ public List findByParameterIds(List parameterIds) throws DAOException {
+ CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
+ CriteriaQuery cq = cb.createQuery(ApplicationParameterData.class);
+ Root root = cq.from(ApplicationParameterData.class);
+
+ cq.select(root);
+ cq.where(root.get(ApplicationParameterData_.APPLICATION_PARAMETER_GUID).in(parameterIds));
+
+ return this.em.createQuery(cq).getResultList();
+ }
+
+ @Transactional(value = Transactional.TxType.SUPPORTS, rollbackOn = DAOException.class)
+ public void deleteByParameterId(String parameterId) throws DAOException {
+ try {
+ CriteriaDelete cq = deleteQuery();
+ Root root = cq.from(ApplicationParameterData.class);
+ cq.where(
+ getEntityManager().getCriteriaBuilder()
+ .equal(root.get(ApplicationParameterData_.APPLICATION_PARAMETER_GUID), parameterId));
+ getEntityManager().createQuery(cq).executeUpdate();
+ getEntityManager().flush();
+ } catch (Exception e) {
+ throw handleConstraint(e, Errors.FAILED_TO_DELETE_BY_GUID_QUERY);
+ }
+ }
+
+ enum Errors {
+ FAILED_TO_DELETE_BY_GUID_QUERY;
+
+ }
+}
diff --git a/src/main/java/io/github/onecx/parameters/domain/daos/ApplicationParameterHistoryDAO.java b/src/main/java/io/github/onecx/parameters/domain/daos/ApplicationParameterHistoryDAO.java
new file mode 100644
index 0000000..b975887
--- /dev/null
+++ b/src/main/java/io/github/onecx/parameters/domain/daos/ApplicationParameterHistoryDAO.java
@@ -0,0 +1,138 @@
+package io.github.onecx.parameters.domain.daos;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.persistence.criteria.*;
+import jakarta.transaction.Transactional;
+
+import org.tkit.quarkus.jpa.daos.AbstractDAO;
+import org.tkit.quarkus.jpa.daos.Page;
+import org.tkit.quarkus.jpa.daos.PageResult;
+import org.tkit.quarkus.jpa.exceptions.DAOException;
+import org.tkit.quarkus.jpa.models.AbstractTraceableEntity_;
+import org.tkit.quarkus.jpa.models.TraceableEntity_;
+
+import io.github.onecx.parameters.domain.criteria.ApplicationParameterHistorySearchCriteria;
+import io.github.onecx.parameters.domain.models.ApplicationParameterHistory;
+import io.github.onecx.parameters.domain.models.ApplicationParameterHistory_;
+import io.github.onecx.parameters.domain.models.ApplicationParameter_;
+import io.github.onecx.parameters.domain.models.ParameterHistoryCountTuple;
+
+@ApplicationScoped
+@Transactional(value = Transactional.TxType.NOT_SUPPORTED, rollbackOn = DAOException.class)
+public class ApplicationParameterHistoryDAO extends AbstractDAO {
+
+ @Transactional(value = Transactional.TxType.REQUIRED, rollbackOn = DAOException.class)
+ public void deleteApplicationHistoryOlderThan(LocalDateTime date) {
+ try {
+ CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
+ CriteriaDelete cd = deleteQuery();
+ Root root = cd.from(ApplicationParameterHistory.class);
+ cd.where(cb.lessThanOrEqualTo(root.get(AbstractTraceableEntity_.CREATION_DATE), date));
+ getEntityManager().createQuery(cd).executeUpdate();
+ } catch (Exception e) {
+ throw new DAOException(ErrorKeys.DELETE_PARAMETER_HISTORY_OLDER_THAN_FAILED, e);
+ }
+ }
+
+ public PageResult searchByCriteria(ApplicationParameterHistorySearchCriteria criteria) {
+ try {
+ CriteriaQuery cq = criteriaQuery();
+ Root root = cq.from(ApplicationParameterHistory.class);
+ List predicates = new ArrayList<>();
+ CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
+ if (criteria.getApplicationId() != null && !criteria.getApplicationId().isEmpty()) {
+ predicates.add(cb.like(cb.lower(root.get(ApplicationParameter_.APPLICATION_ID)),
+ stringPattern(criteria.getApplicationId())));
+ }
+ if (criteria.getKey() != null && !criteria.getKey().isEmpty()) {
+ predicates.add(cb.like(cb.lower(root.get(ApplicationParameterHistory_.KEY)), stringPattern(criteria.getKey())));
+ }
+ if (!criteria.getType().isEmpty()) {
+ predicates.add(cb.lower(root.get(ApplicationParameterHistory_.TYPE)).in(toLowerCase(criteria.getType())));
+ }
+ if (!predicates.isEmpty()) {
+ cq.where(cb.and(predicates.toArray(new Predicate[0])));
+ }
+ cq.orderBy(cb.asc(root.get(AbstractTraceableEntity_.CREATION_DATE)));
+ return createPageQuery(cq, Page.of(criteria.getPageNumber(), criteria.getPageSize())).getPageResult();
+ } catch (Exception exception) {
+ throw new DAOException(ErrorKeys.FIND_ALL_PARAMETERS_HISTORY_FAILED, exception);
+ }
+ }
+
+ public PageResult searchOnlyLatestByCriteria(
+ ApplicationParameterHistorySearchCriteria criteria) {
+ try {
+ CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
+ CriteriaQuery cq = cb.createQuery(ApplicationParameterHistory.class);
+ Root root = cq.from(ApplicationParameterHistory.class);
+
+ Subquery maxDateSubquery = cq.subquery(Number.class);
+ Root maxDateSubqueryRoot = maxDateSubquery.from(ApplicationParameterHistory.class);
+ maxDateSubquery.select(cb.max(maxDateSubqueryRoot.get(AbstractTraceableEntity_.CREATION_DATE)))
+ .groupBy(maxDateSubqueryRoot.get(ApplicationParameterHistory_.INSTANCE_ID));
+
+ List predicates = new ArrayList<>();
+ predicates.add(root.get(AbstractTraceableEntity_.CREATION_DATE).in(maxDateSubquery));
+
+ if (criteria.getApplicationId() != null && !criteria.getApplicationId().isEmpty()) {
+ predicates.add(cb.equal(cb.lower(root.get(ApplicationParameter_.APPLICATION_ID)),
+ criteria.getApplicationId().toLowerCase()));
+ }
+ if (criteria.getKey() != null && !criteria.getKey().isEmpty()) {
+ predicates.add(cb.equal(cb.lower(root.get(ApplicationParameterHistory_.KEY)), criteria.getKey().toLowerCase()));
+ }
+
+ cq.select(root)
+ .where(cb.and(predicates.toArray(new Predicate[0])))
+ .groupBy(root.get(ApplicationParameterHistory_.INSTANCE_ID), root.get(TraceableEntity_.ID));
+
+ return createPageQuery(cq, Page.of(criteria.getPageNumber(), criteria.getPageSize())).getPageResult();
+ } catch (Exception exception) {
+ throw new DAOException(ErrorKeys.FIND_ALL_PARAMETERS_HISTORY_FAILED, exception);
+ }
+ }
+
+ public List searchCountsByCriteria(ApplicationParameterHistorySearchCriteria criteria) {
+ try {
+ var cb = getEntityManager().getCriteriaBuilder();
+ CriteriaQuery cq = cb.createQuery(ParameterHistoryCountTuple.class);
+ Root root = cq.from(ApplicationParameterHistory.class);
+ cq.select(
+ cb.construct(ParameterHistoryCountTuple.class, root.get(AbstractTraceableEntity_.CREATION_DATE),
+ root.get(ApplicationParameterHistory_.COUNT)));
+ List predicates = new ArrayList<>();
+
+ if (criteria.getApplicationId() != null && !criteria.getApplicationId().isEmpty()) {
+ predicates.add(cb.like(cb.lower(root.get(ApplicationParameter_.APPLICATION_ID)),
+ stringPattern(criteria.getApplicationId())));
+ }
+ if (criteria.getKey() != null && !criteria.getKey().isEmpty()) {
+ predicates.add(cb.like(cb.lower(root.get(ApplicationParameterHistory_.KEY)), stringPattern(criteria.getKey())));
+ }
+ if (!predicates.isEmpty()) {
+ cq.where(cb.and(predicates.toArray(new Predicate[0])));
+ }
+ return em.createQuery(cq).getResultList();
+ } catch (Exception exception) {
+ throw new DAOException(ErrorKeys.FIND_ALL_PARAMETERS_HISTORY_FAILED, exception);
+ }
+ }
+
+ private static String stringPattern(String value) {
+ return (value.toLowerCase() + "%");
+ }
+
+ private static List toLowerCase(List value) {
+ return value.stream().map(String::toLowerCase).toList();
+ }
+
+ public enum ErrorKeys {
+ DELETE_PARAMETER_HISTORY_OLDER_THAN_FAILED,
+ FIND_ALL_PARAMETERS_HISTORY_FAILED;
+ }
+}
diff --git a/src/main/java/io/github/onecx/parameters/domain/daos/JobDAO.java b/src/main/java/io/github/onecx/parameters/domain/daos/JobDAO.java
new file mode 100644
index 0000000..2d75e27
--- /dev/null
+++ b/src/main/java/io/github/onecx/parameters/domain/daos/JobDAO.java
@@ -0,0 +1,46 @@
+package io.github.onecx.parameters.domain.daos;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.persistence.LockModeType;
+import jakarta.persistence.NoResultException;
+import jakarta.persistence.criteria.CriteriaBuilder;
+import jakarta.persistence.criteria.CriteriaQuery;
+import jakarta.persistence.criteria.Root;
+import jakarta.transaction.Transactional;
+
+import org.tkit.quarkus.jpa.daos.AbstractDAO;
+import org.tkit.quarkus.jpa.exceptions.DAOException;
+import org.tkit.quarkus.jpa.models.TraceableEntity_;
+
+import io.github.onecx.parameters.domain.di.models.Job;
+
+@ApplicationScoped
+public class JobDAO extends AbstractDAO {
+
+ @Transactional(value = Transactional.TxType.REQUIRED, rollbackOn = DAOException.class)
+ public Job getJob(String id) throws DAOException {
+ try {
+ CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
+ CriteriaQuery cq = cb.createQuery(Job.class);
+ Root root = cq.from(Job.class);
+ cq.where(cb.equal(root.get(TraceableEntity_.ID), id));
+
+ return getEntityManager()
+ .createQuery(cq)
+ .setMaxResults(1)
+ .setLockMode(LockModeType.PESSIMISTIC_WRITE)
+ .setHint("javax.persistence.lock.timeout", -2)
+ .getSingleResult();
+
+ } catch (NoResultException ex) {
+ return null;
+ } catch (Exception ex) {
+ throw new DAOException(Error.GET_JOB_FAILED, ex);
+ }
+ }
+
+ public enum Error {
+
+ GET_JOB_FAILED;
+ }
+}
diff --git a/src/main/java/io/github/onecx/parameters/domain/di/ApplicationParameterDataImportService.java b/src/main/java/io/github/onecx/parameters/domain/di/ApplicationParameterDataImportService.java
new file mode 100644
index 0000000..7c1e0b2
--- /dev/null
+++ b/src/main/java/io/github/onecx/parameters/domain/di/ApplicationParameterDataImportService.java
@@ -0,0 +1,180 @@
+package io.github.onecx.parameters.domain.di;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+
+import jakarta.inject.Inject;
+import jakarta.transaction.Transactional;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tkit.quarkus.dataimport.DataImport;
+import org.tkit.quarkus.dataimport.DataImportConfig;
+import org.tkit.quarkus.dataimport.DataImportService;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import io.github.onecx.parameters.domain.daos.ApplicationParameterDAO;
+import io.github.onecx.parameters.domain.di.models.ApplicationParameterDataImport;
+import io.github.onecx.parameters.domain.models.ApplicationParameter;
+
+/**
+ * Import format
+ * {
+ * "appId" : {
+ * "key1": {
+ * "description": "description_1",
+ * "name": "name_1",
+ * "value": "value_1"
+ * },
+ * "key2": {
+ * "description": "description_2",
+ * "name": "name_2",
+ * "value": "value_2"
+ * }
+ * }
+ * }
+ * operation:
+ * - CLEAN_INSERT - delete all data and import new set
+ * - UPDATE - update existing data from file or create new parameters
+ */
+@DataImport("parameters")
+public class ApplicationParameterDataImportService implements DataImportService {
+
+ private static final Logger log = LoggerFactory.getLogger(ApplicationParameterDataImportService.class);
+
+ public static final String KEY_SEPARATOR = "__";
+
+ @Inject
+ ApplicationParameterDAO dao;
+
+ @Inject
+ ObjectMapper mapper;
+
+ @Override
+ @Transactional(Transactional.TxType.REQUIRES_NEW)
+ public void importData(DataImportConfig config) {
+ try {
+ String operation = config.getMetadata().getOrDefault("operation", "NONE");
+
+ Consumer