diff --git a/.github/workflows/crosschecks.yml b/.github/workflows/crosschecks.yml index 3e081a2c7e4..9ec1330744b 100644 --- a/.github/workflows/crosschecks.yml +++ b/.github/workflows/crosschecks.yml @@ -60,5 +60,10 @@ jobs: run: mvn -T 1C checkstyle:check tools:verify-legal-files modernizer:modernizer apache-rat:check - name: Test run: mvn -T 1C clean test '-Dinvoker.streamLogs=true' '-Dmodernizer.skip=true' '-Dianal.phase=none' '-Drat.skip=true' '-Dcheckstyle.skip=true' '-Dsass.skip=true' + - name: Start PostgreSQL on Windows + if: runner.os == 'Windows' + run: | + sc.exe config postgresql-x64-14 start=auto + sc.exe start postgresql-x64-14 - name: Verify run: mvn -f fit/core-reference/pom.xml verify '-Dit.test=RESTITCase' '-Dinvoker.streamLogs=true' '-Dmodernizer.skip=true' '-Drat.skip=true' '-Dcheckstyle.skip=true' '-Djacoco.skip=true' diff --git a/.github/workflows/fit_Elasticsearch.yml b/.github/workflows/fit_Elasticsearch.yml index 7a0699d174d..b2f24b4e4e5 100644 --- a/.github/workflows/fit_Elasticsearch.yml +++ b/.github/workflows/fit_Elasticsearch.yml @@ -49,5 +49,5 @@ jobs: ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - - name: 'Elasticsearch / H2 / JSON' + - name: 'Elasticsearch / PostgreSQL / JSON' run: mvn -f fit/core-reference/pom.xml -P elasticsearch-it -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true diff --git a/.github/workflows/fit_OpenSearch.yml b/.github/workflows/fit_OpenSearch.yml index 14941314a09..25d5851d46e 100644 --- a/.github/workflows/fit_OpenSearch.yml +++ b/.github/workflows/fit_OpenSearch.yml @@ -49,5 +49,5 @@ jobs: ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - - name: 'OpenSearch / H2 / JSON' + - name: 'OpenSearch / PostgreSQL / JSON' run: mvn -f fit/core-reference/pom.xml -P opensearch-it -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true diff --git a/.github/workflows/fit_Payara.yml b/.github/workflows/fit_Payara.yml index c49867ac648..7b2d697106b 100644 --- a/.github/workflows/fit_Payara.yml +++ b/.github/workflows/fit_Payara.yml @@ -49,5 +49,5 @@ jobs: ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - - name: 'Payara / H2 / JSON' + - name: 'Payara / PostgreSQL / JSON' run: mvn -f fit/core-reference/pom.xml -P payara-it -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true diff --git a/.github/workflows/fit_Tomcat_H2_JSON.yml b/.github/workflows/fit_Tomcat_PostgreSQL_JSON.yml similarity index 94% rename from .github/workflows/fit_Tomcat_H2_JSON.yml rename to .github/workflows/fit_Tomcat_PostgreSQL_JSON.yml index b81fb951674..2d9a5b8bcbd 100644 --- a/.github/workflows/fit_Tomcat_H2_JSON.yml +++ b/.github/workflows/fit_Tomcat_PostgreSQL_JSON.yml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License -name: "FIT Tomcat H2 JSON" +name: "FIT Tomcat PostgreSQL JSON" on: push: @@ -26,7 +26,7 @@ on: - cron: '0 13 * * 4' jobs: - fit_Tomcat_H2_JSON: + fit_Tomcat_PostgreSQL_JSON: runs-on: ubuntu-latest steps: @@ -49,5 +49,5 @@ jobs: ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - - name: 'Tomcat / H2 / JSON' + - name: 'Tomcat / PostgreSQL / JSON' run: mvn -f fit/core-reference/pom.xml verify -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true diff --git a/.github/workflows/fit_Tomcat_H2_XML.yml b/.github/workflows/fit_Tomcat_PostgreSQL_XML.yml similarity index 94% rename from .github/workflows/fit_Tomcat_H2_XML.yml rename to .github/workflows/fit_Tomcat_PostgreSQL_XML.yml index 96e3b3410da..b3153d898c4 100644 --- a/.github/workflows/fit_Tomcat_H2_XML.yml +++ b/.github/workflows/fit_Tomcat_PostgreSQL_XML.yml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License -name: "FIT Tomcat H2 XML" +name: "FIT Tomcat PostgreSQL XML" on: push: @@ -26,7 +26,7 @@ on: - cron: '0 13 * * 4' jobs: - fit_Tomcat_H2_XML: + fit_Tomcat_PostgreSQL_XML: runs-on: ubuntu-latest steps: @@ -49,5 +49,5 @@ jobs: ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - - name: 'Tomcat / H2 / XML' + - name: 'Tomcat / PostgreSQL / XML' run: mvn -f fit/core-reference/pom.xml verify -Djaxrs.content.type=application/xml -Dit.test=org.apache.syncope.fit.core.*ITCase -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true diff --git a/.github/workflows/fit_Tomcat_H2_YAML.yml b/.github/workflows/fit_Tomcat_PostgreSQL_YAML.yml similarity index 94% rename from .github/workflows/fit_Tomcat_H2_YAML.yml rename to .github/workflows/fit_Tomcat_PostgreSQL_YAML.yml index de737fd45a1..ba19bdd2d0c 100644 --- a/.github/workflows/fit_Tomcat_H2_YAML.yml +++ b/.github/workflows/fit_Tomcat_PostgreSQL_YAML.yml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License -name: "FIT Tomcat H2 YAML" +name: "FIT Tomcat PostgreSQL YAML" on: push: @@ -26,7 +26,7 @@ on: - cron: '0 13 * * 4' jobs: - fit_Tomcat_H2_YAML: + fit_Tomcat_PostgreSQL_YAML: runs-on: ubuntu-latest steps: @@ -49,5 +49,5 @@ jobs: ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - - name: 'Tomcat / H2 / YAML' + - name: 'Tomcat / PostgreSQL / YAML' run: mvn -f fit/core-reference/pom.xml verify -Djaxrs.content.type=application/yaml -Dit.test=org.apache.syncope.fit.core.*ITCase -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true diff --git a/.github/workflows/fit_WA_SAML2PS4UI_OIDCC4UI.yml b/.github/workflows/fit_WA_OIDCC4UI.yml similarity index 90% rename from .github/workflows/fit_WA_SAML2PS4UI_OIDCC4UI.yml rename to .github/workflows/fit_WA_OIDCC4UI.yml index 1a21d54e229..9b079f6490b 100644 --- a/.github/workflows/fit_WA_SAML2PS4UI_OIDCC4UI.yml +++ b/.github/workflows/fit_WA_OIDCC4UI.yml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License -name: "FIT WA SAML2SP4UI OIDCC4UI" +name: "FIT WA OIDCC4UI" on: push: @@ -26,7 +26,7 @@ on: - cron: '0 13 * * 4' jobs: - fit_WA_SAML2SP4UI_OIDCC4UI: + fit_WA_OIDCC4UI: runs-on: ubuntu-latest steps: @@ -49,5 +49,5 @@ jobs: ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - - name: 'WA / SAML2SP4UI, OIDCC4UI' - run: mkdir -p fit/core-reference/target/test-classes && cp fit/core-reference/src/test/resources/saml.keystore.jks fit/core-reference/target/test-classes && mvn -f fit/wa-reference/pom.xml verify -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true -Dit.test=org.apache.syncope.fit.ui.*ITCase + - name: 'WA / OIDCC4UI' + run: mkdir -p fit/core-reference/target/test-classes && cp fit/core-reference/src/test/resources/saml.keystore.jks fit/core-reference/target/test-classes && mvn -f fit/wa-reference/pom.xml verify -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true -Dit.test=OIDCC4UIITCase diff --git a/.github/workflows/fit_WA_SAML2SP4UI.yml b/.github/workflows/fit_WA_SAML2SP4UI.yml new file mode 100644 index 00000000000..93881c49d34 --- /dev/null +++ b/.github/workflows/fit_WA_SAML2SP4UI.yml @@ -0,0 +1,53 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License +name: "FIT WA SAML2SP4UI" + +on: + push: + branches: ['master', 'pr-*'] + pull_request: + # The branches below must be a subset of the branches above + branches: [master] + schedule: + - cron: '0 13 * * 4' + +jobs: + fit_WA_SAML2SP4UI: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup Java JDK + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: 21 + - name: Setup Maven + uses: stCarolas/setup-maven@v5 + with: + maven-version: 3.9.6 + - uses: actions/cache@v4 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Build + run: mvn -U -T 1C -P 'skipTests,all' + - name: 'WA / SAML2SP4UI' + run: mkdir -p fit/core-reference/target/test-classes && cp fit/core-reference/src/test/resources/saml.keystore.jks fit/core-reference/target/test-classes && mvn -f fit/wa-reference/pom.xml verify -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true -Dit.test=SAML2SP4UIITCase diff --git a/.github/workflows/fit_Wildfly.yml b/.github/workflows/fit_Wildfly.yml index de15fb824e6..5e165174730 100644 --- a/.github/workflows/fit_Wildfly.yml +++ b/.github/workflows/fit_Wildfly.yml @@ -49,5 +49,5 @@ jobs: ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - - name: 'Wildfly / H2 / JSON' + - name: 'Wildfly / PostgreSQL / JSON' run: mvn -f fit/core-reference/pom.xml -P wildfly-it -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true diff --git a/.github/workflows/fit_Zookeeper.yml b/.github/workflows/fit_Zookeeper.yml index a496ce0f51c..c2ff40d05e9 100644 --- a/.github/workflows/fit_Zookeeper.yml +++ b/.github/workflows/fit_Zookeeper.yml @@ -49,5 +49,5 @@ jobs: ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' - - name: 'Zookeeper / H2 / JSON' + - name: 'Zookeeper / PostgreSQL / JSON' run: mvn -f fit/core-reference/pom.xml -P zookeeper-it -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true diff --git a/.github/workflows/mariadb.yml b/.github/workflows/mariadb.yml index 94b37117094..8c2e2b7b1ea 100644 --- a/.github/workflows/mariadb.yml +++ b/.github/workflows/mariadb.yml @@ -49,33 +49,7 @@ jobs: ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' + - name: 'Unit Tests: MariaDB' + run: mvn -f core/persistence-jpa/pom.xml -P mariadb -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Dianal.phase=none -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true - name: 'Integration Tests: MariaDB' run: mvn -f fit/core-reference/pom.xml -P mariadb-it -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true - - majson: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Setup Java JDK - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: 21 - - name: Setup Maven - uses: stCarolas/setup-maven@v5 - with: - maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - name: Build - run: mvn -U -T 1C -P 'skipTests,all' - - name: 'Unit Tests: MariaDB JPA JSON' - run: mvn -f core/persistence-jpa-json/pom.xml -P majson -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Dianal.phase=none -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true - - name: 'Integration Tests: MariaDB JPA JSON' - run: mvn -f fit/core-reference/pom.xml -P majson-it -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true diff --git a/.github/workflows/mysql.yml b/.github/workflows/mysql.yml index 0c236f90a59..30997151f9b 100644 --- a/.github/workflows/mysql.yml +++ b/.github/workflows/mysql.yml @@ -49,33 +49,7 @@ jobs: ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' + - name: 'Unit Tests: MySQL' + run: mvn -f core/persistence-jpa/pom.xml -P mysql -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Dianal.phase=none -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true - name: 'Integration Tests: MySQL' run: mvn -f fit/core-reference/pom.xml -P mysql-it -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true - - myjson: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Setup Java JDK - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: 21 - - name: Setup Maven - uses: stCarolas/setup-maven@v5 - with: - maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - name: Build - run: mvn -U -T 1C -P 'skipTests,all' - - name: 'Unit Tests: MySQL JPA JSON' - run: mvn -f core/persistence-jpa-json/pom.xml -P myjson -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Dianal.phase=none -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true - - name: 'Integration Tests: MySQL JPA JSON' - run: mvn -f fit/core-reference/pom.xml -P myjson-it -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true diff --git a/.github/workflows/oracle.yml b/.github/workflows/oracle.yml index 7bef3c1869c..128a47b4d51 100644 --- a/.github/workflows/oracle.yml +++ b/.github/workflows/oracle.yml @@ -49,33 +49,7 @@ jobs: ${{ runner.os }}-maven- - name: Build run: mvn -U -T 1C -P 'skipTests,all' + - name: 'Unit Tests: Oracle' + run: mvn -f core/persistence-jpa/pom.xml -P oracle -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Dianal.phase=none -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true - name: 'Integration Tests: Oracle' run: mvn -f fit/core-reference/pom.xml -P oracle-it -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true - - ojson: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Setup Java JDK - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: 21 - - name: Setup Maven - uses: stCarolas/setup-maven@v5 - with: - maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - name: Build - run: mvn -U -T 1C -P 'skipTests,all' - - name: 'Unit Tests: Oracle JPA JSON' - run: mvn -f core/persistence-jpa-json/pom.xml -P ojson -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Dianal.phase=none -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true - - name: 'Integration Tests: Oracle JPA JSON' - run: mvn -f fit/core-reference/pom.xml -P ojson-it -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true diff --git a/.github/workflows/postgresql.yml b/.github/workflows/postgresql.yml deleted file mode 100644 index a2297f93f62..00000000000 --- a/.github/workflows/postgresql.yml +++ /dev/null @@ -1,81 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License -name: "PostgreSQL" - -on: - push: - branches: ['master', 'pr-*'] - pull_request: - # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 13 * * 4' - -jobs: - postgres: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Setup Java JDK - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: 21 - - name: Setup Maven - uses: stCarolas/setup-maven@v5 - with: - maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - name: Build - run: mvn -U -T 1C -P 'skipTests,all' - - name: 'Integration Tests: PostgreSQL' - run: mvn -f fit/core-reference/pom.xml -P postgres-it -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true - - pgjsonb: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Setup Java JDK - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: 21 - - name: Setup Maven - uses: stCarolas/setup-maven@v5 - with: - maven-version: 3.9.6 - - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - name: Build - run: mvn -U -T 1C -P 'skipTests,all' - - name: 'Unit Tests: PostgreSQL JPA JSON' - run: mvn -f core/persistence-jpa-json/pom.xml -P pgjsonb -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Dianal.phase=none -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true - - name: 'Integration Tests: PostgreSQL JPA JSON' - run: mvn -f fit/core-reference/pom.xml -P pgjsonb-it -Dinvoker.streamLogs=true -Dmodernizer.skip=true -Drat.skip=true -Dcheckstyle.skip=true -Djacoco.skip=true diff --git a/archetype/src/main/resources/archetype-resources/fit/pom.xml b/archetype/src/main/resources/archetype-resources/fit/pom.xml index fb2721c2fd2..42191e79e62 100644 --- a/archetype/src/main/resources/archetype-resources/fit/pom.xml +++ b/archetype/src/main/resources/archetype-resources/fit/pom.xml @@ -39,8 +39,15 @@ under the License. - com.h2database - h2 + org.postgresql + postgresql + test + + + org.apache.syncope.fit + persistence-embedded + ${syncope.version} + bundle test @@ -144,6 +151,9 @@ under the License. + - com.h2database - h2 + org.postgresql + postgresql @@ -235,8 +245,6 @@ under the License. file:/dev/./urandom true - true - ${basedir}/src/test/resources/keystore.jks password @@ -330,7 +338,7 @@ under the License. - clean verify cargo:run + clean verify cargo:run diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainWizardBuilder.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainWizardBuilder.java index a350ce6b92d..80953993516 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainWizardBuilder.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/DomainWizardBuilder.java @@ -54,7 +54,6 @@ public class DomainWizardBuilder extends BaseAjaxWizardBuilder { "org.postgresql.Driver", "com.mysql.cj.jdbc.Driver", "org.mariadb.jdbc.Driver", - "com.microsoft.sqlserver.jdbc.SQLServerDriver", "oracle.jdbc.OracleDriver", "org.h2.Driver"); @@ -64,7 +63,6 @@ public class DomainWizardBuilder extends BaseAjaxWizardBuilder { + "(blobTypeName=LONGBLOB,dateFractionDigits=3,useSetStringForClobs=true)", "org.apache.openjpa.jdbc.sql.MariaDBDictionary" + "(blobTypeName=LONGBLOB,dateFractionDigits=3)", - "org.apache.openjpa.jdbc.sql.SQLServerDictionary", "org.apache.openjpa.jdbc.sql.OracleDictionary", "org.apache.openjpa.jdbc.sql.H2Dictionary"); diff --git a/core/idm/logic/pom.xml b/core/idm/logic/pom.xml index 8bfcad6d96b..b78651d03d1 100644 --- a/core/idm/logic/pom.xml +++ b/core/idm/logic/pom.xml @@ -78,13 +78,18 @@ under the License. test - org.slf4j - slf4j-simple + org.postgresql + postgresql test - com.h2database - h2 + io.zonky.test + embedded-postgres + test + + + org.slf4j + slf4j-simple test @@ -126,6 +131,9 @@ under the License. ${basedir}/../../persistence-jpa/src/test/resources true + + core-test.properties + ${basedir}/../../provisioning-java/src/test/resources @@ -140,6 +148,7 @@ under the License. file:${bundles.directory}/ + true diff --git a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java index 722fbe84c8a..e62a95e55bd 100644 --- a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java +++ b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java @@ -18,18 +18,51 @@ */ package org.apache.syncope.core.logic; +import static org.junit.jupiter.api.Assertions.fail; + +import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; import jakarta.persistence.EntityManager; +import java.util.function.Supplier; import org.apache.syncope.common.lib.types.EntitlementsHolder; import org.apache.syncope.common.lib.types.IdMEntitlement; import org.apache.syncope.common.lib.types.IdRepoEntitlement; import org.apache.syncope.core.persistence.jpa.MasterDomain; import org.junit.jupiter.api.BeforeAll; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; @SpringJUnitConfig(classes = { MasterDomain.class, IdMLogicTestContext.class }) public abstract class AbstractTest { + private static Supplier JDBC_URL_SUPPLIER; + + private static final Supplier DB_CRED_SUPPLIER = () -> "syncope"; + + static { + try { + EmbeddedPostgres pg = EmbeddedPostgres.builder().start(); + JdbcTemplate jdbcTemplate = new JdbcTemplate(pg.getPostgresDatabase()); + jdbcTemplate.execute("CREATE DATABASE syncope"); + + jdbcTemplate.execute("CREATE USER syncope WITH PASSWORD 'syncope'"); + jdbcTemplate.execute("ALTER DATABASE syncope OWNER TO syncope"); + + JDBC_URL_SUPPLIER = () -> pg.getJdbcUrl("syncope", "syncope") + "&stringtype=unspecified"; + } catch (Exception e) { + fail("Could not setup PostgreSQL database", e); + } + } + + @DynamicPropertySource + static void configureProperties(final DynamicPropertyRegistry registry) { + registry.add("DB_URL", JDBC_URL_SUPPLIER); + registry.add("DB_USER", DB_CRED_SUPPLIER); + registry.add("DB_PASSWORD", DB_CRED_SUPPLIER); + } + @BeforeAll public static void init() { EntitlementsHolder.getInstance().addAll(IdRepoEntitlement.values()); diff --git a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/IdMLogicTestContext.java b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/IdMLogicTestContext.java index aaaa1b55297..cffd6e7613e 100644 --- a/core/idm/logic/src/test/java/org/apache/syncope/core/logic/IdMLogicTestContext.java +++ b/core/idm/logic/src/test/java/org/apache/syncope/core/logic/IdMLogicTestContext.java @@ -28,7 +28,10 @@ import org.apache.syncope.common.keymaster.client.api.model.JPADomain; import org.apache.syncope.core.persistence.api.DomainRegistry; import org.apache.syncope.core.persistence.api.content.ContentLoader; -import org.apache.syncope.core.persistence.jpa.MasterDomain; +import org.apache.syncope.core.persistence.jpa.MariaDBPersistenceContext; +import org.apache.syncope.core.persistence.jpa.MySQLPersistenceContext; +import org.apache.syncope.core.persistence.jpa.OraclePersistenceContext; +import org.apache.syncope.core.persistence.jpa.PGPersistenceContext; import org.apache.syncope.core.persistence.jpa.PersistenceContext; import org.apache.syncope.core.persistence.jpa.StartupDomainLoader; import org.apache.syncope.core.provisioning.api.ImplementationLookup; @@ -44,8 +47,18 @@ import org.springframework.mail.javamail.JavaMailSender; @PropertySource("classpath:core-test.properties") -@Import({ IdRepoLogicContext.class, IdMLogicContext.class, SecurityContext.class, - PersistenceContext.class, MasterDomain.class, ProvisioningContext.class, WorkflowContext.class }) +@Import({ + SecurityContext.class, + WorkflowContext.class, + PersistenceContext.class, + PGPersistenceContext.class, + MySQLPersistenceContext.class, + MariaDBPersistenceContext.class, + OraclePersistenceContext.class, + ProvisioningContext.class, + IdRepoLogicContext.class, + IdMLogicContext.class +}) @Configuration(proxyBeanMethods = false) public class IdMLogicTestContext { diff --git a/core/idrepo/logic/pom.xml b/core/idrepo/logic/pom.xml index ec57721015a..630e6aec8a4 100644 --- a/core/idrepo/logic/pom.xml +++ b/core/idrepo/logic/pom.xml @@ -87,13 +87,18 @@ under the License. test - org.slf4j - slf4j-simple + org.postgresql + postgresql + test + + + io.zonky.test + embedded-postgres test - com.h2database - h2 + org.slf4j + slf4j-simple test @@ -135,6 +140,9 @@ under the License. ${basedir}/../../persistence-jpa/src/test/resources true + + core-test.properties + ${basedir}/../../provisioning-java/src/test/resources @@ -143,6 +151,18 @@ under the License. + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.build.directory}/test-classes + file:${bundles.directory}/ + true + + + + org.apache.maven.plugins maven-checkstyle-plugin diff --git a/core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java b/core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java index f4c26ee21cb..4f151a41bc7 100644 --- a/core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java +++ b/core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java @@ -18,17 +18,50 @@ */ package org.apache.syncope.core.logic; +import static org.junit.jupiter.api.Assertions.fail; + +import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; import jakarta.persistence.EntityManager; +import java.util.function.Supplier; import org.apache.syncope.common.lib.types.EntitlementsHolder; import org.apache.syncope.common.lib.types.IdRepoEntitlement; import org.apache.syncope.core.persistence.jpa.MasterDomain; import org.junit.jupiter.api.BeforeAll; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; @SpringJUnitConfig(classes = { MasterDomain.class, IdRepoLogicTestContext.class }) public abstract class AbstractTest { + private static Supplier JDBC_URL_SUPPLIER; + + private static final Supplier DB_CRED_SUPPLIER = () -> "syncope"; + + static { + try { + EmbeddedPostgres pg = EmbeddedPostgres.builder().start(); + JdbcTemplate jdbcTemplate = new JdbcTemplate(pg.getPostgresDatabase()); + jdbcTemplate.execute("CREATE DATABASE syncope"); + + jdbcTemplate.execute("CREATE USER syncope WITH PASSWORD 'syncope'"); + jdbcTemplate.execute("ALTER DATABASE syncope OWNER TO syncope"); + + JDBC_URL_SUPPLIER = () -> pg.getJdbcUrl("syncope", "syncope") + "&stringtype=unspecified"; + } catch (Exception e) { + fail("Could not setup PostgreSQL database", e); + } + } + + @DynamicPropertySource + static void configureProperties(final DynamicPropertyRegistry registry) { + registry.add("DB_URL", JDBC_URL_SUPPLIER); + registry.add("DB_USER", DB_CRED_SUPPLIER); + registry.add("DB_PASSWORD", DB_CRED_SUPPLIER); + } + @BeforeAll public static void init() { EntitlementsHolder.getInstance().addAll(IdRepoEntitlement.values()); diff --git a/core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/IdRepoLogicTestContext.java b/core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/IdRepoLogicTestContext.java index c2b01ef6715..8217a10ceb4 100644 --- a/core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/IdRepoLogicTestContext.java +++ b/core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/IdRepoLogicTestContext.java @@ -28,7 +28,10 @@ import org.apache.syncope.common.keymaster.client.api.model.JPADomain; import org.apache.syncope.core.persistence.api.DomainRegistry; import org.apache.syncope.core.persistence.api.content.ContentLoader; -import org.apache.syncope.core.persistence.jpa.MasterDomain; +import org.apache.syncope.core.persistence.jpa.MariaDBPersistenceContext; +import org.apache.syncope.core.persistence.jpa.MySQLPersistenceContext; +import org.apache.syncope.core.persistence.jpa.OraclePersistenceContext; +import org.apache.syncope.core.persistence.jpa.PGPersistenceContext; import org.apache.syncope.core.persistence.jpa.PersistenceContext; import org.apache.syncope.core.persistence.jpa.StartupDomainLoader; import org.apache.syncope.core.provisioning.api.ImplementationLookup; @@ -44,8 +47,17 @@ import org.springframework.mail.javamail.JavaMailSender; @PropertySource("classpath:core-test.properties") -@Import({ IdRepoLogicContext.class, IdRepoLogicContext.class, SecurityContext.class, - PersistenceContext.class, MasterDomain.class, ProvisioningContext.class, WorkflowContext.class }) +@Import({ + SecurityContext.class, + WorkflowContext.class, + PersistenceContext.class, + PGPersistenceContext.class, + MySQLPersistenceContext.class, + MariaDBPersistenceContext.class, + OraclePersistenceContext.class, + ProvisioningContext.class, + IdRepoLogicContext.class +}) @Configuration(proxyBeanMethods = false) public class IdRepoLogicTestContext { diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/GroupablePlainAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/GroupablePlainAttr.java index 7e345a5caab..4ce61fc718e 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/GroupablePlainAttr.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/GroupablePlainAttr.java @@ -20,6 +20,8 @@ public interface GroupablePlainAttr, M extends Membership> extends PlainAttr { + String getMembershipKey(); + M getMembership(); void setMembership(M membership); diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java index b857ab9950a..71394996dbc 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java @@ -27,10 +27,14 @@ public interface PlainAttr> extends Entity { void setOwner(A owner); + String getSchemaKey(); + PlainSchema getSchema(); void setSchema(PlainSchema schema); + void add(PlainAttrValue attrValue); + void add(PlainAttrValidationManager validator, String value, AnyUtils anyUtils); void add(PlainAttrValidationManager validator, String value, PlainAttrValue attrValue); diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/AbstractPersistenceProperties.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/AbstractPersistenceProperties.java index ae4e26e866a..9b1b3488148 100644 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/AbstractPersistenceProperties.java +++ b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/AbstractPersistenceProperties.java @@ -24,7 +24,7 @@ public abstract class AbstractPersistenceProperties { - private String indexesXML = "classpath:indexes.xml"; + private String indexesXML = "classpath:META-INF/indexes.xml"; @NestedConfigurationProperty private final List domain = new ArrayList<>(); diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/RuntimeDomainLoader.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/RuntimeDomainLoader.java index 278602178f7..d1a9a0afe79 100644 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/RuntimeDomainLoader.java +++ b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/RuntimeDomainLoader.java @@ -58,10 +58,6 @@ public RuntimeDomainLoader( } } - protected void onAdd(final Domain domain) { - // nothing to do - } - @Async @SuppressWarnings("unchecked") @Override @@ -73,8 +69,6 @@ public void added(final Domain domain) { domainRegistry.register((D) domain); - onAdd(domain); - ApplicationContextProvider.getBeanFactory().getBeansOfType(SyncopeCoreLoader.class).values(). stream().sorted(Comparator.comparing(SyncopeCoreLoader::getOrder)). forEachOrdered(loader -> { diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AbstractValidator.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AbstractValidator.java index d996c57fb3b..ee45e953a94 100644 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AbstractValidator.java +++ b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AbstractValidator.java @@ -28,16 +28,16 @@ public abstract class AbstractValidator implements Cons protected static final Logger LOG = LoggerFactory.getLogger(AbstractValidator.class); - @Override - public void initialize(final A annotation) { - // no initialization - } - protected static String getTemplate(final EntityViolationType type, final String message) { return type.name() + ';' + message; } - protected boolean isHtml(final String text) { + protected static boolean isHtml(final String text) { return text != null && (text.indexOf('<') != -1 || text.indexOf('>') != -1); } + + @Override + public void initialize(final A annotation) { + // no initialization + } } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AttributableCheck.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AttributableCheck.java similarity index 94% rename from core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AttributableCheck.java rename to core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AttributableCheck.java index 59217b30cbf..652d6fdba39 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AttributableCheck.java +++ b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AttributableCheck.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.syncope.core.persistence.neo4j.entity; +package org.apache.syncope.core.persistence.common.validation; import jakarta.validation.Constraint; import jakarta.validation.Payload; @@ -32,7 +32,7 @@ @Documented public @interface AttributableCheck { - String message() default "{org.apache.syncope.core.persistence.validation.any}"; + String message() default "{org.apache.syncope.core.persistence.common.validation}"; Class[] groups() default {}; diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/PlainAttrValueValidator.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AttributableValidator.java similarity index 54% rename from core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/PlainAttrValueValidator.java rename to core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AttributableValidator.java index 054d540eb20..3d59c15744f 100644 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/PlainAttrValueValidator.java +++ b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/AttributableValidator.java @@ -19,15 +19,48 @@ package org.apache.syncope.core.persistence.common.validation; import jakarta.validation.ConstraintValidatorContext; +import java.util.concurrent.atomic.AtomicReference; import org.apache.syncope.common.lib.types.EntityViolationType; +import org.apache.syncope.core.persistence.api.entity.Attributable; +import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -public class PlainAttrValueValidator extends AbstractValidator { +public class AttributableValidator extends AbstractValidator> { - @Override - public boolean isValid(final PlainAttrValue value, final ConstraintValidatorContext context) { + protected boolean isValid(final PlainAttr attr, final ConstraintValidatorContext context) { + context.disableDefaultConstraintViolation(); + + boolean isValid; + if (attr == null) { + isValid = true; + } else { + if (attr.getSchema().isUniqueConstraint()) { + isValid = attr.getValues().isEmpty() && attr.getUniqueValue() != null; + } else { + isValid = !attr.getValues().isEmpty() && attr.getUniqueValue() == null; + + if (!attr.getSchema().isMultivalue()) { + isValid &= attr.getValues().size() == 1; + } + } + + if (!isValid) { + LOG.error("Invalid values for attribute schema={}, values={}", + attr.getSchema().getKey(), attr.getValuesAsStrings()); + + context.buildConstraintViolationWithTemplate( + getTemplate(EntityViolationType.InvalidValueList, + "Invalid values " + attr.getValuesAsStrings())). + addPropertyNode(attr.getSchema().getKey()).addConstraintViolation(); + } + } + + return isValid; + } + + protected boolean isValid(final PlainAttrValue value, final ConstraintValidatorContext context) { context.disableDefaultConstraintViolation(); boolean isValid; @@ -59,7 +92,8 @@ public boolean isValid(final PlainAttrValue value, final ConstraintValidatorCont LOG.error("More than one non-null value for " + value); context.buildConstraintViolationWithTemplate( - getTemplate(EntityViolationType.MoreThanOneNonNull, "More than one non-null value found")). + AbstractValidator.getTemplate(EntityViolationType.MoreThanOneNonNull, + "More than one non-null value found")). addPropertyNode(value.getClass().getSimpleName().replaceAll("\\n", " ")). addConstraintViolation(); @@ -73,9 +107,11 @@ public boolean isValid(final PlainAttrValue value, final ConstraintValidatorCont LOG.error("Unique value schema for " + value + " is " + uniqueValueSchema + ", while owning attribute's schema is " + attrSchema); - context.buildConstraintViolationWithTemplate(getTemplate(EntityViolationType.InvalidPlainAttr, - "Unique value schema is " + uniqueValueSchema - + ", while owning attribute's schema is " + attrSchema)).addPropertyNode("schema"). + context.buildConstraintViolationWithTemplate( + AbstractValidator.getTemplate(EntityViolationType.InvalidPlainAttr, + "Unique value schema is " + uniqueValueSchema + + ", while owning attribute's schema is " + attrSchema)). + addPropertyNode("schema"). addConstraintViolation(); } } @@ -83,4 +119,17 @@ public boolean isValid(final PlainAttrValue value, final ConstraintValidatorCont return isValid; } + + @Override + public boolean isValid(final Attributable entity, final ConstraintValidatorContext context) { + context.disableDefaultConstraintViolation(); + + AtomicReference isValid = new AtomicReference<>(Boolean.TRUE); + entity.getPlainAttrs().forEach(attr -> { + isValid.getAndSet(isValid.get() && isValid(attr, context)); + attr.getValues().forEach(value -> isValid.getAndSet(isValid.get() && isValid(value, context))); + }); + + return isValid.get(); + } } diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/PlainAttrCheck.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/PlainAttrCheck.java deleted file mode 100644 index 3776dafc4c1..00000000000 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/PlainAttrCheck.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.common.validation; - -import jakarta.validation.Constraint; -import jakarta.validation.Payload; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target({ ElementType.TYPE }) -@Retention(RetentionPolicy.RUNTIME) -@Constraint(validatedBy = PlainAttrValidator.class) -@Documented -public @interface PlainAttrCheck { - - String message() default "{org.apache.syncope.core.persistence.validation.attr}"; - - Class[] groups() default {}; - - Class[] payload() default {}; -} diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/PlainAttrValidator.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/PlainAttrValidator.java deleted file mode 100644 index 2bc87286809..00000000000 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/PlainAttrValidator.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.common.validation; - -import jakarta.validation.ConstraintValidatorContext; -import org.apache.syncope.common.lib.types.EntityViolationType; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; - -public class PlainAttrValidator extends AbstractValidator> { - - @Override - public boolean isValid(final PlainAttr attr, final ConstraintValidatorContext context) { - context.disableDefaultConstraintViolation(); - - boolean isValid; - if (attr == null) { - isValid = true; - } else { - if (attr.getSchema().isUniqueConstraint()) { - isValid = attr.getValues().isEmpty() && attr.getUniqueValue() != null; - } else { - isValid = !attr.getValues().isEmpty() && attr.getUniqueValue() == null; - - if (!attr.getSchema().isMultivalue()) { - isValid &= attr.getValues().size() == 1; - } - } - - if (!isValid) { - LOG.error("Invalid values for attribute schema={}, values={}", - attr.getSchema().getKey(), attr.getValuesAsStrings()); - - context.buildConstraintViolationWithTemplate( - getTemplate(EntityViolationType.InvalidValueList, - "Invalid values " + attr.getValuesAsStrings())). - addPropertyNode(attr.getSchema().getKey()).addConstraintViolation(); - } - } - - return isValid; - } -} diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/PlainAttrValueCheck.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/PlainAttrValueCheck.java deleted file mode 100644 index d54561ab345..00000000000 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/validation/PlainAttrValueCheck.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.common.validation; - -import jakarta.validation.Constraint; -import jakarta.validation.Payload; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target({ ElementType.TYPE }) -@Retention(RetentionPolicy.RUNTIME) -@Constraint(validatedBy = PlainAttrValueValidator.class) -@Documented -public @interface PlainAttrValueCheck { - - String message() default "{org.apache.syncope.core.persistence.validation.attrvalue}"; - - Class[] groups() default {}; - - Class[] payload() default {}; -} diff --git a/core/persistence-jpa-json/pom.xml b/core/persistence-jpa-json/pom.xml deleted file mode 100644 index a2b153959f4..00000000000 --- a/core/persistence-jpa-json/pom.xml +++ /dev/null @@ -1,649 +0,0 @@ - - - - - 4.0.0 - - - org.apache.syncope - syncope-core - 4.0.0-SNAPSHOT - - - Apache Syncope Core Persistence JPA JSON - Apache Syncope Core Persistence JPA JSON - org.apache.syncope.core - syncope-core-persistence-jpa-json - jar - - - pgjsonb - ${basedir}/../.. - - - - - org.apache.syncope.core - syncope-core-persistence-jpa - ${project.version} - - - - - org.springframework.boot - spring-boot-starter-validation - test - - - jakarta.servlet - jakarta.servlet-api - test - - - org.slf4j - slf4j-simple - test - - - org.slf4j - jcl-over-slf4j - test - - - com.h2database - h2 - test - - - org.springframework.boot - spring-boot-starter-test - test - - - org.bouncycastle - bcpkix-jdk18on - test - - - org.bouncycastle - bcprov-jdk18on - test - - - - - - - org.apache.openjpa - openjpa-maven-plugin - true - - - com.h2database - h2 - ${h2.version} - - - - ${project.build.directory}/classes/persistence-enhance.xml - org/apache/syncope/core/persistence/jpa/entity/**/*.class - org.springframework.jdbc.datasource.DriverManagerDataSource - - driverClassName=org.h2.Driver, - url=jdbc:h2:mem:syncopedb - username=sa, - password= - - - - - enhancer - process-classes - - enhance - - - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - - - - - - src/main/resources - true - - - - - src/test/resources - true - - - src/main/resources - true - - domains/MasterContent.xml - - - - ${basedir}/../persistence-jpa/src/test/resources - true - - *-metadata.xml - - - - - - - - openjpa - - - - sql - - - ojson - - true - - - - clean verify - - - - org.apache.openjpa - openjpa-maven-plugin - true - - - schemagen - process-classes - - ${action} - - - - - - - - - - pgjsonb - - - - org.postgresql - postgresql - ${jdbc.postgresql.version} - test - - - - - clean verify - - - - org.codehaus.mojo - build-helper-maven-plugin - - - add-test-source - generate-test-sources - - add-test-source - - - - ${basedir}/../persistence-jpa/src/test/java - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - **/*Test.java - - multitenancy,plainAttrTable - - ${project.activeProfiles[0].id} - classpath:core-pgjsonb.properties,classpath:core-pgjsonb-test.properties - ${docker.container.postgres.ip} - file:${bundles.directory}/ - - - - - - io.fabric8 - docker-maven-plugin - - - - postgres - postgres:${docker.postgresql.version} - - postgres -N 200 - - syncope - syncope - syncope - - - database system is ready to accept connections - - - - /var/lib/postgresql/data:rw - - - - - - - - start-postgres - pre-integration-test - - start - - - - stop-postgres - post-integration-test - - stop - remove - - - - - - - - - src/test/resources - true - - - - - - - myjson - - - - com.mysql - mysql-connector-j - ${jdbc.mysql.version} - test - - - - - clean verify - - - - org.codehaus.mojo - build-helper-maven-plugin - - - add-test-source - generate-test-sources - - add-test-source - - - - ${basedir}/../persistence-jpa/src/test/java - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - **/*Test.java - - multitenancy,plainAttrTable - - ${project.activeProfiles[0].id} - classpath:core-myjson.properties,classpath:core-myjson-test.properties - ${docker.container.mysql.ip} - file:${bundles.directory}/ - - - - - - io.fabric8 - docker-maven-plugin - - - - mysql - mysql:${docker.mysql.version} - - --skip-log-bin --server-id=1 - - password - syncope - syncope - syncope - - - /var/lib/mysql:rw - - - MySQL init process done. Ready for start up. - - - - - - - - - start-mysql - pre-integration-test - - start - - - - stop-mysql - post-integration-test - - stop - remove - - - - - - - - - src/test/resources - true - - - - - - - majson - - - - org.mariadb.jdbc - mariadb-java-client - ${jdbc.mariadb.version} - test - - - - - clean verify - - - - org.codehaus.mojo - build-helper-maven-plugin - - - add-test-source - generate-test-sources - - add-test-source - - - - ${basedir}/../persistence-jpa/src/test/java - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - **/*Test.java - - multitenancy,plainAttrTable - - ${project.activeProfiles[0].id} - classpath:core-majson.properties,classpath:core-majson-test.properties - ${docker.container.mariadb.ip} - file:${bundles.directory}/ - - - - - - io.fabric8 - docker-maven-plugin - - - - mariadb - mariadb:${docker.mariadb.version} - - - password - syncope - syncope - syncope - - - /var/lib/mysql:rw - - - MariaDB init process done. Ready for start up. - - - - - - - - - start-mariadb - pre-integration-test - - start - - - - stop-mariadb - post-integration-test - - stop - remove - - - - - - - - - src/test/resources - true - - - - - - - ojson - - - - com.oracle.database.jdbc - ojdbc11 - ${jdbc.oracle.version} - test - - - - - clean verify - - - - org.codehaus.mojo - build-helper-maven-plugin - - - add-test-source - generate-test-sources - - add-test-source - - - - ${basedir}/../persistence-jpa/src/test/java - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - **/*Test.java - - multitenancy,plainAttrTable - - ${project.activeProfiles[0].id} - classpath:core-ojson.properties,classpath:core-ojson-test.properties - ${docker.container.oracle.ip} - file:${bundles.directory}/ - - - - - - io.fabric8 - docker-maven-plugin - - - - oracle - gvenzl/oracle-xe:21-slim - - - password - syncope - syncope - - - DATABASE IS READY TO USE - - - - - - - - - start-oracle - pre-integration-test - - start - - - - stop-oracle - post-integration-test - - stop - remove - - - - - - - - - src/test/resources - true - - - - - - diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/api/dao/JPAJSONAnyDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/api/dao/JPAJSONAnyDAO.java deleted file mode 100644 index f6fed58dd39..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/api/dao/JPAJSONAnyDAO.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.api.dao; - -import java.util.List; -import java.util.Optional; -import org.apache.syncope.core.persistence.api.entity.Any; -import org.apache.syncope.core.persistence.api.entity.AnyUtils; -import org.apache.syncope.core.persistence.api.entity.DerSchema; -import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.PlainSchema; - -public interface JPAJSONAnyDAO { - - > List findByPlainAttrValue( - String table, - AnyUtils anyUtils, - PlainSchema schema, - PlainAttrValue attrValue, - boolean ignoreCaseMatch); - - > Optional findByPlainAttrUniqueValue( - String table, - AnyUtils anyUtils, - PlainSchema schema, - PlainAttrUniqueValue attrUniqueValue, - boolean ignoreCaseMatch); - - > List findByDerAttrValue( - String table, AnyUtils anyUtils, DerSchema schema, String value, boolean ignoreCaseMatch); - - > void checkBeforeSave(String table, AnyUtils anyUtils, A any); -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/api/entity/JSONAttributable.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/api/entity/JSONAttributable.java deleted file mode 100644 index 5f3b6a3e5ef..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/api/entity/JSONAttributable.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.api.entity; - -import java.util.List; - -public interface JSONAttributable> { - - String getPlainAttrsJSON(); - - void setPlainAttrsJSON(String plainAttrs); - - boolean add(JSONPlainAttr attr); - - List> getPlainAttrList(); -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/api/entity/JSONLAPlainAttr.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/api/entity/JSONLAPlainAttr.java deleted file mode 100644 index 56dae7de615..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/api/entity/JSONLAPlainAttr.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.api.entity; - -import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.User; - -public interface JSONLAPlainAttr extends JSONPlainAttr, LAPlainAttr { -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/api/entity/JSONPlainAttr.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/api/entity/JSONPlainAttr.java deleted file mode 100644 index 78f75034706..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/api/entity/JSONPlainAttr.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.api.entity; - -public interface JSONPlainAttr> extends PlainAttr { - - String getSchemaKey(); - - boolean add(PlainAttrValue value); -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/JPAJSONPersistenceContext.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/JPAJSONPersistenceContext.java deleted file mode 100644 index 78da898b5c5..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/JPAJSONPersistenceContext.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa; - -import jakarta.persistence.EntityManager; -import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO; -import org.apache.syncope.core.persistence.api.dao.AnyMatchDAO; -import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; -import org.apache.syncope.core.persistence.api.dao.AnySearchDAO; -import org.apache.syncope.core.persistence.api.dao.DelegationDAO; -import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.DynRealmDAO; -import org.apache.syncope.core.persistence.api.dao.FIQLQueryDAO; -import org.apache.syncope.core.persistence.api.dao.GroupDAO; -import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO; -import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.RoleDAO; -import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; -import org.apache.syncope.core.persistence.api.search.SearchCondVisitor; -import org.apache.syncope.core.persistence.jpa.dao.JPAJSONPlainAttrValueDAO; -import org.apache.syncope.core.persistence.jpa.dao.repo.AnyObjectRepoExt; -import org.apache.syncope.core.persistence.jpa.dao.repo.AnyObjectRepoExtJSONImpl; -import org.apache.syncope.core.persistence.jpa.dao.repo.GroupRepoExt; -import org.apache.syncope.core.persistence.jpa.dao.repo.GroupRepoExtJSONImpl; -import org.apache.syncope.core.persistence.jpa.dao.repo.JSONAnyObjectRepo; -import org.apache.syncope.core.persistence.jpa.dao.repo.JSONGroupRepo; -import org.apache.syncope.core.persistence.jpa.dao.repo.JSONUserRepo; -import org.apache.syncope.core.persistence.jpa.dao.repo.UserRepoExt; -import org.apache.syncope.core.persistence.jpa.dao.repo.UserRepoExtJSONImpl; -import org.apache.syncope.core.spring.security.SecurityProperties; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; -import org.springframework.data.jpa.repository.support.JpaRepositoryFactory; - -@Configuration(proxyBeanMethods = false) -public abstract class JPAJSONPersistenceContext { - - @ConditionalOnMissingBean(name = "jpaJSONAnyObjectRepoExt") - @Bean - public AnyObjectRepoExt anyObjectRepoExt( - final AnyUtilsFactory anyUtilsFactory, - final @Lazy PlainSchemaDAO plainSchemaDAO, - final @Lazy DerSchemaDAO derSchemaDAO, - final @Lazy DynRealmDAO dynRealmDAO, - final @Lazy UserDAO userDAO, - final @Lazy GroupDAO groupDAO, - final @Lazy JPAJSONAnyDAO anyDAO, - final EntityManager entityManager) { - - return new AnyObjectRepoExtJSONImpl( - anyUtilsFactory, - plainSchemaDAO, - derSchemaDAO, - dynRealmDAO, - userDAO, - groupDAO, - anyDAO, - entityManager); - } - - @ConditionalOnMissingBean(name = "jpaJSONAnyObjectDAO") - @Bean - public AnyObjectDAO anyObjectDAO( - final JpaRepositoryFactory jpaRepositoryFactory, - final AnyObjectRepoExt anyObjectRepoExt) { - - return jpaRepositoryFactory.getRepository(JSONAnyObjectRepo.class, anyObjectRepoExt); - } - - @ConditionalOnMissingBean(name = "jpaJSONGroupRepoExt") - @Bean - public GroupRepoExt groupRepoExt( - final AnyUtilsFactory anyUtilsFactory, - final ApplicationEventPublisher publisher, - final @Lazy PlainSchemaDAO plainSchemaDAO, - final @Lazy DerSchemaDAO derSchemaDAO, - final @Lazy DynRealmDAO dynRealmDAO, - final @Lazy AnyMatchDAO anyMatchDAO, - final @Lazy UserDAO userDAO, - final @Lazy AnyObjectDAO anyObjectDAO, - final @Lazy AnySearchDAO anySearchDAO, - final @Lazy JPAJSONAnyDAO anyDAO, - final SearchCondVisitor searchCondVisitor, - final EntityManager entityManager) { - - return new GroupRepoExtJSONImpl( - anyUtilsFactory, - publisher, - plainSchemaDAO, - derSchemaDAO, - dynRealmDAO, - anyMatchDAO, - userDAO, - anyObjectDAO, - anySearchDAO, - anyDAO, - searchCondVisitor, - entityManager); - } - - @ConditionalOnMissingBean(name = "jpaJSONGroupDAO") - @Bean - public GroupDAO groupDAO( - final JpaRepositoryFactory jpaRepositoryFactory, - final GroupRepoExt groupRepoExt) { - - return jpaRepositoryFactory.getRepository(JSONGroupRepo.class, groupRepoExt); - } - - @ConditionalOnMissingBean(name = "jpaJSONPlainAttrValueDAO") - @Bean - public PlainAttrValueDAO plainAttrValueDAO() { - return new JPAJSONPlainAttrValueDAO(); - } - - @ConditionalOnMissingBean(name = "jpaJSONUserRepoExt") - @Bean - public UserRepoExt userRepoExt( - final AnyUtilsFactory anyUtilsFactory, - final @Lazy PlainSchemaDAO plainSchemaDAO, - final @Lazy DerSchemaDAO derSchemaDAO, - final @Lazy DynRealmDAO dynRealmDAO, - final @Lazy RoleDAO roleDAO, - final @Lazy AccessTokenDAO accessTokenDAO, - final @Lazy GroupDAO groupDAO, - final @Lazy DelegationDAO delegationDAO, - final @Lazy FIQLQueryDAO fiqlQueryDAO, - final @Lazy JPAJSONAnyDAO anyDAO, - final SecurityProperties securityProperties, - final EntityManager entityManager) { - - return new UserRepoExtJSONImpl( - anyUtilsFactory, - plainSchemaDAO, - derSchemaDAO, - dynRealmDAO, - roleDAO, - accessTokenDAO, - groupDAO, - delegationDAO, - fiqlQueryDAO, - anyDAO, - securityProperties, - entityManager); - } - - @ConditionalOnMissingBean(name = "jpaJSONUserDAO") - @Bean - public UserDAO userDAO( - final JpaRepositoryFactory jpaRepositoryFactory, - final UserRepoExt userRepoExt) { - - return jpaRepositoryFactory.getRepository(JSONUserRepo.class, userRepoExt); - } -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONPlainAttrValueDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONPlainAttrValueDAO.java deleted file mode 100644 index 52374c8f1a0..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJSONPlainAttrValueDAO.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao; - -import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO; -import org.apache.syncope.core.persistence.api.entity.AnyUtils; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; - -public class JPAJSONPlainAttrValueDAO implements PlainAttrValueDAO { - - @Override - public void deleteAll(final PlainAttr attr, final AnyUtils anyUtils) { - if (attr.getUniqueValue() == null) { - attr.getValues().clear(); - } else { - attr.setUniqueValue(null); - } - } -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyObjectRepoExtJSONImpl.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyObjectRepoExtJSONImpl.java deleted file mode 100644 index 78a793b3b56..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyObjectRepoExtJSONImpl.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao.repo; - -import jakarta.persistence.EntityManager; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.DynRealmDAO; -import org.apache.syncope.core.persistence.api.dao.GroupDAO; -import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; -import org.apache.syncope.core.persistence.api.entity.DerSchema; -import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; -import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAJSONAnyObject; - -public class AnyObjectRepoExtJSONImpl extends AnyObjectRepoExtImpl { - - protected final JPAJSONAnyDAO anyDAO; - - public AnyObjectRepoExtJSONImpl( - final AnyUtilsFactory anyUtilsFactory, - final PlainSchemaDAO plainSchemaDAO, - final DerSchemaDAO derSchemaDAO, - final DynRealmDAO dynRealmDAO, - final UserDAO userDAO, - final GroupDAO groupDAO, - final JPAJSONAnyDAO anyDAO, - final EntityManager entityManager) { - - super( - anyUtilsFactory, - plainSchemaDAO, - derSchemaDAO, - dynRealmDAO, - userDAO, - groupDAO, - entityManager); - this.anyDAO = anyDAO; - } - - @Override - public List findByPlainAttrValue( - final PlainSchema schema, - final PlainAttrValue attrValue, - final boolean ignoreCaseMatch) { - - return anyDAO.findByPlainAttrValue(JPAJSONAnyObject.TABLE, anyUtils, schema, attrValue, ignoreCaseMatch); - } - - @Override - public Optional findByPlainAttrUniqueValue( - final PlainSchema schema, - final PlainAttrUniqueValue attrUniqueValue, - final boolean ignoreCaseMatch) { - - return anyDAO.findByPlainAttrUniqueValue( - JPAJSONAnyObject.TABLE, anyUtils, schema, attrUniqueValue, ignoreCaseMatch); - } - - @Override - public List findByDerAttrValue( - final DerSchema schema, - final String value, - final boolean ignoreCaseMatch) { - - return anyDAO.findByDerAttrValue(JPAJSONAnyObject.TABLE, anyUtils, schema, value, ignoreCaseMatch); - } - - @Override - protected Pair, Set>> doSave(final AnyObject anyObject) { - AnyObject merged = entityManager.merge(anyObject); - - // ensure that entity listeners are invoked at this point - entityManager.flush(); - - Pair, Set> dynGroupMembs = groupDAO.refreshDynMemberships(merged); - dynRealmDAO.refreshDynMemberships(merged); - - return Pair.of(merged, dynGroupMembs); - } - - @Override - public S save(final S anyObject) { - anyDAO.checkBeforeSave(JPAJSONAnyObject.TABLE, anyUtils, anyObject); - return super.save(anyObject); - } -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/GroupRepoExtJSONImpl.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/GroupRepoExtJSONImpl.java deleted file mode 100644 index a5af21c9158..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/GroupRepoExtJSONImpl.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao.repo; - -import jakarta.persistence.EntityManager; -import java.util.List; -import java.util.Optional; -import org.apache.syncope.core.persistence.api.dao.AnyMatchDAO; -import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; -import org.apache.syncope.core.persistence.api.dao.AnySearchDAO; -import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.DynRealmDAO; -import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; -import org.apache.syncope.core.persistence.api.entity.DerSchema; -import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.group.Group; -import org.apache.syncope.core.persistence.api.search.SearchCondVisitor; -import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup; -import org.springframework.context.ApplicationEventPublisher; - -public class GroupRepoExtJSONImpl extends GroupRepoExtImpl { - - protected final JPAJSONAnyDAO anyDAO; - - public GroupRepoExtJSONImpl( - final AnyUtilsFactory anyUtilsFactory, - final ApplicationEventPublisher publisher, - final PlainSchemaDAO plainSchemaDAO, - final DerSchemaDAO derSchemaDAO, - final DynRealmDAO dynRealmDAO, - final AnyMatchDAO anyMatchDAO, - final UserDAO userDAO, - final AnyObjectDAO anyObjectDAO, - final AnySearchDAO searchDAO, - final JPAJSONAnyDAO anyDAO, - final SearchCondVisitor searchCondVisitor, - final EntityManager entityManager) { - - super( - anyUtilsFactory, - publisher, - plainSchemaDAO, - derSchemaDAO, - dynRealmDAO, - anyMatchDAO, - userDAO, - anyObjectDAO, - searchDAO, - searchCondVisitor, - entityManager); - this.anyDAO = anyDAO; - } - - @Override - public List findByPlainAttrValue( - final PlainSchema schema, - final PlainAttrValue attrValue, - final boolean ignoreCaseMatch) { - - return anyDAO.findByPlainAttrValue(JPAGroup.TABLE, anyUtils, schema, attrValue, ignoreCaseMatch); - } - - @Override - public Optional findByPlainAttrUniqueValue( - final PlainSchema schema, - final PlainAttrUniqueValue attrUniqueValue, - final boolean ignoreCaseMatch) { - - return anyDAO.findByPlainAttrUniqueValue(JPAGroup.TABLE, anyUtils, schema, attrUniqueValue, ignoreCaseMatch); - } - - @Override - public List findByDerAttrValue( - final DerSchema schema, - final String value, - final boolean ignoreCaseMatch) { - - return anyDAO.findByDerAttrValue(JPAGroup.TABLE, anyUtils, schema, value, ignoreCaseMatch); - } - - @Override - public S save(final S group) { - anyDAO.checkBeforeSave(JPAGroup.TABLE, anyUtils, group); - return entityManager.merge(group); - } -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/JSONAnyObjectRepo.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/JSONAnyObjectRepo.java deleted file mode 100644 index d4439cd72ab..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/JSONAnyObjectRepo.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao.repo; - -import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAJSONAnyObject; -import org.springframework.data.repository.PagingAndSortingRepository; - -public interface JSONAnyObjectRepo - extends PagingAndSortingRepository, AnyObjectRepoBase, AnyObjectRepoExt { -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/JSONGroupRepo.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/JSONGroupRepo.java deleted file mode 100644 index 772776a150d..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/JSONGroupRepo.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao.repo; - -import org.apache.syncope.core.persistence.jpa.entity.group.JPAJSONGroup; -import org.springframework.data.repository.PagingAndSortingRepository; - -public interface JSONGroupRepo - extends PagingAndSortingRepository, GroupRepoBase, GroupRepoExt { -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/JSONUserRepo.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/JSONUserRepo.java deleted file mode 100644 index b9191339a0e..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/JSONUserRepo.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao.repo; - -import org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONUser; -import org.springframework.data.repository.PagingAndSortingRepository; - -public interface JSONUserRepo - extends PagingAndSortingRepository, UserRepoBase, UserRepoExt { -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/UserRepoExtJSONImpl.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/UserRepoExtJSONImpl.java deleted file mode 100644 index 57012a31a44..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/UserRepoExtJSONImpl.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao.repo; - -import jakarta.persistence.EntityManager; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO; -import org.apache.syncope.core.persistence.api.dao.DelegationDAO; -import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.DynRealmDAO; -import org.apache.syncope.core.persistence.api.dao.FIQLQueryDAO; -import org.apache.syncope.core.persistence.api.dao.GroupDAO; -import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.dao.RoleDAO; -import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; -import org.apache.syncope.core.persistence.api.entity.DerSchema; -import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.user.User; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONUser; -import org.apache.syncope.core.spring.security.SecurityProperties; - -public class UserRepoExtJSONImpl extends UserRepoExtImpl { - - protected final JPAJSONAnyDAO anyDAO; - - public UserRepoExtJSONImpl( - final AnyUtilsFactory anyUtilsFactory, - final PlainSchemaDAO plainSchemaDAO, - final DerSchemaDAO derSchemaDAO, - final DynRealmDAO dynRealmDAO, - final RoleDAO roleDAO, - final AccessTokenDAO accessTokenDAO, - final GroupDAO groupDAO, - final DelegationDAO delegationDAO, - final FIQLQueryDAO fiqlQueryDAO, - final JPAJSONAnyDAO anyDAO, - final SecurityProperties securityProperties, - final EntityManager entityManager) { - - super( - anyUtilsFactory, - plainSchemaDAO, - derSchemaDAO, - dynRealmDAO, - roleDAO, - accessTokenDAO, - groupDAO, - delegationDAO, - fiqlQueryDAO, - securityProperties, - entityManager); - this.anyDAO = anyDAO; - } - - @Override - public List findByPlainAttrValue( - final PlainSchema schema, - final PlainAttrValue attrValue, - final boolean ignoreCaseMatch) { - - return anyDAO.findByPlainAttrValue(JPAJSONUser.TABLE, anyUtils, schema, attrValue, ignoreCaseMatch); - } - - @Override - public Optional findByPlainAttrUniqueValue( - final PlainSchema schema, - final PlainAttrUniqueValue attrUniqueValue, - final boolean ignoreCaseMatch) { - - return anyDAO.findByPlainAttrUniqueValue(JPAJSONUser.TABLE, anyUtils, schema, attrUniqueValue, ignoreCaseMatch); - } - - @Override - public List findByDerAttrValue( - final DerSchema schema, - final String value, - final boolean ignoreCaseMatch) { - - return anyDAO.findByDerAttrValue(JPAJSONUser.TABLE, anyUtils, schema, value, ignoreCaseMatch); - } - - @Override - protected Pair, Set>> doSave(final User user) { - entityManager.flush(); - User merged = entityManager.merge(user); - - // ensure that entity listeners are invoked at this point - entityManager.flush(); - - roleDAO.refreshDynMemberships(merged); - Pair, Set> dynGroupMembs = groupDAO.refreshDynMemberships(merged); - dynRealmDAO.refreshDynMemberships(merged); - - return Pair.of(merged, dynGroupMembs); - } - - @Override - public S save(final S user) { - anyDAO.checkBeforeSave(JPAJSONUser.TABLE, anyUtils, user); - return super.save(user); - } - - @Override - public Pair, Set> saveAndGetDynGroupMembs(final User user) { - anyDAO.checkBeforeSave(JPAJSONUser.TABLE, anyUtils, user); - return super.saveAndGetDynGroupMembs(user); - } -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAJSONEntityFactory.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAJSONEntityFactory.java deleted file mode 100644 index 24dcd0695e1..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAJSONEntityFactory.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity; - -import org.apache.syncope.core.persistence.api.entity.Entity; -import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; -import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.group.Group; -import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.user.User; -import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAJSONAPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAJSONAPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAJSONAPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAJSONAnyObject; -import org.apache.syncope.core.persistence.jpa.entity.group.JPAJSONGPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.group.JPAJSONGPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.group.JPAJSONGPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.group.JPAJSONGroup; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONLAPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONLAPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONLAPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONLinkedAccount; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONUPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONUPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONUPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONUser; -import org.apache.syncope.core.spring.security.SecureRandomUtils; - -public abstract class JPAJSONEntityFactory extends JPAEntityFactory { - - @SuppressWarnings("unchecked") - @Override - public E newEntity(final Class reference) { - E result; - - if (reference.equals(User.class)) { - result = (E) new JPAJSONUser(); - ((JPAJSONUser) result).setKey(SecureRandomUtils.generateRandomUUID().toString()); - } else if (reference.equals(LinkedAccount.class)) { - result = (E) new JPAJSONLinkedAccount(); - ((JPAJSONLinkedAccount) result).setKey(SecureRandomUtils.generateRandomUUID().toString()); - } else if (reference.equals(Group.class)) { - result = (E) new JPAJSONGroup(); - ((JPAJSONGroup) result).setKey(SecureRandomUtils.generateRandomUUID().toString()); - } else if (reference.equals(AnyObject.class)) { - result = (E) new JPAJSONAnyObject(); - ((JPAJSONAnyObject) result).setKey(SecureRandomUtils.generateRandomUUID().toString()); - } else if (reference.equals(APlainAttr.class)) { - result = (E) new JPAJSONAPlainAttr(); - } else if (reference.equals(APlainAttrValue.class)) { - result = (E) new JPAJSONAPlainAttrValue(); - } else if (reference.equals(APlainAttrUniqueValue.class)) { - result = (E) new JPAJSONAPlainAttrUniqueValue(); - } else if (reference.equals(GPlainAttr.class)) { - result = (E) new JPAJSONGPlainAttr(); - } else if (reference.equals(GPlainAttrValue.class)) { - result = (E) new JPAJSONGPlainAttrValue(); - } else if (reference.equals(GPlainAttrUniqueValue.class)) { - result = (E) new JPAJSONGPlainAttrUniqueValue(); - } else if (reference.equals(UPlainAttr.class)) { - result = (E) new JPAJSONUPlainAttr(); - } else if (reference.equals(UPlainAttrValue.class)) { - result = (E) new JPAJSONUPlainAttrValue(); - } else if (reference.equals(UPlainAttrUniqueValue.class)) { - result = (E) new JPAJSONUPlainAttrUniqueValue(); - } else if (reference.equals(LAPlainAttr.class)) { - result = (E) new JPAJSONLAPlainAttr(); - } else if (reference.equals(LAPlainAttrValue.class)) { - result = (E) new JPAJSONLAPlainAttrValue(); - } else if (reference.equals(LAPlainAttrUniqueValue.class)) { - result = (E) new JPAJSONLAPlainAttrUniqueValue(); - } else { - result = super.newEntity(reference); - } - - return result; - } - - @Override - public Class userClass() { - return JPAJSONUser.class; - } - - @Override - public Class groupClass() { - return JPAJSONGroup.class; - } - - @Override - public Class anyObjectClass() { - return JPAJSONAnyObject.class; - } -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAnyObject.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAnyObject.java deleted file mode 100644 index bd0bbb7e398..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAnyObject.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.anyobject; - -import jakarta.persistence.Entity; -import jakarta.persistence.EntityListeners; -import jakarta.persistence.Table; -import jakarta.persistence.Transient; -import jakarta.persistence.UniqueConstraint; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import org.apache.syncope.core.persistence.api.entity.JSONAttributable; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; -import org.apache.syncope.core.persistence.api.entity.Membership; -import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; -import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; -import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; -import org.apache.syncope.core.persistence.jpa.validation.JPAJSONAttributableCheck; - -@Entity -@Table(name = JPAAnyObject.TABLE, uniqueConstraints = - @UniqueConstraint(columnNames = { "name", "type_id" })) -@EntityListeners({ JPAJSONAnyObjectListener.class }) -@JPAJSONAttributableCheck -public class JPAJSONAnyObject extends JPAAnyObject implements JSONAttributable, AnyObject { - - private static final long serialVersionUID = -8543654943709531885L; - - private String plainAttrs; - - @Transient - private final List plainAttrList = new ArrayList<>(); - - @Override - public String getPlainAttrsJSON() { - return plainAttrs; - } - - @Override - public void setPlainAttrsJSON(final String plainAttrs) { - this.plainAttrs = plainAttrs; - } - - @Override - public List getPlainAttrList() { - return plainAttrList; - } - - @Override - public boolean add(final JSONPlainAttr attr) { - return add((APlainAttr) attr); - } - - @Override - public boolean add(final APlainAttr attr) { - checkType(attr, JPAJSONAPlainAttr.class); - return plainAttrList.add((JPAJSONAPlainAttr) attr); - } - - @Override - public boolean remove(final APlainAttr attr) { - return plainAttrList.removeIf(jsonAttr -> jsonAttr.getSchemaKey().equals(attr.getSchema().getKey()) - && Objects.equals(jsonAttr.getMembershipKey(), ((JPAJSONAPlainAttr) attr).getMembershipKey())); - } - - @Override - protected List internalGetPlainAttrs() { - return plainAttrList; - } - - @Override - public List getPlainAttrs() { - return plainAttrList.stream(). - filter(attr -> attr.getMembershipKey() == null). - toList(); - } - - @Override - public Optional getPlainAttr(final String plainSchema) { - return plainAttrList.stream(). - filter(attr -> attr.getSchemaKey() != null && attr.getSchemaKey().equals(plainSchema) - && attr.getMembershipKey() == null). - findFirst(); - } - - @Override - public Optional getPlainAttr(final String plainSchema, final Membership membership) { - return plainAttrList.stream(). - filter(attr -> attr.getSchemaKey() != null && attr.getSchemaKey().equals(plainSchema) - && attr.getMembershipKey() != null && attr.getMembershipKey().equals(membership.getKey())). - findFirst(); - } - - @Override - public boolean remove(final AMembership membership) { - plainAttrList.removeIf(attr -> attr.getMembershipKey() != null - && attr.getMembershipKey().equals(membership.getKey())); - return super.remove(membership); - } -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGPlainAttr.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGPlainAttr.java deleted file mode 100644 index bb3fd349f4b..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGPlainAttr.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.group; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; -import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.group.Group; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema; -import org.apache.syncope.core.spring.ApplicationContextProvider; - -@JsonIgnoreProperties("valuesAsStrings") -@JsonInclude(JsonInclude.Include.NON_EMPTY) -public class JPAJSONGPlainAttr extends AbstractPlainAttr implements GPlainAttr, JSONPlainAttr { - - private static final long serialVersionUID = 806271775349587902L; - - /** - * The owner of this attribute. - */ - @JsonIgnore - private JPAJSONGroup owner; - - @JsonProperty - private String schema; - - /** - * Values of this attribute (if schema is not UNIQUE). - */ - private final List values = new ArrayList<>(); - - /** - * Value of this attribute (if schema is UNIQUE). - */ - @JsonProperty - private JPAJSONGPlainAttrUniqueValue uniqueValue; - - @Override - public Group getOwner() { - return owner; - } - - @Override - public void setOwner(final Group owner) { - checkType(owner, JPAJSONGroup.class); - this.owner = (JPAJSONGroup) owner; - } - - @JsonIgnore - @Override - public String getSchemaKey() { - return schema; - } - - @JsonIgnore - @Override - public JPAPlainSchema getSchema() { - return Optional.ofNullable(schema). - flatMap(s -> ApplicationContextProvider.getBeanFactory().getBean(PlainSchemaDAO.class).findById(s)). - map(JPAPlainSchema.class::cast). - orElse(null); - } - - @Override - public void setSchema(final PlainSchema schema) { - if (schema != null) { - this.schema = schema.getKey(); - } - } - - @JsonSetter("schema") - public void setSchema(final String schema) { - this.schema = schema; - } - - @Override - protected boolean addForMultiValue(final PlainAttrValue attrValue) { - checkType(attrValue, JPAJSONGPlainAttrValue.class); - return values.add((JPAJSONGPlainAttrValue) attrValue); - } - - @Override - public boolean add(final PlainAttrValue value) { - return addForMultiValue(value); - } - - @Override - public List getValues() { - return values; - } - - @JsonIgnore - public List getPGValues() { - return values; - } - - @Override - public JPAJSONGPlainAttrUniqueValue getUniqueValue() { - return uniqueValue; - } - - @JsonIgnore - @Override - public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) { - checkType(uniqueValue, JPAJSONGPlainAttrUniqueValue.class); - this.uniqueValue = (JPAJSONGPlainAttrUniqueValue) uniqueValue; - } - - @Override - public int hashCode() { - return new HashCodeBuilder(). - append(schema). - append(values). - append(uniqueValue). - build(); - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final JPAJSONGPlainAttr other = (JPAJSONGPlainAttr) obj; - return new EqualsBuilder(). - append(schema, other.schema). - append(values, other.values). - append(uniqueValue, other.uniqueValue). - build(); - } -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGroup.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGroup.java deleted file mode 100644 index 944e069faca..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGroup.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.group; - -import jakarta.persistence.Entity; -import jakarta.persistence.EntityListeners; -import jakarta.persistence.Table; -import jakarta.persistence.Transient; -import java.util.ArrayList; -import java.util.List; -import org.apache.syncope.core.persistence.api.entity.JSONAttributable; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; -import org.apache.syncope.core.persistence.api.entity.group.Group; -import org.apache.syncope.core.persistence.jpa.validation.JPAJSONAttributableCheck; - -@Entity -@Table(name = JPAGroup.TABLE) -@EntityListeners({ JPAJSONGroupListener.class }) -@JPAJSONAttributableCheck -public class JPAJSONGroup extends JPAGroup implements JSONAttributable, Group { - - private static final long serialVersionUID = -8543654943709531885L; - - private String plainAttrs; - - @Transient - private final List plainAttrList = new ArrayList<>(); - - @Override - public String getPlainAttrsJSON() { - return plainAttrs; - } - - @Override - public void setPlainAttrsJSON(final String plainAttrs) { - this.plainAttrs = plainAttrs; - } - - @Override - public List getPlainAttrList() { - return plainAttrList; - } - - @Override - public boolean add(final JSONPlainAttr attr) { - return add((GPlainAttr) attr); - } - - @Override - public boolean add(final GPlainAttr attr) { - checkType(attr, JPAJSONGPlainAttr.class); - return plainAttrList.add((JPAJSONGPlainAttr) attr); - } - - @Override - public boolean remove(final GPlainAttr attr) { - return plainAttrList.removeIf(jsonAttr -> jsonAttr.getSchemaKey().equals(attr.getSchema().getKey())); - } - - @Override - public List getPlainAttrs() { - return plainAttrList; - } -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLAPlainAttr.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLAPlainAttr.java deleted file mode 100644 index b81814cb9e7..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLAPlainAttr.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.user; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.entity.JSONLAPlainAttr; -import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; -import org.apache.syncope.core.persistence.api.entity.user.User; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema; -import org.apache.syncope.core.spring.ApplicationContextProvider; - -@JsonIgnoreProperties("valuesAsStrings") -@JsonInclude(JsonInclude.Include.NON_EMPTY) -public class JPAJSONLAPlainAttr extends AbstractPlainAttr implements JSONLAPlainAttr { - - private static final long serialVersionUID = -7712812886044037467L; - - /** - * The owner of this attribute. - */ - @JsonIgnore - private JPAJSONUser owner; - - @JsonIgnore - private JPAJSONLinkedAccount account; - - @JsonProperty - private String schema; - - /** - * Values of this attribute (if schema is not UNIQUE). - */ - private final List values = new ArrayList<>(); - - /** - * Value of this attribute (if schema is UNIQUE). - */ - @JsonProperty - private JPAJSONLAPlainAttrUniqueValue uniqueValue; - - @Override - public User getOwner() { - return owner; - } - - @Override - public void setOwner(final User owner) { - checkType(owner, JPAJSONUser.class); - this.owner = (JPAJSONUser) owner; - } - - @Override - public LinkedAccount getAccount() { - return account; - } - - @Override - public void setAccount(final LinkedAccount account) { - checkType(account, JPAJSONLinkedAccount.class); - this.account = (JPAJSONLinkedAccount) account; - } - - @JsonIgnore - @Override - public String getSchemaKey() { - return schema; - } - - @JsonIgnore - @Override - public JPAPlainSchema getSchema() { - return Optional.ofNullable(schema). - flatMap(s -> ApplicationContextProvider.getBeanFactory().getBean(PlainSchemaDAO.class).findById(s)). - map(JPAPlainSchema.class::cast). - orElse(null); - } - - @Override - public void setSchema(final PlainSchema schema) { - if (schema != null) { - this.schema = schema.getKey(); - } - } - - @JsonSetter("schema") - public void setSchema(final String schema) { - this.schema = schema; - } - - @Override - protected boolean addForMultiValue(final PlainAttrValue attrValue) { - checkType(attrValue, JPAJSONLAPlainAttrValue.class); - return values.add((JPAJSONLAPlainAttrValue) attrValue); - } - - @Override - public boolean add(final PlainAttrValue value) { - return addForMultiValue(value); - } - - @Override - public List getValues() { - return values; - } - - @JsonIgnore - public List getPGValues() { - return values; - } - - @Override - public JPAJSONLAPlainAttrUniqueValue getUniqueValue() { - return uniqueValue; - } - - @JsonIgnore - @Override - public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) { - checkType(uniqueValue, JPAJSONLAPlainAttrUniqueValue.class); - this.uniqueValue = (JPAJSONLAPlainAttrUniqueValue) uniqueValue; - } - - @Override - public int hashCode() { - return new HashCodeBuilder(). - append(schema). - append(account). - append(values). - append(uniqueValue). - build(); - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final JPAJSONLAPlainAttr other = (JPAJSONLAPlainAttr) obj; - return new EqualsBuilder(). - append(schema, other.schema). - append(account, other.account). - append(values, other.values). - append(uniqueValue, other.uniqueValue). - build(); - } -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLinkedAccount.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLinkedAccount.java deleted file mode 100644 index bffdb3d867e..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLinkedAccount.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.user; - -import jakarta.persistence.Entity; -import jakarta.persistence.EntityListeners; -import jakarta.persistence.Table; -import jakarta.persistence.Transient; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import org.apache.syncope.core.persistence.api.entity.JSONAttributable; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; -import org.apache.syncope.core.persistence.api.entity.user.User; -import org.apache.syncope.core.persistence.jpa.validation.JPAJSONAttributableCheck; - -@Entity -@Table(name = JPALinkedAccount.TABLE) -@EntityListeners({ JPAJSONLinkedAccountListener.class }) -@JPAJSONAttributableCheck -public class JPAJSONLinkedAccount extends JPALinkedAccount implements JSONAttributable, LinkedAccount { - - private static final long serialVersionUID = 7495284980208765032L; - - private String plainAttrs; - - @Transient - private final List plainAttrList = new ArrayList<>(); - - @Override - public String getPlainAttrsJSON() { - return plainAttrs; - } - - @Override - public void setPlainAttrsJSON(final String plainAttrs) { - this.plainAttrs = plainAttrs; - } - - @Override - public List getPlainAttrList() { - return plainAttrList; - } - - @Override - public boolean add(final JSONPlainAttr attr) { - return add((LAPlainAttr) attr); - } - - @Override - public boolean add(final LAPlainAttr attr) { - checkType(attr, JPAJSONLAPlainAttr.class); - return plainAttrList.add((JPAJSONLAPlainAttr) attr); - } - - @Override - public boolean remove(final LAPlainAttr attr) { - return plainAttrList.removeIf(jsonAttr -> jsonAttr.getSchemaKey().equals(attr.getSchema().getKey())); - } - - @Override - public List getPlainAttrs() { - return plainAttrList.stream().toList(); - } - - @Override - public Optional getPlainAttr(final String plainSchema) { - return plainAttrList.stream(). - filter(attr -> attr.getSchemaKey() != null && attr.getSchemaKey().equals(plainSchema)). - findFirst(); - } -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUser.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUser.java deleted file mode 100644 index 762deb26ff0..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUser.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.user; - -import jakarta.persistence.CascadeType; -import jakarta.persistence.Entity; -import jakarta.persistence.EntityListeners; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import jakarta.persistence.Transient; -import jakarta.validation.Valid; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import org.apache.syncope.core.persistence.api.entity.JSONAttributable; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; -import org.apache.syncope.core.persistence.api.entity.Membership; -import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; -import org.apache.syncope.core.persistence.api.entity.user.UMembership; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.User; -import org.apache.syncope.core.persistence.jpa.validation.JPAJSONAttributableCheck; - -@Entity -@Table(name = JPAUser.TABLE) -@EntityListeners({ JPAJSONUserListener.class }) -@JPAJSONAttributableCheck -public class JPAJSONUser extends JPAUser implements JSONAttributable, User { - - private static final long serialVersionUID = -8543654943709531885L; - - private String plainAttrs; - - @Transient - private final List plainAttrList = new ArrayList<>(); - - @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "owner") - @Valid - private List linkedAccounts = new ArrayList<>(); - - @Override - public String getPlainAttrsJSON() { - return plainAttrs; - } - - @Override - public void setPlainAttrsJSON(final String plainAttrs) { - this.plainAttrs = plainAttrs; - } - - @Override - public List getPlainAttrList() { - return plainAttrList; - } - - @Override - public boolean add(final JSONPlainAttr attr) { - return add((UPlainAttr) attr); - } - - @Override - public boolean add(final UPlainAttr attr) { - checkType(attr, JPAJSONUPlainAttr.class); - return plainAttrList.add((JPAJSONUPlainAttr) attr); - } - - @Override - public boolean remove(final UPlainAttr attr) { - return plainAttrList.removeIf(jsonAttr -> jsonAttr.getSchemaKey().equals(attr.getSchema().getKey()) - && Objects.equals(jsonAttr.getMembershipKey(), ((JPAJSONUPlainAttr) attr).getMembershipKey())); - } - - @Override - protected List internalGetPlainAttrs() { - return plainAttrList; - } - - @Override - public List getPlainAttrs() { - return plainAttrList.stream(). - filter(attr -> attr.getMembershipKey() == null). - toList(); - } - - @Override - public Optional getPlainAttr(final String plainSchema) { - return plainAttrList.stream(). - filter(attr -> attr.getSchemaKey() != null && attr.getSchemaKey().equals(plainSchema) - && attr.getMembershipKey() == null). - findFirst(); - } - - @Override - public Optional getPlainAttr(final String plainSchema, final Membership membership) { - return plainAttrList.stream(). - filter(attr -> attr.getSchemaKey() != null && attr.getSchemaKey().equals(plainSchema) - && attr.getMembershipKey() != null && attr.getMembershipKey().equals(membership.getKey())). - findFirst(); - } - - @Override - public boolean remove(final UMembership membership) { - plainAttrList.removeIf(attr -> attr.getMembershipKey() != null - && attr.getMembershipKey().equals(membership.getKey())); - return super.remove(membership); - } - - @Override - public boolean add(final LinkedAccount account) { - checkType(account, JPALinkedAccount.class); - return linkedAccounts.contains((JPAJSONLinkedAccount) account) - || linkedAccounts.add((JPAJSONLinkedAccount) account); - } - - @Override - public Optional getLinkedAccount(final String resource, final String connObjectKeyValue) { - return linkedAccounts.stream(). - filter(account -> account.getResource().getKey().equals(resource) - && account.getConnObjectKeyValue().equals(connObjectKeyValue)). - findFirst(); - } - - @Override - public List getLinkedAccounts(final String resource) { - return linkedAccounts.stream(). - filter(account -> account.getResource().getKey().equals(resource)). - toList(); - } - - @Override - public List getLinkedAccounts() { - return linkedAccounts; - } -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/validation/JPAJSONAttributableCheck.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/validation/JPAJSONAttributableCheck.java deleted file mode 100644 index d3dc6339bba..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/validation/JPAJSONAttributableCheck.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.validation; - -import jakarta.validation.Constraint; -import jakarta.validation.Payload; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target({ ElementType.TYPE }) -@Retention(RetentionPolicy.RUNTIME) -@Constraint(validatedBy = JPAJSONAttributableValidator.class) -@Documented -public @interface JPAJSONAttributableCheck { - - String message() default "{org.apache.syncope.core.persistence.validation.any}"; - - Class[] groups() default {}; - - Class[] payload() default {}; -} diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/validation/JPAJSONAttributableValidator.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/validation/JPAJSONAttributableValidator.java deleted file mode 100644 index 9d7c9970fbe..00000000000 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/validation/JPAJSONAttributableValidator.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.validation; - -import jakarta.validation.ConstraintValidatorContext; -import java.util.concurrent.atomic.AtomicReference; -import org.apache.syncope.core.persistence.api.entity.JSONAttributable; -import org.apache.syncope.core.persistence.common.validation.AbstractValidator; -import org.apache.syncope.core.persistence.common.validation.PlainAttrValidator; -import org.apache.syncope.core.persistence.common.validation.PlainAttrValueValidator; - -public class JPAJSONAttributableValidator extends AbstractValidator> { - - private static final PlainAttrValidator ATTR_VALIDATOR = new PlainAttrValidator(); - - private static final PlainAttrValueValidator ATTR_VALUE_VALIDATOR = new PlainAttrValueValidator(); - - @Override - public boolean isValid(final JSONAttributable entity, final ConstraintValidatorContext context) { - context.disableDefaultConstraintViolation(); - - AtomicReference isValid = new AtomicReference<>(Boolean.TRUE); - entity.getPlainAttrList().forEach(attr -> { - isValid.getAndSet(isValid.get() && ATTR_VALIDATOR.isValid(attr, context)); - attr.getValues().forEach( - value -> isValid.getAndSet(isValid.get() && ATTR_VALUE_VALIDATOR.isValid(value, context))); - }); - - return isValid.get(); - } -} diff --git a/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-majson.xml b/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-majson.xml deleted file mode 100644 index e80b7338638..00000000000 --- a/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-majson.xml +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-myjson.xml b/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-myjson.xml deleted file mode 100644 index e80b7338638..00000000000 --- a/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-myjson.xml +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-ojson.xml b/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-ojson.xml deleted file mode 100644 index ad7ddcb0b42..00000000000 --- a/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-ojson.xml +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-pgjsonb.xml b/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-pgjsonb.xml deleted file mode 100644 index 73e3b096a9d..00000000000 --- a/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-pgjsonb.xml +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/persistence-jpa-json/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/core/persistence-jpa-json/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index 3b77233a780..00000000000 --- a/core/persistence-jpa-json/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1,20 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -org.apache.syncope.core.persistence.jpa.PGJPAJSONPersistenceContext -org.apache.syncope.core.persistence.jpa.MyJPAJSONPersistenceContext -org.apache.syncope.core.persistence.jpa.MaJPAJSONPersistenceContext -org.apache.syncope.core.persistence.jpa.OJPAJSONPersistenceContext diff --git a/core/persistence-jpa-json/src/main/resources/core-majson.properties b/core/persistence-jpa-json/src/main/resources/core-majson.properties deleted file mode 100644 index 6e9074df4bd..00000000000 --- a/core/persistence-jpa-json/src/main/resources/core-majson.properties +++ /dev/null @@ -1,32 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -persistence.indexesXML=classpath:majson/indexes.xml -persistence.viewsXML=classpath:majson/views.xml - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=org.mariadb.jdbc.Driver -persistence.domain[0].jdbcURL=jdbc:mariadb://localhost:3306/syncope?characterEncoding=UTF-8 -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=syncope -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MariaDBDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3) -persistence.domain[0].orm=META-INF/spring-orm-majson.xml -persistence.domain[0].poolMaxActive=10 -persistence.domain[0].poolMinIdle=2 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_mariadb.sql diff --git a/core/persistence-jpa-json/src/main/resources/core-myjson.properties b/core/persistence-jpa-json/src/main/resources/core-myjson.properties deleted file mode 100644 index dbf86402bc8..00000000000 --- a/core/persistence-jpa-json/src/main/resources/core-myjson.properties +++ /dev/null @@ -1,29 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -persistence.indexesXML=classpath:myjson/indexes.xml -persistence.viewsXML=classpath:myjson/views.xml - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=com.mysql.cj.jdbc.Driver -persistence.domain[0].jdbcURL=jdbc:mysql://localhost:3306/syncope?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8 -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=syncope -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3,useSetStringForClobs=true) -persistence.domain[0].orm=META-INF/spring-orm-myjson.xml -persistence.domain[0].poolMaxActive=20 -persistence.domain[0].poolMinIdle=5 diff --git a/core/persistence-jpa-json/src/main/resources/core-ojson.properties b/core/persistence-jpa-json/src/main/resources/core-ojson.properties deleted file mode 100644 index adf6a9516f8..00000000000 --- a/core/persistence-jpa-json/src/main/resources/core-ojson.properties +++ /dev/null @@ -1,30 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -persistence.indexesXML=classpath:ojson/indexes.xml -persistence.viewsXML=classpath:ojson/views.xml - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=oracle.jdbc.OracleDriver -persistence.domain[0].jdbcURL=jdbc:oracle:thin:@localhost:1521/XEPDB1 -persistence.domain[0].schema=SYNCOPE -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=syncope -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.OracleDictionary -persistence.domain[0].orm=META-INF/spring-orm-ojson.xml -persistence.domain[0].poolMaxActive=20 -persistence.domain[0].poolMinIdle=5 diff --git a/core/persistence-jpa-json/src/main/resources/core-pgjsonb.properties b/core/persistence-jpa-json/src/main/resources/core-pgjsonb.properties deleted file mode 100644 index e1cfd236cff..00000000000 --- a/core/persistence-jpa-json/src/main/resources/core-pgjsonb.properties +++ /dev/null @@ -1,29 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -persistence.indexesXML=classpath:pgjsonb/indexes.xml -persistence.viewsXML=classpath:pgjsonb/views.xml - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=org.postgresql.Driver -persistence.domain[0].jdbcURL=jdbc:postgresql://localhost:5432/syncope?stringtype=unspecified -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=syncope -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDictionary -persistence.domain[0].orm=META-INF/spring-orm-pgjsonb.xml -persistence.domain[0].poolMaxActive=20 -persistence.domain[0].poolMinIdle=5 diff --git a/core/persistence-jpa-json/src/main/resources/domains/jpa-json/MasterContent.xml b/core/persistence-jpa-json/src/main/resources/domains/jpa-json/MasterContent.xml deleted file mode 100644 index 256e121b740..00000000000 --- a/core/persistence-jpa-json/src/main/resources/domains/jpa-json/MasterContent.xml +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/persistence-jpa-json/src/main/resources/persistence-enhance.xml b/core/persistence-jpa-json/src/main/resources/persistence-enhance.xml deleted file mode 100644 index 0c6e795b93c..00000000000 --- a/core/persistence-jpa-json/src/main/resources/persistence-enhance.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - META-INF/spring-orm-${orm}.xml - NONE - - - diff --git a/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizer.java b/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizer.java deleted file mode 100644 index d0d62325bb8..00000000000 --- a/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizer.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa; - -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; -import org.springframework.test.context.ContextCustomizer; -import org.springframework.test.context.MergedContextConfiguration; - -public class JPAJSONTestContextCustomizer implements ContextCustomizer { - - private static BeanDefinitionRegistry getBeanDefinitionRegistry(final ApplicationContext ctx) { - if (ctx instanceof BeanDefinitionRegistry beanDefinitionRegistry) { - return beanDefinitionRegistry; - } - if (ctx instanceof ConfigurableApplicationContext configurableApplicationContext) { - return (BeanDefinitionRegistry) configurableApplicationContext.getBeanFactory(); - } - throw new IllegalStateException("Could not locate BeanDefinitionRegistry"); - } - - @Override - public void customizeContext(final ConfigurableApplicationContext ctx, final MergedContextConfiguration cfg) { - AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(getBeanDefinitionRegistry(ctx)); - reader.registerBean(PGJPAJSONPersistenceContext.class, "PGJPAJSONPersistenceContext"); - reader.registerBean(MyJPAJSONPersistenceContext.class, "MyJPAJSONPersistenceContext"); - reader.registerBean(MaJPAJSONPersistenceContext.class, "MaJPAJSONPersistenceContext"); - reader.registerBean(OJPAJSONPersistenceContext.class, "OJPAJSONPersistenceContext"); - } -} diff --git a/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizerFactory.java b/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizerFactory.java deleted file mode 100644 index 6738f886e0a..00000000000 --- a/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizerFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa; - -import java.util.List; -import org.springframework.test.context.ContextConfigurationAttributes; -import org.springframework.test.context.ContextCustomizer; -import org.springframework.test.context.ContextCustomizerFactory; - -public class JPAJSONTestContextCustomizerFactory implements ContextCustomizerFactory { - - @Override - public ContextCustomizer createContextCustomizer( - final Class testClass, - final List configAttributes) { - - return new JPAJSONTestContextCustomizer(); - } -} diff --git a/core/persistence-jpa-json/src/test/resources/core-majson-test.properties b/core/persistence-jpa-json/src/test/resources/core-majson-test.properties deleted file mode 100644 index 9f235bece14..00000000000 --- a/core/persistence-jpa-json/src/test/resources/core-majson-test.properties +++ /dev/null @@ -1,30 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -security.adminUser=${adminUser} -security.anonymousUser=${anonymousUser} -security.jwsKey=${jwsKey} -security.secretKey=${secretKey} - -persistence.domain[0].jdbcURL=jdbc:mariadb://${DB_CONTAINER_IP}:3306/syncope?characterEncoding=UTF-8 -persistence.domain[0].poolMaxActive=10 -persistence.domain[0].poolMinIdle=2 -# keep the next two lines until https://jira.mariadb.org/browse/MDEV-27898 is fixed -persistence.domain[0].dbUsername=root -persistence.domain[0].dbPassword=password - -provisioning.connIdLocation=${syncope.connid.location} diff --git a/core/persistence-jpa-json/src/test/resources/core-myjson-test.properties b/core/persistence-jpa-json/src/test/resources/core-myjson-test.properties deleted file mode 100644 index 4bd61242286..00000000000 --- a/core/persistence-jpa-json/src/test/resources/core-myjson-test.properties +++ /dev/null @@ -1,27 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -security.adminUser=${adminUser} -security.anonymousUser=${anonymousUser} -security.jwsKey=${jwsKey} -security.secretKey=${secretKey} - -persistence.domain[0].jdbcURL=jdbc:mysql://${DB_CONTAINER_IP}:3306/syncope?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8 -persistence.domain[0].poolMaxActive=10 -persistence.domain[0].poolMinIdle=2 - -provisioning.connIdLocation=${syncope.connid.location} diff --git a/core/persistence-jpa-json/src/test/resources/core-ojson-test.properties b/core/persistence-jpa-json/src/test/resources/core-ojson-test.properties deleted file mode 100644 index 96ce2aa12da..00000000000 --- a/core/persistence-jpa-json/src/test/resources/core-ojson-test.properties +++ /dev/null @@ -1,28 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -security.adminUser=${adminUser} -security.anonymousUser=${anonymousUser} -security.jwsKey=${jwsKey} -security.secretKey=${secretKey} - -persistence.domain[0].jdbcURL=jdbc:oracle:thin:@${DB_CONTAINER_IP}:1521/XEPDB1 -#persistence.domain[0].jdbcURL=jdbc:oracle:thin:@192.168.0.176:1521/orcl -persistence.domain[0].poolMaxActive=10 -persistence.domain[0].poolMinIdle=2 - -provisioning.connIdLocation=${syncope.connid.location} diff --git a/core/persistence-jpa-json/src/test/resources/core-pgjsonb-test.properties b/core/persistence-jpa-json/src/test/resources/core-pgjsonb-test.properties deleted file mode 100644 index a7a7b9594a3..00000000000 --- a/core/persistence-jpa-json/src/test/resources/core-pgjsonb-test.properties +++ /dev/null @@ -1,27 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -security.adminUser=${adminUser} -security.anonymousUser=${anonymousUser} -security.jwsKey=${jwsKey} -security.secretKey=${secretKey} - -persistence.domain[0].jdbcURL=jdbc:postgresql://${DB_CONTAINER_IP}:5432/syncope?stringtype=unspecified -persistence.domain[0].poolMaxActive=10 -persistence.domain[0].poolMinIdle=2 - -provisioning.connIdLocation=${syncope.connid.location} diff --git a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml deleted file mode 100644 index 4b3244d4393..00000000000 --- a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml +++ /dev/null @@ -1,1016 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml index 166aa8ea421..cb0dae80fb0 100644 --- a/core/persistence-jpa/pom.xml +++ b/core/persistence-jpa/pom.xml @@ -35,6 +35,10 @@ under the License. file:${bundles.directory}/ + + org.postgresql + postgresql + ${basedir}/../.. @@ -57,13 +61,22 @@ under the License. - org.springframework.boot - spring-boot-starter-validation + ${jdbcdriver.groupId} + ${jdbcdriver.artifactId} + test + + + org.bouncycastle + bcpkix-jdk18on test - jakarta.servlet - jakarta.servlet-api + org.bouncycastle + bcprov-jdk18on + + + jakarta.servlet + jakarta.servlet-api test @@ -77,8 +90,8 @@ under the License. test - com.h2database - h2 + org.springframework.boot + spring-boot-starter-validation test @@ -87,13 +100,23 @@ under the License. test - org.bouncycastle - bcpkix-jdk18on + io.zonky.test + embedded-postgres test - org.bouncycastle - bcprov-jdk18on + org.testcontainers + mysql + test + + + org.testcontainers + mariadb + test + + + org.testcontainers + oracle-free test @@ -104,23 +127,9 @@ under the License. org.apache.openjpa openjpa-maven-plugin true - - - com.h2database - h2 - ${h2.version} - - ${project.basedir}/src/main/resources/persistence-enhance.xml org/apache/syncope/core/persistence/jpa/entity/**/*.class - org.springframework.jdbc.datasource.DriverManagerDataSource - - driverClassName=org.h2.Driver, - url=jdbc:h2:mem:syncopedb - username=sa, - password= - @@ -139,8 +148,8 @@ under the License. ${syncope.connid.location} - true classpath:core-test.properties + true @@ -167,38 +176,39 @@ under the License. - sqlgen - + mysql + - true + com.mysql + mysql-connector-j - - - clean verify - - - - org.apache.openjpa - openjpa-maven-plugin - true - - - sqlgen - process-classes - - sql - - - - - - - + - schemagen - + mariadb + + + org.mariadb.jdbc + mariadb-java-client + + + + + oracle + + com.oracle.database.jdbc + ojdbc11 + + + + + openjpa-maven-plugin + + + + sql + true @@ -210,12 +220,14 @@ under the License. org.apache.openjpa openjpa-maven-plugin true + + org.postgresql.Driver + - schemagen process-classes - schema + ${action} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/JPARuntimeDomainLoader.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/JPARuntimeDomainLoader.java index 54cd86b90da..2106c37a37e 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/JPARuntimeDomainLoader.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/JPARuntimeDomainLoader.java @@ -19,13 +19,11 @@ package org.apache.syncope.core.persistence.jpa; import org.apache.syncope.common.keymaster.client.api.DomainOps; -import org.apache.syncope.common.keymaster.client.api.model.Domain; import org.apache.syncope.common.keymaster.client.api.model.JPADomain; import org.apache.syncope.core.persistence.api.DomainHolder; import org.apache.syncope.core.persistence.api.DomainRegistry; import org.apache.syncope.core.persistence.common.RuntimeDomainLoader; import org.apache.syncope.core.persistence.jpa.spring.DomainRoutingEntityManagerFactory; -import org.apache.syncope.core.spring.security.AuthContextUtils; import org.springframework.context.ConfigurableApplicationContext; public class JPARuntimeDomainLoader extends RuntimeDomainLoader { @@ -42,9 +40,4 @@ public JPARuntimeDomainLoader( super(domainHolder, domainRegistry, domainOps, ctx); this.entityManagerFactory = entityManagerFactory; } - - @Override - protected void onAdd(final Domain domain) { - AuthContextUtils.runAsAdmin(domain.getKey(), () -> entityManagerFactory.initJPASchema()); - } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/MaJPAJSONPersistenceContext.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MariaDBPersistenceContext.java similarity index 75% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/MaJPAJSONPersistenceContext.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MariaDBPersistenceContext.java index 1e59da7977c..337d5700fdc 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/MaJPAJSONPersistenceContext.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MariaDBPersistenceContext.java @@ -26,38 +26,40 @@ import org.apache.syncope.core.persistence.api.dao.DynRealmDAO; import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; -import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.EntityFactory; -import org.apache.syncope.core.persistence.jpa.dao.MaJPAJSONAnyDAO; -import org.apache.syncope.core.persistence.jpa.dao.MaJPAJSONAnySearchDAO; +import org.apache.syncope.core.persistence.jpa.dao.AnyFinder; +import org.apache.syncope.core.persistence.jpa.dao.MariaDBAnyFinder; +import org.apache.syncope.core.persistence.jpa.dao.MariaDBJPAAnySearchDAO; +import org.apache.syncope.core.persistence.jpa.dao.repo.MariaDBPlainSchemaRepoExtImpl; import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExt; -import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExtMaJSONImpl; -import org.apache.syncope.core.persistence.jpa.entity.MaJPAJSONEntityFactory; +import org.apache.syncope.core.persistence.jpa.entity.MariaDBEntityFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; +@Configuration(proxyBeanMethods = false) @ConditionalOnClass(name = "org.mariadb.jdbc.Driver") -public class MaJPAJSONPersistenceContext extends JPAJSONPersistenceContext { +public class MariaDBPersistenceContext { - @ConditionalOnMissingBean(name = "maJPAJSONEntityFactory") + @ConditionalOnMissingBean @Bean public EntityFactory entityFactory() { - return new MaJPAJSONEntityFactory(); + return new MariaDBEntityFactory(); } - @ConditionalOnMissingBean(name = "maJPAJSONAnyDAO") + @ConditionalOnMissingBean @Bean - public JPAJSONAnyDAO anyDAO(final @Lazy PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { - return new MaJPAJSONAnyDAO(plainSchemaDAO, entityManager); + public AnyFinder anyFinder(final @Lazy PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { + return new MariaDBAnyFinder(plainSchemaDAO, entityManager); } - @ConditionalOnMissingBean(name = "maJPAJSONAnySearchDAO") + @ConditionalOnMissingBean @Bean public AnySearchDAO anySearchDAO( final @Lazy RealmSearchDAO realmSearchDAO, @@ -72,7 +74,7 @@ public AnySearchDAO anySearchDAO( final EntityManagerFactory entityManagerFactory, final EntityManager entityManager) { - return new MaJPAJSONAnySearchDAO( + return new MariaDBJPAAnySearchDAO( realmSearchDAO, dynRealmDAO, userDAO, @@ -86,13 +88,13 @@ public AnySearchDAO anySearchDAO( entityManager); } - @ConditionalOnMissingBean(name = "maJPAJSONPlainSchemaRepoExt") + @ConditionalOnMissingBean @Bean public PlainSchemaRepoExt plainSchemaRepoExt( final AnyUtilsFactory anyUtilsFactory, final @Lazy ExternalResourceDAO resourceDAO, final EntityManager entityManager) { - return new PlainSchemaRepoExtMaJSONImpl(anyUtilsFactory, resourceDAO, entityManager); + return new MariaDBPlainSchemaRepoExtImpl(anyUtilsFactory, resourceDAO, entityManager); } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/MyJPAJSONPersistenceContext.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MySQLPersistenceContext.java similarity index 75% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/MyJPAJSONPersistenceContext.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MySQLPersistenceContext.java index 3e883b1df0b..44b35dbcce7 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/MyJPAJSONPersistenceContext.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MySQLPersistenceContext.java @@ -26,38 +26,40 @@ import org.apache.syncope.core.persistence.api.dao.DynRealmDAO; import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; -import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.EntityFactory; -import org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAnyDAO; -import org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAnySearchDAO; +import org.apache.syncope.core.persistence.jpa.dao.AnyFinder; +import org.apache.syncope.core.persistence.jpa.dao.MySQLAnyFinder; +import org.apache.syncope.core.persistence.jpa.dao.MySQLJPAAnySearchDAO; +import org.apache.syncope.core.persistence.jpa.dao.repo.MySQLPlainSchemaRepoExtImpl; import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExt; -import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExtMyJSONImpl; -import org.apache.syncope.core.persistence.jpa.entity.MyJPAJSONEntityFactory; +import org.apache.syncope.core.persistence.jpa.entity.MySQLEntityFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; +@Configuration(proxyBeanMethods = false) @ConditionalOnClass(name = "com.mysql.cj.jdbc.Driver") -public class MyJPAJSONPersistenceContext extends JPAJSONPersistenceContext { +public class MySQLPersistenceContext { - @ConditionalOnMissingBean(name = "myJPAJSONEntityFactory") + @ConditionalOnMissingBean @Bean public EntityFactory entityFactory() { - return new MyJPAJSONEntityFactory(); + return new MySQLEntityFactory(); } - @ConditionalOnMissingBean(name = "myJPAJSONAnyDAO") + @ConditionalOnMissingBean @Bean - public JPAJSONAnyDAO anyDAO(final @Lazy PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { - return new MyJPAJSONAnyDAO(plainSchemaDAO, entityManager); + public AnyFinder anyFinder(final @Lazy PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { + return new MySQLAnyFinder(plainSchemaDAO, entityManager); } - @ConditionalOnMissingBean(name = "myJPAJSONAnySearchDAO") + @ConditionalOnMissingBean @Bean public AnySearchDAO anySearchDAO( final @Lazy RealmSearchDAO realmSearchDAO, @@ -72,7 +74,7 @@ public AnySearchDAO anySearchDAO( final EntityManagerFactory entityManagerFactory, final EntityManager entityManager) { - return new MyJPAJSONAnySearchDAO( + return new MySQLJPAAnySearchDAO( realmSearchDAO, dynRealmDAO, userDAO, @@ -86,13 +88,13 @@ public AnySearchDAO anySearchDAO( entityManager); } - @ConditionalOnMissingBean(name = "myJPAJSONPlainSchemaRepoExt") + @ConditionalOnMissingBean @Bean public PlainSchemaRepoExt plainSchemaRepoExt( final AnyUtilsFactory anyUtilsFactory, final @Lazy ExternalResourceDAO resourceDAO, final EntityManager entityManager) { - return new PlainSchemaRepoExtMyJSONImpl(anyUtilsFactory, resourceDAO, entityManager); + return new MySQLPlainSchemaRepoExtImpl(anyUtilsFactory, resourceDAO, entityManager); } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/OJPAJSONPersistenceContext.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/OraclePersistenceContext.java similarity index 76% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/OJPAJSONPersistenceContext.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/OraclePersistenceContext.java index 1e100c7af8f..2d4a7fa11d6 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/OJPAJSONPersistenceContext.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/OraclePersistenceContext.java @@ -26,38 +26,40 @@ import org.apache.syncope.core.persistence.api.dao.DynRealmDAO; import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; -import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.EntityFactory; -import org.apache.syncope.core.persistence.jpa.dao.OJPAJSONAnyDAO; -import org.apache.syncope.core.persistence.jpa.dao.OJPAJSONAnySearchDAO; +import org.apache.syncope.core.persistence.jpa.dao.AnyFinder; +import org.apache.syncope.core.persistence.jpa.dao.OracleAnyFinder; +import org.apache.syncope.core.persistence.jpa.dao.OracleJPAAnySearchDAO; +import org.apache.syncope.core.persistence.jpa.dao.repo.OraclePlainSchemaRepoExtImpl; import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExt; -import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExtOJSONImpl; -import org.apache.syncope.core.persistence.jpa.entity.OJPAJSONEntityFactory; +import org.apache.syncope.core.persistence.jpa.entity.OracleEntityFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; +@Configuration(proxyBeanMethods = false) @ConditionalOnClass(name = "oracle.jdbc.OracleDriver") -public class OJPAJSONPersistenceContext extends JPAJSONPersistenceContext { +public class OraclePersistenceContext { - @ConditionalOnMissingBean(name = "oJPAJSONEntityFactory") + @ConditionalOnMissingBean @Bean public EntityFactory entityFactory() { - return new OJPAJSONEntityFactory(); + return new OracleEntityFactory(); } - @ConditionalOnMissingBean(name = "oJPAJSONAnyDAO") + @ConditionalOnMissingBean @Bean - public JPAJSONAnyDAO anyDAO(final @Lazy PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { - return new OJPAJSONAnyDAO(plainSchemaDAO, entityManager); + public AnyFinder anyFinder(final @Lazy PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { + return new OracleAnyFinder(plainSchemaDAO, entityManager); } - @ConditionalOnMissingBean(name = "oJPAJSONAnySearchDAO") + @ConditionalOnMissingBean @Bean public AnySearchDAO anySearchDAO( final @Lazy RealmSearchDAO realmSearchDAO, @@ -72,7 +74,7 @@ public AnySearchDAO anySearchDAO( final EntityManagerFactory entityManagerFactory, final EntityManager entityManager) { - return new OJPAJSONAnySearchDAO( + return new OracleJPAAnySearchDAO( realmSearchDAO, dynRealmDAO, userDAO, @@ -86,13 +88,13 @@ public AnySearchDAO anySearchDAO( entityManager); } - @ConditionalOnMissingBean(name = "oJPAJSONPlainSchemaRepoExt") + @ConditionalOnMissingBean @Bean public PlainSchemaRepoExt plainSchemaRepoExt( final AnyUtilsFactory anyUtilsFactory, final @Lazy ExternalResourceDAO resourceDAO, final EntityManager entityManager) { - return new PlainSchemaRepoExtOJSONImpl(anyUtilsFactory, resourceDAO, entityManager); + return new OraclePlainSchemaRepoExtImpl(anyUtilsFactory, resourceDAO, entityManager); } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/PGJPAJSONPersistenceContext.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PGPersistenceContext.java similarity index 75% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/PGJPAJSONPersistenceContext.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PGPersistenceContext.java index e71f3bfeb24..8a4f2dfe237 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/PGJPAJSONPersistenceContext.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PGPersistenceContext.java @@ -26,38 +26,40 @@ import org.apache.syncope.core.persistence.api.dao.DynRealmDAO; import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; -import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.EntityFactory; -import org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAnyDAO; -import org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAnySearchDAO; +import org.apache.syncope.core.persistence.jpa.dao.AnyFinder; +import org.apache.syncope.core.persistence.jpa.dao.PGAnyFinder; +import org.apache.syncope.core.persistence.jpa.dao.PGJPAAnySearchDAO; +import org.apache.syncope.core.persistence.jpa.dao.repo.PGPlainSchemaRepoExtImpl; import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExt; -import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExtPGJSONImpl; -import org.apache.syncope.core.persistence.jpa.entity.PGJPAJSONEntityFactory; +import org.apache.syncope.core.persistence.jpa.entity.PGEntityFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; +@Configuration(proxyBeanMethods = false) @ConditionalOnClass(name = "org.postgresql.Driver") -public class PGJPAJSONPersistenceContext extends JPAJSONPersistenceContext { +public class PGPersistenceContext { - @ConditionalOnMissingBean(name = "pgJPAJSONEntityFactory") + @ConditionalOnMissingBean @Bean public EntityFactory entityFactory() { - return new PGJPAJSONEntityFactory(); + return new PGEntityFactory(); } - @ConditionalOnMissingBean(name = "pgJPAJSONAnyDAO") + @ConditionalOnMissingBean @Bean - public JPAJSONAnyDAO anyDAO(final @Lazy PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { - return new PGJPAJSONAnyDAO(plainSchemaDAO, entityManager); + public AnyFinder anyFinder(final @Lazy PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { + return new PGAnyFinder(plainSchemaDAO, entityManager); } - @ConditionalOnMissingBean(name = "pgJPAJSONAnySearchDAO") + @ConditionalOnMissingBean @Bean public AnySearchDAO anySearchDAO( final @Lazy RealmSearchDAO realmSearchDAO, @@ -72,7 +74,7 @@ public AnySearchDAO anySearchDAO( final EntityManagerFactory entityManagerFactory, final EntityManager entityManager) { - return new PGJPAJSONAnySearchDAO( + return new PGJPAAnySearchDAO( realmSearchDAO, dynRealmDAO, userDAO, @@ -86,13 +88,13 @@ public AnySearchDAO anySearchDAO( entityManager); } - @ConditionalOnMissingBean(name = "pgJPAJSONPlainSchemaRepoExt") + @ConditionalOnMissingBean @Bean public PlainSchemaRepoExt plainSchemaRepoExt( final AnyUtilsFactory anyUtilsFactory, final @Lazy ExternalResourceDAO resourceDAO, final EntityManager entityManager) { - return new PlainSchemaRepoExtPGJSONImpl(anyUtilsFactory, resourceDAO, entityManager); + return new PGPlainSchemaRepoExtImpl(anyUtilsFactory, resourceDAO, entityManager); } } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java index bb16860475a..82abb71e9fc 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java @@ -90,8 +90,8 @@ import org.apache.syncope.core.persistence.common.RuntimeDomainLoader; import org.apache.syncope.core.persistence.jpa.content.XMLContentExporter; import org.apache.syncope.core.persistence.jpa.content.XMLContentLoader; +import org.apache.syncope.core.persistence.jpa.dao.AnyFinder; import org.apache.syncope.core.persistence.jpa.dao.JPAAnyMatchDAO; -import org.apache.syncope.core.persistence.jpa.dao.JPAAnySearchDAO; import org.apache.syncope.core.persistence.jpa.dao.JPAAuditEventDAO; import org.apache.syncope.core.persistence.jpa.dao.JPABatchDAO; import org.apache.syncope.core.persistence.jpa.dao.JPAEntityCacheDAO; @@ -164,7 +164,6 @@ import org.apache.syncope.core.persistence.jpa.dao.repo.OIDCRPClientAppRepoExtImpl; import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepo; import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExt; -import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExtImpl; import org.apache.syncope.core.persistence.jpa.dao.repo.RelationshipTypeRepo; import org.apache.syncope.core.persistence.jpa.dao.repo.RelationshipTypeRepoExt; import org.apache.syncope.core.persistence.jpa.dao.repo.RelationshipTypeRepoExtImpl; @@ -194,7 +193,6 @@ import org.apache.syncope.core.persistence.jpa.dao.repo.VirSchemaRepoExt; import org.apache.syncope.core.persistence.jpa.dao.repo.VirSchemaRepoExtImpl; import org.apache.syncope.core.persistence.jpa.dao.repo.WAConfigRepo; -import org.apache.syncope.core.persistence.jpa.entity.JPAEntityFactory; import org.apache.syncope.core.persistence.jpa.entity.task.JPATaskUtilsFactory; import org.apache.syncope.core.persistence.jpa.spring.CommonEntityManagerFactoryConf; import org.apache.syncope.core.persistence.jpa.spring.DomainRoutingEntityManagerFactory; @@ -349,12 +347,6 @@ public StartupDomainLoader startupDomainLoader( return new StartupDomainLoader(domainOps, domainHolder, props, resourceLoader, domainRegistry); } - @ConditionalOnMissingBean - @Bean - public EntityFactory entityFactory() { - return new JPAEntityFactory(); - } - @ConditionalOnMissingBean @Bean public TaskUtilsFactory taskUtilsFactory() { @@ -412,21 +404,19 @@ public AnyMatchDAO anyMatchDAO( @Bean public AnyObjectRepoExt anyObjectRepoExt( final AnyUtilsFactory anyUtilsFactory, - final @Lazy PlainSchemaDAO plainSchemaDAO, - final @Lazy DerSchemaDAO derSchemaDAO, final @Lazy DynRealmDAO dynRealmDAO, final @Lazy UserDAO userDAO, final @Lazy GroupDAO groupDAO, - final EntityManager entityManager) { + final EntityManager entityManager, + final AnyFinder anyFinder) { return new AnyObjectRepoExtImpl( anyUtilsFactory, - plainSchemaDAO, - derSchemaDAO, dynRealmDAO, userDAO, groupDAO, - entityManager); + entityManager, + anyFinder); } @ConditionalOnMissingBean @@ -438,35 +428,6 @@ public AnyObjectDAO anyObjectDAO( return jpaRepositoryFactory.getRepository(AnyObjectRepo.class, anyObjectRepoExt); } - @ConditionalOnMissingBean - @Bean - public AnySearchDAO anySearchDAO( - final RealmSearchDAO realmSearchDAO, - final @Lazy DynRealmDAO dynRealmDAO, - final @Lazy UserDAO userDAO, - final @Lazy GroupDAO groupDAO, - final @Lazy AnyObjectDAO anyObjectDAO, - final PlainSchemaDAO schemaDAO, - final EntityFactory entityFactory, - final AnyUtilsFactory anyUtilsFactory, - final PlainAttrValidationManager validator, - final EntityManagerFactory entityManagerFactory, - final EntityManager entityManager) { - - return new JPAAnySearchDAO( - realmSearchDAO, - dynRealmDAO, - userDAO, - groupDAO, - anyObjectDAO, - schemaDAO, - entityFactory, - anyUtilsFactory, - validator, - entityManagerFactory, - entityManager); - } - @ConditionalOnMissingBean @Bean public AnyTypeClassRepoExt anyTypeClassRepoExt( @@ -701,27 +662,27 @@ public GroupRepoExt groupRepoExt( final ApplicationEventPublisher publisher, final AnyUtilsFactory anyUtilsFactory, final @Lazy PlainSchemaDAO plainSchemaDAO, - final @Lazy DerSchemaDAO derSchemaDAO, final @Lazy DynRealmDAO dynRealmDAO, final AnyMatchDAO anyMatchDAO, final @Lazy UserDAO userDAO, final @Lazy AnyObjectDAO anyObjectDAO, final AnySearchDAO anySearchDAO, final SearchCondVisitor searchCondVisitor, - final EntityManager entityManager) { + final EntityManager entityManager, + final AnyFinder anyFinder) { return new GroupRepoExtImpl( anyUtilsFactory, publisher, plainSchemaDAO, - derSchemaDAO, dynRealmDAO, anyMatchDAO, userDAO, anyObjectDAO, anySearchDAO, searchCondVisitor, - entityManager); + entityManager, + anyFinder); } @ConditionalOnMissingBean @@ -811,18 +772,8 @@ public PersistenceInfoDAO persistenceInfoDAO(final EntityManagerFactory entityMa @ConditionalOnMissingBean @Bean - public PlainAttrValueDAO plainAttrValueDAO(final EntityManager entityManager) { - return new JPAPlainAttrValueDAO(entityManager); - } - - @ConditionalOnMissingBean - @Bean - public PlainSchemaRepoExt plainSchemaRepoExt( - final AnyUtilsFactory anyUtilsFactory, - final @Lazy ExternalResourceDAO resourceDAO, - final EntityManager entityManager) { - - return new PlainSchemaRepoExtImpl(anyUtilsFactory, resourceDAO, entityManager); + public PlainAttrValueDAO plainAttrValueDAO() { + return new JPAPlainAttrValueDAO(); } @ConditionalOnMissingBean @@ -1059,20 +1010,17 @@ public TaskExecDAO taskExecDAO( public UserRepoExt userRepoExt( final SecurityProperties securityProperties, final AnyUtilsFactory anyUtilsFactory, - final @Lazy PlainSchemaDAO plainSchemaDAO, - final @Lazy DerSchemaDAO derSchemaDAO, final @Lazy DynRealmDAO dynRealmDAO, final RoleDAO roleDAO, final AccessTokenDAO accessTokenDAO, final @Lazy GroupDAO groupDAO, final DelegationDAO delegationDAO, final FIQLQueryDAO fiqlQueryDAO, - final EntityManager entityManager) { + final EntityManager entityManager, + final AnyFinder anyFinder) { return new UserRepoExtImpl( anyUtilsFactory, - plainSchemaDAO, - derSchemaDAO, dynRealmDAO, roleDAO, accessTokenDAO, @@ -1080,7 +1028,8 @@ public UserRepoExt userRepoExt( delegationDAO, fiqlQueryDAO, securityProperties, - entityManager); + entityManager, + anyFinder); } @ConditionalOnMissingBean diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceProperties.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceProperties.java index 7559dccbb1b..b20daf67f7b 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceProperties.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceProperties.java @@ -28,7 +28,7 @@ public class PersistenceProperties extends AbstractPersistenceProperties p protected final EntityManager entityManager; - public JPAAnySearchDAO( + protected AbstractJPAAnySearchDAO( final RealmSearchDAO realmSearchDAO, final DynRealmDAO dynRealmDAO, final UserDAO userDAO, diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAnyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AnyFinder.java similarity index 83% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAnyDAO.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AnyFinder.java index 55d02d15421..8b962e652bb 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAnyDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AnyFinder.java @@ -20,7 +20,6 @@ import jakarta.persistence.EntityManager; import jakarta.persistence.Query; -import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedHashMap; @@ -37,25 +36,20 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.AttrSchemaType; -import org.apache.syncope.core.persistence.api.dao.DuplicateException; -import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyUtils; import org.apache.syncope.core.persistence.api.entity.DerSchema; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.spring.security.AuthContextUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.transaction.annotation.Transactional; -abstract class AbstractJPAJSONAnyDAO implements JPAJSONAnyDAO { +public abstract class AnyFinder { - protected static final Logger LOG = LoggerFactory.getLogger(JPAJSONAnyDAO.class); + protected static final Logger LOG = LoggerFactory.getLogger(AnyFinder.class); /** * Split an attribute value recurring on provided literals/tokens. @@ -64,8 +58,8 @@ abstract class AbstractJPAJSONAnyDAO implements JPAJSONAnyDAO { * @param literals literals/tokens * @return split value */ - private static List split(final String attrValue, final List literals) { - List attrValues = new ArrayList<>(); + protected static List split(final String attrValue, final List literals) { + final List attrValues = new ArrayList<>(); if (literals.isEmpty()) { attrValues.add(attrValue); @@ -84,7 +78,7 @@ private static List split(final String attrValue, final List lit protected final EntityManager entityManager; - protected AbstractJPAJSONAnyDAO(final PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { + protected AnyFinder(final PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { this.plainSchemaDAO = plainSchemaDAO; this.entityManager = entityManager; } @@ -170,7 +164,6 @@ protected String plainAttrQuery( @SuppressWarnings("unchecked") @Transactional(readOnly = true) - @Override public > List findByPlainAttrValue( final String table, final AnyUtils anyUtils, @@ -194,7 +187,6 @@ public > List findByPlainAttrValue( } @Transactional(readOnly = true) - @Override public > Optional findByPlainAttrUniqueValue( final String table, final AnyUtils anyUtils, @@ -239,9 +231,7 @@ private List findByDerAttrValue( return query.getResultList(); } - @SuppressWarnings("unchecked") @Transactional(readOnly = true) - @Override public > List findByDerAttrValue( final String table, final AnyUtils anyUtils, @@ -341,32 +331,4 @@ public > List findByDerAttrValue( return buildResult(anyUtils, findByDerAttrValue(table, clauses)); } - - @Transactional - @Override - public > void checkBeforeSave(final String table, final AnyUtils anyUtils, final A any) { - // check UNIQUE constraints - // cannot move to functional style due to the same issue reported at - // https://medium.com/xiumeteo-labs/stream-and-concurrentmodificationexception-2d14ed8ff4b2 - for (PlainAttr attr : any.getPlainAttrs()) { - if (attr.getUniqueValue() != null && attr instanceof JSONPlainAttr) { - PlainSchema schema = attr.getSchema(); - Optional other = findByPlainAttrUniqueValue(table, anyUtils, schema, attr.getUniqueValue(), false); - if (other.isEmpty() || other.get().getKey().equals(any.getKey())) { - LOG.debug("No duplicate value found for {}", attr.getUniqueValue().getValueAsString()); - } else { - throw new DuplicateException( - "Value " + attr.getUniqueValue().getValueAsString() - + " existing for " + schema.getKey()); - } - } - } - - // update sysInfo - OffsetDateTime now = OffsetDateTime.now(); - String who = AuthContextUtils.getWho(); - LOG.debug("Set last change date '{}' and modifier '{}' for '{}'", now, who, any); - any.setLastModifier(who); - any.setLastChangeDate(now); - } } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java index 64eadac227c..d6d83fb5e5b 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java @@ -18,68 +18,17 @@ */ package org.apache.syncope.core.persistence.jpa.dao; -import jakarta.persistence.EntityManager; -import java.util.stream.Collectors; import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtils; import org.apache.syncope.core.persistence.api.entity.PlainAttr; -import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue; public class JPAPlainAttrValueDAO implements PlainAttrValueDAO { - @SuppressWarnings("unchecked") - public static Class getEntityReference( - final Class reference) { - - return AbstractPlainAttrValue.class.isAssignableFrom(reference) - ? (Class) reference - : reference.equals(GPlainAttrValue.class) - ? JPAGPlainAttrValue.class - : reference.equals(GPlainAttrUniqueValue.class) - ? JPAGPlainAttrUniqueValue.class - : reference.equals(APlainAttrValue.class) - ? JPAAPlainAttrValue.class - : reference.equals(APlainAttrUniqueValue.class) - ? JPAAPlainAttrUniqueValue.class - : reference.equals(UPlainAttrValue.class) - ? JPAUPlainAttrValue.class - : reference.equals(UPlainAttrUniqueValue.class) - ? JPAUPlainAttrUniqueValue.class - : null; - } - - protected final EntityManager entityManager; - - public JPAPlainAttrValueDAO(final EntityManager entityManager) { - this.entityManager = entityManager; - } - @Override public void deleteAll(final PlainAttr attr, final AnyUtils anyUtils) { if (attr.getUniqueValue() == null) { - attr.getValues().stream().map(PlainAttrValue::getKey).collect(Collectors.toSet()).forEach(attrValueKey -> { - PlainAttrValue attrValue = anyUtils.plainAttrValueClass().cast( - entityManager.find(getEntityReference(anyUtils.plainAttrValueClass()), attrValueKey)); - if (attrValue != null) { - entityManager.remove(attrValue); - attr.getValues().remove(attrValue); - } - }); + attr.getValues().clear(); } else { - entityManager.remove(attr.getUniqueValue()); attr.setUniqueValue(null); } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MaJPAJSONAnyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MariaDBAnyFinder.java similarity index 89% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MaJPAJSONAnyDAO.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MariaDBAnyFinder.java index feb05c38a2f..5fd194b942b 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MaJPAJSONAnyDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MariaDBAnyFinder.java @@ -27,9 +27,9 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -public class MaJPAJSONAnyDAO extends AbstractJPAJSONAnyDAO { +public class MariaDBAnyFinder extends AnyFinder { - public MaJPAJSONAnyDAO(final PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { + public MariaDBAnyFinder(final PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { super(plainSchemaDAO, entityManager); } @@ -70,9 +70,9 @@ protected String plainAttrQuery( + (schema.isUniqueConstraint() ? svs.uniqueAttr().name() : svs.attr().name()) + " WHERE schema_id = ? AND ((stringValue IS NOT NULL" + " AND " - + (ignoreCaseMatch ? "LOWER(" : "BINARY ") + "stringValue" + (ignoreCaseMatch ? ")" : "") + + (ignoreCaseMatch ? "LOWER(" : "") + "stringValue" + (ignoreCaseMatch ? ")" : "") + " = " - + (ignoreCaseMatch ? "LOWER(" : "") + "?" + (ignoreCaseMatch ? ")" : "") + ')' + + (ignoreCaseMatch ? "LOWER(" : "BINARY ") + "?" + (ignoreCaseMatch ? ")" : "") + ')' + " OR (booleanValue IS NOT NULL AND booleanValue = ?)" + " OR (dateValue IS NOT NULL AND dateValue = ?)" + " OR (longValue IS NOT NULL AND longValue = ?)" diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MaJPAJSONAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MariaDBJPAAnySearchDAO.java similarity index 96% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MaJPAJSONAnySearchDAO.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MariaDBJPAAnySearchDAO.java index d7754950bf6..135e620c912 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MaJPAJSONAnySearchDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MariaDBJPAAnySearchDAO.java @@ -35,16 +35,15 @@ import org.apache.syncope.core.persistence.api.dao.search.AttrCond; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.EntityFactory; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; -public class MaJPAJSONAnySearchDAO extends JPAAnySearchDAO { +public class MariaDBJPAAnySearchDAO extends AbstractJPAAnySearchDAO { - public MaJPAJSONAnySearchDAO( + public MariaDBJPAAnySearchDAO( final RealmSearchDAO realmSearchDAO, final DynRealmDAO dynRealmDAO, final UserDAO userDAO, @@ -111,7 +110,7 @@ protected String getQuery( if (checked.getRight() instanceof PlainAttrUniqueValue plainAttrUniqueValue) { container.setUniqueValue(plainAttrUniqueValue); } else { - ((JSONPlainAttr) container).add(checked.getRight()); + container.add(checked.getRight()); } query.append("JSON_CONTAINS(plainAttrs, '"). diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MySQLAnyFinder.java similarity index 90% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnyDAO.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MySQLAnyFinder.java index 5736eecc560..27b84981756 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnyDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MySQLAnyFinder.java @@ -23,16 +23,15 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtils; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; -public class MyJPAJSONAnyDAO extends AbstractJPAJSONAnyDAO { +public class MySQLAnyFinder extends AnyFinder { - public MyJPAJSONAnyDAO(final PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { + public MySQLAnyFinder(final PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { super(plainSchemaDAO, entityManager); } @@ -62,7 +61,7 @@ protected String attrValueMatch( if (attrValue instanceof PlainAttrUniqueValue plainAttrUniqueValue) { container.setUniqueValue(plainAttrUniqueValue); } else { - ((JSONPlainAttr) container).add(attrValue); + container.add(attrValue); } return "JSON_CONTAINS(plainAttrs, '" + POJOHelper.serialize(List.of(container)).replace("'", "''") + "')"; } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MySQLJPAAnySearchDAO.java similarity index 98% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnySearchDAO.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MySQLJPAAnySearchDAO.java index e87d7f997ff..1bc16c5f8d9 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnySearchDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MySQLJPAAnySearchDAO.java @@ -38,7 +38,6 @@ import org.apache.syncope.core.persistence.api.entity.AnyUtils; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.EntityFactory; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; @@ -46,9 +45,9 @@ import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; import org.springframework.data.domain.Sort; -public class MyJPAJSONAnySearchDAO extends JPAAnySearchDAO { +public class MySQLJPAAnySearchDAO extends AbstractJPAAnySearchDAO { - public MyJPAJSONAnySearchDAO( + public MySQLJPAAnySearchDAO( final RealmSearchDAO realmSearchDAO, final DynRealmDAO dynRealmDAO, final UserDAO userDAO, @@ -178,7 +177,7 @@ protected void fillAttrQuery( if (attrValue instanceof PlainAttrUniqueValue plainAttrUniqueValue) { container.setUniqueValue(plainAttrUniqueValue); } else { - ((JSONPlainAttr) container).add(attrValue); + container.add(attrValue); } query.append("JSON_CONTAINS(plainAttrs, '"). diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OJPAJSONAnyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OracleAnyFinder.java similarity index 94% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OJPAJSONAnyDAO.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OracleAnyFinder.java index 9a8b44b703e..31c12ed185d 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OJPAJSONAnyDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OracleAnyFinder.java @@ -28,9 +28,9 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -public class OJPAJSONAnyDAO extends AbstractJPAJSONAnyDAO { +public class OracleAnyFinder extends AnyFinder { - public OJPAJSONAnyDAO(final PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { + public OracleAnyFinder(final PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { super(plainSchemaDAO, entityManager); } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OJPAJSONAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OracleJPAAnySearchDAO.java similarity index 99% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OJPAJSONAnySearchDAO.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OracleJPAAnySearchDAO.java index 9a08ee5796d..9d6ea949ebe 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OJPAJSONAnySearchDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OracleJPAAnySearchDAO.java @@ -44,9 +44,9 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.springframework.data.domain.Sort; -public class OJPAJSONAnySearchDAO extends JPAAnySearchDAO { +public class OracleJPAAnySearchDAO extends AbstractJPAAnySearchDAO { - public OJPAJSONAnySearchDAO( + public OracleJPAAnySearchDAO( final RealmSearchDAO realmSearchDAO, final DynRealmDAO dynRealmDAO, final UserDAO userDAO, diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGAnyFinder.java similarity index 90% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGAnyFinder.java index a0d4d91e43c..afe257a819d 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGAnyFinder.java @@ -23,16 +23,15 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtils; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; -public class PGJPAJSONAnyDAO extends AbstractJPAJSONAnyDAO { +public class PGAnyFinder extends AnyFinder { - public PGJPAJSONAnyDAO(final PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { + public PGAnyFinder(final PlainSchemaDAO plainSchemaDAO, final EntityManager entityManager) { super(plainSchemaDAO, entityManager); } @@ -64,7 +63,7 @@ protected String attrValueMatch( if (attrValue instanceof PlainAttrUniqueValue plainAttrUniqueValue) { container.setUniqueValue(plainAttrUniqueValue); } else { - ((JSONPlainAttr) container).add(attrValue); + container.add(attrValue); } return "plainAttrs::jsonb @> '" + POJOHelper.serialize(List.of(container)).replace("'", "''") + "'::jsonb"; } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAAnySearchDAO.java similarity index 99% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAAnySearchDAO.java index a7b38945406..38fd7d37b7e 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAAnySearchDAO.java @@ -65,7 +65,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; -public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO { +public class PGJPAAnySearchDAO extends AbstractJPAAnySearchDAO { protected static final String ALWAYS_FALSE_ASSERTION = "1=2"; @@ -85,7 +85,7 @@ protected static String escapeIfString(final String value, final boolean isStr) : value; } - public PGJPAJSONAnySearchDAO( + public PGJPAAnySearchDAO( final RealmSearchDAO realmSearchDAO, final DynRealmDAO dynRealmDAO, final UserDAO userDAO, diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractAnyRepoExt.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractAnyRepoExt.java index 598fb62813c..b84e8cb7b23 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractAnyRepoExt.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractAnyRepoExt.java @@ -29,18 +29,12 @@ import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.regex.Pattern; import javax.sql.DataSource; -import org.apache.commons.jexl3.parser.Parser; -import org.apache.commons.jexl3.parser.ParserConstants; -import org.apache.commons.jexl3.parser.Token; -import org.apache.commons.lang3.StringUtils; import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI; import org.apache.syncope.core.persistence.api.dao.AllowedSchemas; -import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; +import org.apache.syncope.core.persistence.api.dao.DuplicateException; import org.apache.syncope.core.persistence.api.dao.DynRealmDAO; import org.apache.syncope.core.persistence.api.dao.NotFoundException; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.AnyUtils; @@ -54,6 +48,12 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.persistence.jpa.dao.AnyFinder; +import org.apache.syncope.core.persistence.jpa.entity.AbstractAttributable; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject; +import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup; +import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser; +import org.apache.syncope.core.spring.security.AuthContextUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.jdbc.core.JdbcTemplate; @@ -64,54 +64,44 @@ public abstract class AbstractAnyRepoExt> implements AnyRepoExt protected static final Logger LOG = LoggerFactory.getLogger(AnyRepoExt.class); - /** - * Split an attribute value recurring on provided literals/tokens. - * - * @param attrValue value to be split - * @param literals literals/tokens - * @return split value - */ - protected static List split(final String attrValue, final List literals) { - final List attrValues = new ArrayList<>(); - - if (literals.isEmpty()) { - attrValues.add(attrValue); - } else { - for (String token : attrValue.split(Pattern.quote(literals.get(0)))) { - if (!token.isEmpty()) { - attrValues.addAll(split(token, literals.subList(1, literals.size()))); - } - } - } - - return attrValues; - } - - protected final PlainSchemaDAO plainSchemaDAO; - - protected final DerSchemaDAO derSchemaDAO; - protected final DynRealmDAO dynRealmDAO; protected final EntityManager entityManager; + protected final AnyFinder anyFinder; + protected final AnyUtils anyUtils; + protected final String table; + protected AbstractAnyRepoExt( - final PlainSchemaDAO plainSchemaDAO, - final DerSchemaDAO derSchemaDAO, final DynRealmDAO dynRealmDAO, final EntityManager entityManager, + final AnyFinder anyFinder, final AnyUtils anyUtils) { - this.plainSchemaDAO = plainSchemaDAO; - this.derSchemaDAO = derSchemaDAO; this.dynRealmDAO = dynRealmDAO; this.entityManager = entityManager; + this.anyFinder = anyFinder; this.anyUtils = anyUtils; + switch (anyUtils.anyTypeKind()) { + case ANY_OBJECT: + table = JPAAnyObject.TABLE; + break; + + case GROUP: + table = JPAGroup.TABLE; + break; + + case USER: + default: + table = JPAUser.TABLE; + } } - protected Optional findLastChange(final String key, final String table) { + @Transactional(readOnly = true) + @Override + public Optional findLastChange(final String key) { OpenJPAEntityManagerFactorySPI emf = entityManager.getEntityManagerFactory(). unwrap(OpenJPAEntityManagerFactorySPI.class); return new JdbcTemplate((DataSource) emf.getConfiguration().getConnectionFactory()).query( @@ -149,20 +139,6 @@ public A authFind(final String key) { return any; } - private Query findByPlainAttrValueQuery(final String entityName, final boolean ignoreCaseMatch) { - String query = "SELECT e FROM " + entityName + " e" - + " WHERE e.attribute.schema.id = :schemaKey AND ((e.stringValue IS NOT NULL" - + " AND " - + (ignoreCaseMatch ? "LOWER(" : "") + "e.stringValue" + (ignoreCaseMatch ? ")" : "") - + " = " - + (ignoreCaseMatch ? "LOWER(" : "") + ":stringValue" + (ignoreCaseMatch ? ")" : "") + ')' - + " OR (e.booleanValue IS NOT NULL AND e.booleanValue = :booleanValue)" - + " OR (e.dateValue IS NOT NULL AND e.dateValue = :dateValue)" - + " OR (e.longValue IS NOT NULL AND e.longValue = :longValue)" - + " OR (e.doubleValue IS NOT NULL AND e.doubleValue = :doubleValue))"; - return entityManager.createQuery(query); - } - @Override @SuppressWarnings("unchecked") public List findByPlainAttrValue( @@ -170,32 +146,7 @@ public List findByPlainAttrValue( final PlainAttrValue attrValue, final boolean ignoreCaseMatch) { - if (schema == null) { - LOG.error("No PlainSchema"); - return List.of(); - } - - String entityName = schema.isUniqueConstraint() - ? anyUtils.plainAttrUniqueValueClass().getName() - : anyUtils.plainAttrValueClass().getName(); - Query query = findByPlainAttrValueQuery(entityName, ignoreCaseMatch); - query.setParameter("schemaKey", schema.getKey()); - query.setParameter("stringValue", attrValue.getStringValue()); - query.setParameter("booleanValue", attrValue.getBooleanValue()); - query.setParameter("dateValue", Optional.ofNullable(attrValue.getDateValue()). - map(OffsetDateTime::toInstant).orElse(null)); - query.setParameter("longValue", attrValue.getLongValue()); - query.setParameter("doubleValue", attrValue.getDoubleValue()); - - List result = new ArrayList<>(); - ((List) query.getResultList()).stream().forEach(value -> { - A any = (A) value.getAttr().getOwner(); - if (!result.contains(any)) { - result.add(any); - } - }); - - return result; + return anyFinder.findByPlainAttrValue(table, anyUtils, schema, attrValue, ignoreCaseMatch); } @Override @@ -204,171 +155,12 @@ public Optional findByPlainAttrUniqueValue( final PlainAttrUniqueValue attrUniqueValue, final boolean ignoreCaseMatch) { - if (schema == null) { - LOG.error("No PlainSchema"); - return Optional.empty(); - } - if (!schema.isUniqueConstraint()) { - LOG.error("This schema has not unique constraint: '{}'", schema.getKey()); - return Optional.empty(); - } - - List result = findByPlainAttrValue(schema, attrUniqueValue, ignoreCaseMatch); - return result.isEmpty() - ? Optional.empty() - : Optional.of(result.get(0)); - } - - private Set getWhereClause(final String expression, final String value, final boolean ignoreCaseMatch) { - Parser parser = new Parser(expression); - - // Schema keys - List identifiers = new ArrayList<>(); - - // Literals - List literals = new ArrayList<>(); - - // Get schema keys and literals - for (Token token = parser.getNextToken(); token != null && StringUtils.isNotBlank(token.toString()); - token = parser.getNextToken()) { - - if (token.kind == ParserConstants.STRING_LITERAL) { - literals.add(token.toString().substring(1, token.toString().length() - 1)); - } - - if (token.kind == ParserConstants.IDENTIFIER) { - identifiers.add(token.toString()); - } - } - - // Sort literals in order to process later literals included into others - literals.sort((l1, l2) -> { - if (l1 == null && l2 == null) { - return 0; - } else if (l1 != null && l2 == null) { - return -1; - } else if (l1 == null) { - return 1; - } else if (l1.length() == l2.length()) { - return 0; - } else if (l1.length() > l2.length()) { - return -1; - } else { - return 1; - } - }); - - // Split value on provided literals - List attrValues = split(value, literals); - - if (attrValues.size() != identifiers.size()) { - LOG.error("Ambiguous JEXL expression resolution: literals and values have different size"); - return Set.of(); - } - - // clauses to be used with INTERSECTed queries - Set clauses = new HashSet<>(); - - // builder to build the clauses - StringBuilder bld = new StringBuilder(); - - // Contains used identifiers in order to avoid replications - Set used = new HashSet<>(); - - // Create several clauses: one for each identifiers - for (int i = 0; i < identifiers.size(); i++) { - if (!used.contains(identifiers.get(i))) { - // verify schema existence and get schema type - PlainSchema schema = plainSchemaDAO.findById(identifiers.get(i)).orElse(null); - if (schema == null) { - LOG.error("Invalid schema '{}', ignoring", identifiers.get(i)); - } else { - // clear builder - bld.delete(0, bld.length()); - - bld.append('('); - - // set schema key - bld.append("s.id = '").append(identifiers.get(i)).append('\''). - append(" AND "). - append("s.id = a.schema_id"). - append(" AND "). - append("a.id = v.attribute_id"). - append(" AND "); - - // use a value clause different for each different schema type - switch (schema.getType()) { - case Boolean -> - bld.append("v.booleanValue = '").append(attrValues.get(i)).append('\''); - case Long -> - bld.append("v.longValue = ").append(attrValues.get(i)); - case Double -> - bld.append("v.doubleValue = ").append(attrValues.get(i)); - case Date -> - bld.append("v.dateValue = '").append(attrValues.get(i)).append('\''); - default -> { - if (ignoreCaseMatch) { - bld.append("LOWER(v.stringValue) = '"). - append(attrValues.get(i).toLowerCase()).append('\''); - } else { - bld.append("v.stringValue = '"). - append(attrValues.get(i)).append('\''); - } - } - } - - bld.append(')'); - - used.add(identifiers.get(i)); - - clauses.add(bld.toString()); - } - } - } - - LOG.debug("Generated where clauses {}", clauses); - - return clauses; + return anyFinder.findByPlainAttrUniqueValue(table, anyUtils, schema, attrUniqueValue, ignoreCaseMatch); } @Override - public List findByDerAttrValue(final DerSchema schema, final String value, final boolean ignoreCaseMatch) { - if (schema == null) { - LOG.error("No DerSchema"); - return List.of(); - } - - // query string - StringBuilder querystring = new StringBuilder(); - - boolean subquery = false; - for (String clause : getWhereClause(schema.getExpression(), value, ignoreCaseMatch)) { - if (querystring.length() > 0) { - subquery = true; - querystring.append(" AND a.owner_id IN ( "); - } - - querystring.append("SELECT a.owner_id "). - append("FROM ").append(anyUtils.plainAttrClass().getSimpleName().substring(3)).append(" a, "). - append(anyUtils.plainAttrValueClass().getSimpleName().substring(3)).append(" v, "). - append(PlainSchema.class.getSimpleName()).append(" s "). - append("WHERE ").append(clause); - - if (subquery) { - querystring.append(')'); - } - } - - List result = new ArrayList<>(); - if (querystring.length() > 0) { - Query query = entityManager.createNativeQuery(querystring.toString()); - - for (Object anyKey : query.getResultList()) { - findById(anyKey.toString()).filter(any -> !result.contains(any)).ifPresent(result::add); - } - } - - return result; + public List findByDerAttrValue(final DerSchema derSchema, final String value, final boolean ignoreCaseMatch) { + return anyFinder.findByDerAttrValue(table, anyUtils, derSchema, value, ignoreCaseMatch); } @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true) @@ -442,6 +234,29 @@ public List findDynRealms(final String key) { toList(); } + protected void checkBeforeSave(final A any) { + // check UNIQUE constraints + new ArrayList<>(((AbstractAttributable) any).getPlainAttrsList()).stream(). + filter(attr -> attr.getUniqueValue() != null). + forEach(attr -> { + Optional other = findByPlainAttrUniqueValue(attr.getSchema(), attr.getUniqueValue(), false); + if (other.isEmpty() || other.get().getKey().equals(any.getKey())) { + LOG.debug("No duplicate value found for {}={}", + attr.getSchema().getKey(), attr.getUniqueValue().getValueAsString()); + } else { + throw new DuplicateException("Duplicate value found for " + + attr.getSchema().getKey() + "=" + attr.getUniqueValue().getValueAsString()); + } + }); + + // update sysInfo + OffsetDateTime now = OffsetDateTime.now(); + String who = AuthContextUtils.getWho(); + LOG.debug("Set last change date '{}' and modifier '{}' for '{}'", now, who, any); + any.setLastModifier(who); + any.setLastChangeDate(now); + } + @Override public void deleteById(final String key) { findById(key).ifPresent(this::delete); diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractPlainSchemaRepoExtJSON.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractPlainSchemaRepoExt.java similarity index 58% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractPlainSchemaRepoExtJSON.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractPlainSchemaRepoExt.java index ab5a4200d9a..e71fb31d79a 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractPlainSchemaRepoExtJSON.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AbstractPlainSchemaRepoExt.java @@ -19,46 +19,73 @@ package org.apache.syncope.core.persistence.jpa.dao.repo; import jakarta.persistence.EntityManager; +import java.util.Collection; import java.util.List; +import java.util.Optional; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; +import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.Attributable; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; +import org.apache.syncope.core.persistence.jpa.entity.AbstractSchema; +import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema; -abstract class AbstractPlainSchemaRepoExtJSON extends PlainSchemaRepoExtImpl { +abstract class AbstractPlainSchemaRepoExt extends AbstractSchemaRepoExt implements PlainSchemaRepoExt { - protected AbstractPlainSchemaRepoExtJSON( + protected static > AnyTypeKind getAnyTypeKind(final Class plainAttrClass) { + if (GPlainAttr.class.isAssignableFrom(plainAttrClass)) { + return AnyTypeKind.GROUP; + } + if (APlainAttr.class.isAssignableFrom(plainAttrClass)) { + return AnyTypeKind.ANY_OBJECT; + } + + return AnyTypeKind.USER; + } + + protected final AnyUtilsFactory anyUtilsFactory; + + protected final ExternalResourceDAO resourceDAO; + + protected AbstractPlainSchemaRepoExt( final AnyUtilsFactory anyUtilsFactory, final ExternalResourceDAO resourceDAO, final EntityManager entityManager) { - super(anyUtilsFactory, resourceDAO, entityManager); + super(entityManager); + this.anyUtilsFactory = anyUtilsFactory; + this.resourceDAO = resourceDAO; } @Override - public > List findAttrs(final PlainSchema schema, final Class reference) { - // not possible - return List.of(); + public List findByAnyTypeClasses(final Collection anyTypeClasses) { + return findByAnyTypeClasses(anyTypeClasses, JPAPlainSchema.class.getSimpleName(), PlainSchema.class); } - protected > AnyTypeKind getAnyTypeKind(final Class plainAttrClass) { - if (GPlainAttr.class.isAssignableFrom(plainAttrClass)) { - return AnyTypeKind.GROUP; - } - if (APlainAttr.class.isAssignableFrom(plainAttrClass)) { - return AnyTypeKind.ANY_OBJECT; - } - - return AnyTypeKind.USER; + @Override + public PlainSchema save(final PlainSchema schema) { + ((AbstractSchema) schema).map2json(); + PlainSchema merged = entityManager.merge(schema); + ((AbstractSchema) merged).postSave(); + return merged; } @Override - protected void deleteAttrs(final PlainSchema schema) { - // nothing to do + public void deleteById(final String key) { + PlainSchema schema = entityManager.find(JPAPlainSchema.class, key); + if (schema == null) { + return; + } + + resourceDAO.deleteMapping(key); + + Optional.ofNullable(schema.getAnyTypeClass()).ifPresent(c -> c.getPlainSchemas().remove(schema)); + + entityManager.remove(schema); } @Override diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyObjectRepo.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyObjectRepo.java index 867b18d3271..e4985a57b2f 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyObjectRepo.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyObjectRepo.java @@ -18,9 +18,31 @@ */ package org.apache.syncope.core.persistence.jpa.dao.repo; +import java.util.List; +import java.util.Optional; +import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.repository.query.Param; public interface AnyObjectRepo - extends PagingAndSortingRepository, AnyObjectRepoBase, AnyObjectRepoExt { + extends PagingAndSortingRepository, AnyObjectRepoExt, AnyObjectDAO { + + @Query("SELECT e.id FROM #{#entityName} e WHERE e.type.id = :type AND e.name = :name") + @Override + Optional findKey(@Param("type") String type, @Param("name") String name); + + @Query("SELECT e FROM #{#entityName} e WHERE e.type.id = :type AND e.name = :name") + @Override + Optional findByName(@Param("type") String type, @Param("name") String name); + + @Query("SELECT e FROM #{#entityName} e WHERE e.name = :name") + @Override + List findByName(@Param("name") String name); + + @Query("SELECT e FROM #{#entityName} e WHERE e.id IN (:keys)") + @Override + List findByKeys(@Param("keys") List keys); } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyObjectRepoBase.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyObjectRepoBase.java deleted file mode 100644 index b2326adf0ff..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyObjectRepoBase.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao.repo; - -import java.util.List; -import java.util.Optional; -import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; -import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface AnyObjectRepoBase extends AnyObjectDAO { - - @Query("SELECT e.id FROM #{#entityName} e WHERE e.type.id = :type AND e.name = :name") - @Override - Optional findKey(@Param("type") String type, @Param("name") String name); - - @Query("SELECT e FROM #{#entityName} e WHERE e.type.id = :type AND e.name = :name") - @Override - Optional findByName(@Param("type") String type, @Param("name") String name); - - @Query("SELECT e FROM #{#entityName} e WHERE e.name = :name") - @Override - List findByName(@Param("name") String name); - - @Query("SELECT e FROM #{#entityName} e WHERE e.id IN (:keys)") - @Override - List findByKeys(@Param("keys") List keys); -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyObjectRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyObjectRepoExtImpl.java index be595408483..fb919cd819e 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyObjectRepoExtImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/AnyObjectRepoExtImpl.java @@ -21,7 +21,6 @@ import jakarta.persistence.EntityManager; import jakarta.persistence.Query; import jakarta.persistence.TypedQuery; -import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -36,10 +35,8 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.common.lib.types.AnyEntitlement; import org.apache.syncope.common.lib.types.AnyTypeKind; -import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; import org.apache.syncope.core.persistence.api.dao.DynRealmDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyType; @@ -52,9 +49,9 @@ import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.user.URelationship; import org.apache.syncope.core.persistence.api.utils.RealmUtils; +import org.apache.syncope.core.persistence.jpa.dao.AnyFinder; import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership; import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship; -import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject; import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.spring.security.DelegatedAdministrationException; @@ -69,29 +66,21 @@ public class AnyObjectRepoExtImpl extends AbstractAnyRepoExt implemen public AnyObjectRepoExtImpl( final AnyUtilsFactory anyUtilsFactory, - final PlainSchemaDAO plainSchemaDAO, - final DerSchemaDAO derSchemaDAO, final DynRealmDAO dynRealmDAO, final UserDAO userDAO, final GroupDAO groupDAO, - final EntityManager entityManager) { + final EntityManager entityManager, + final AnyFinder anyFinder) { super( - plainSchemaDAO, - derSchemaDAO, dynRealmDAO, entityManager, + anyFinder, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT)); this.userDAO = userDAO; this.groupDAO = groupDAO; } - @Transactional(readOnly = true) - @Override - public Optional findLastChange(final String key) { - return findLastChange(key, JPAAnyObject.TABLE); - } - @Override public Map countByType() { Query query = entityManager.createQuery( @@ -193,6 +182,9 @@ public List, AnyObject>> findAllRelationships(final AnyObjec protected Pair, Set>> doSave(final AnyObject anyObject) { AnyObject merged = entityManager.merge(anyObject); + // ensure that entity listeners are invoked at this point + entityManager.flush(); + Pair, Set> dynGroupMembs = groupDAO.refreshDynMemberships(merged); dynRealmDAO.refreshDynMemberships(merged); @@ -202,6 +194,7 @@ protected Pair, Set>> doSave(final AnyObject @Override @SuppressWarnings("unchecked") public S save(final S anyObject) { + checkBeforeSave(anyObject); return (S) doSave(anyObject).getLeft(); } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/GroupRepo.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/GroupRepo.java index 8a861809212..6540bed6b46 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/GroupRepo.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/GroupRepo.java @@ -18,9 +18,47 @@ */ package org.apache.syncope.core.persistence.jpa.dao.repo; +import java.util.List; +import java.util.Optional; +import org.apache.syncope.core.persistence.api.dao.GroupDAO; +import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.repository.query.Param; public interface GroupRepo - extends PagingAndSortingRepository, GroupRepoBase, GroupRepoExt { + extends PagingAndSortingRepository, GroupRepoExt, GroupDAO { + + @Query("SELECT e.id FROM #{#entityName} e WHERE e.name = :name") + @Override + Optional findKey(@Param("name") String name); + + @Query("SELECT e.id FROM #{#entityName} e WHERE LOWER(e.name) LIKE :pattern") + @Override + List findKeysByNamePattern(@Param("pattern") String pattern); + + @Query("SELECT e FROM #{#entityName} e WHERE e.id IN (:keys)") + @Override + List findByKeys(@Param("keys") List keys); + + @Query("SELECT e FROM #{#entityName} e WHERE e.groupOwner.id = :groupKey") + @Override + List findOwnedByGroup(@Param("groupKey") String groupKey); + + @Query("SELECT DISTINCT e.leftEnd.id FROM JPAAMembership e WHERE e.rightEnd.id = :groupKey") + @Override + List findAMembers(@Param("groupKey") String groupKey); + + @Query("SELECT DISTINCT e.leftEnd.id FROM JPAUMembership e WHERE e.rightEnd.id = :groupKey") + @Override + List findUMembers(@Param("groupKey") String groupKey); + + @Query("SELECT COUNT(DISTINCT e.leftEnd.id) FROM JPAAMembership e WHERE e.rightEnd.id = :groupKey") + @Override + long countAMembers(@Param("groupKey") String groupKey); + + @Query("SELECT COUNT(DISTINCT e.leftEnd.id) FROM JPAUMembership e WHERE e.rightEnd.id = :groupKey") + @Override + long countUMembers(@Param("groupKey") String groupKey); } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/GroupRepoBase.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/GroupRepoBase.java deleted file mode 100644 index 38d9a57f75b..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/GroupRepoBase.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao.repo; - -import java.util.List; -import java.util.Optional; -import org.apache.syncope.core.persistence.api.dao.GroupDAO; -import org.apache.syncope.core.persistence.api.entity.group.Group; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface GroupRepoBase extends GroupDAO { - - @Query("SELECT e.id FROM #{#entityName} e WHERE e.name = :name") - @Override - Optional findKey(@Param("name") String name); - - @Query("SELECT e.id FROM #{#entityName} e WHERE LOWER(e.name) LIKE :pattern") - @Override - List findKeysByNamePattern(@Param("pattern") String pattern); - - @Query("SELECT e FROM #{#entityName} e WHERE e.id IN (:keys)") - @Override - List findByKeys(@Param("keys") List keys); - - @Query("SELECT e FROM #{#entityName} e WHERE e.groupOwner.id = :groupKey") - @Override - List findOwnedByGroup(@Param("groupKey") String groupKey); - - @Query("SELECT DISTINCT e.leftEnd.id FROM JPAAMembership e WHERE e.rightEnd.id = :groupKey") - @Override - List findAMembers(@Param("groupKey") String groupKey); - - @Query("SELECT DISTINCT e.leftEnd.id FROM JPAUMembership e WHERE e.rightEnd.id = :groupKey") - @Override - List findUMembers(@Param("groupKey") String groupKey); - - @Query("SELECT COUNT(DISTINCT e.leftEnd.id) FROM JPAAMembership e WHERE e.rightEnd.id = :groupKey") - @Override - long countAMembers(@Param("groupKey") String groupKey); - - @Query("SELECT COUNT(DISTINCT e.leftEnd.id) FROM JPAUMembership e WHERE e.rightEnd.id = :groupKey") - @Override - long countUMembers(@Param("groupKey") String groupKey); -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/GroupRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/GroupRepoExtImpl.java index 3633a8264db..88b1879cd9e 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/GroupRepoExtImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/GroupRepoExtImpl.java @@ -21,13 +21,11 @@ import jakarta.persistence.EntityManager; import jakarta.persistence.Query; import jakarta.persistence.TypedQuery; -import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.lang3.tuple.Pair; @@ -37,7 +35,6 @@ import org.apache.syncope.core.persistence.api.dao.AnyMatchDAO; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; import org.apache.syncope.core.persistence.api.dao.AnySearchDAO; -import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; import org.apache.syncope.core.persistence.api.dao.DynRealmDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; @@ -59,9 +56,9 @@ import org.apache.syncope.core.persistence.api.search.SearchCondConverter; import org.apache.syncope.core.persistence.api.search.SearchCondVisitor; import org.apache.syncope.core.persistence.api.utils.RealmUtils; +import org.apache.syncope.core.persistence.jpa.dao.AnyFinder; import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership; import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership; -import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup; import org.apache.syncope.core.persistence.jpa.entity.group.JPATypeExtension; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership; @@ -77,6 +74,8 @@ public class GroupRepoExtImpl extends AbstractAnyRepoExt implements Group protected final ApplicationEventPublisher publisher; + protected final PlainSchemaDAO plainSchemaDAO; + protected final AnyMatchDAO anyMatchDAO; protected final UserDAO userDAO; @@ -91,22 +90,22 @@ public GroupRepoExtImpl( final AnyUtilsFactory anyUtilsFactory, final ApplicationEventPublisher publisher, final PlainSchemaDAO plainSchemaDAO, - final DerSchemaDAO derSchemaDAO, final DynRealmDAO dynRealmDAO, final AnyMatchDAO anyMatchDAO, final UserDAO userDAO, final AnyObjectDAO anyObjectDAO, final AnySearchDAO searchDAO, final SearchCondVisitor searchCondVisitor, - final EntityManager entityManager) { + final EntityManager entityManager, + final AnyFinder anyFinder) { super( - plainSchemaDAO, - derSchemaDAO, dynRealmDAO, entityManager, + anyFinder, anyUtilsFactory.getInstance(AnyTypeKind.GROUP)); this.publisher = publisher; + this.plainSchemaDAO = plainSchemaDAO; this.anyMatchDAO = anyMatchDAO; this.userDAO = userDAO; this.anyObjectDAO = anyObjectDAO; @@ -114,12 +113,6 @@ public GroupRepoExtImpl( this.searchCondVisitor = searchCondVisitor; } - @Transactional(readOnly = true) - @Override - public Optional findLastChange(final String key) { - return findLastChange(key, JPAGroup.TABLE); - } - @Transactional(readOnly = true) @Override public void securityChecks( @@ -233,6 +226,7 @@ public List findUMemberships(final Group group) { @Override public S save(final S group) { + checkBeforeSave(group); return entityManager.merge(group); } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtMyJSONImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/MariaDBPlainSchemaRepoExtImpl.java similarity index 94% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtMyJSONImpl.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/MariaDBPlainSchemaRepoExtImpl.java index 0065d527e7c..94a7f19d716 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtMyJSONImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/MariaDBPlainSchemaRepoExtImpl.java @@ -26,9 +26,9 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.jpa.dao.SearchSupport; -public class PlainSchemaRepoExtMyJSONImpl extends AbstractPlainSchemaRepoExtJSON { +public class MariaDBPlainSchemaRepoExtImpl extends AbstractPlainSchemaRepoExt { - public PlainSchemaRepoExtMyJSONImpl( + public MariaDBPlainSchemaRepoExtImpl( final AnyUtilsFactory anyUtilsFactory, final ExternalResourceDAO resourceDAO, final EntityManager entityManager) { diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtMaJSONImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/MySQLPlainSchemaRepoExtImpl.java similarity index 94% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtMaJSONImpl.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/MySQLPlainSchemaRepoExtImpl.java index de81c1c3878..4b45fb6c52d 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtMaJSONImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/MySQLPlainSchemaRepoExtImpl.java @@ -26,9 +26,9 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.jpa.dao.SearchSupport; -public class PlainSchemaRepoExtMaJSONImpl extends AbstractPlainSchemaRepoExtJSON { +public class MySQLPlainSchemaRepoExtImpl extends AbstractPlainSchemaRepoExt { - public PlainSchemaRepoExtMaJSONImpl( + public MySQLPlainSchemaRepoExtImpl( final AnyUtilsFactory anyUtilsFactory, final ExternalResourceDAO resourceDAO, final EntityManager entityManager) { diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtOJSONImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java similarity index 94% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtOJSONImpl.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java index 33ef30d7147..729336b27c5 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtOJSONImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/OraclePlainSchemaRepoExtImpl.java @@ -26,9 +26,9 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.jpa.dao.SearchSupport; -public class PlainSchemaRepoExtOJSONImpl extends AbstractPlainSchemaRepoExtJSON { +public class OraclePlainSchemaRepoExtImpl extends AbstractPlainSchemaRepoExt { - public PlainSchemaRepoExtOJSONImpl( + public OraclePlainSchemaRepoExtImpl( final AnyUtilsFactory anyUtilsFactory, final ExternalResourceDAO resourceDAO, final EntityManager entityManager) { diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtPGJSONImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PGPlainSchemaRepoExtImpl.java similarity index 94% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtPGJSONImpl.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PGPlainSchemaRepoExtImpl.java index c119ec3d7dc..c307c104a06 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtPGJSONImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PGPlainSchemaRepoExtImpl.java @@ -26,9 +26,9 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.jpa.dao.SearchSupport; -public class PlainSchemaRepoExtPGJSONImpl extends AbstractPlainSchemaRepoExtJSON { +public class PGPlainSchemaRepoExtImpl extends AbstractPlainSchemaRepoExt { - public PlainSchemaRepoExtPGJSONImpl( + public PGPlainSchemaRepoExtImpl( final AnyUtilsFactory anyUtilsFactory, final ExternalResourceDAO resourceDAO, final EntityManager entityManager) { diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtImpl.java deleted file mode 100644 index f791d19b9f4..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/PlainSchemaRepoExtImpl.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao.repo; - -import jakarta.persistence.EntityManager; -import jakarta.persistence.Query; -import jakarta.persistence.TypedQuery; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import org.apache.syncope.common.lib.types.AnyTypeKind; -import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; -import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; -import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; -import org.apache.syncope.core.persistence.api.entity.Attributable; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; -import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema; -import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttr; - -public class PlainSchemaRepoExtImpl extends AbstractSchemaRepoExt implements PlainSchemaRepoExt { - - protected static > String getTable(final Class plainAttrClass) { - if (GPlainAttr.class.isAssignableFrom(plainAttrClass)) { - return JPAGPlainAttr.TABLE; - } - if (APlainAttr.class.isAssignableFrom(plainAttrClass)) { - return JPAAPlainAttr.TABLE; - } - return JPAUPlainAttr.TABLE; - } - - public static > Class> getEntityReference( - final Class plainAttrClass) { - - return GPlainAttr.class.isAssignableFrom(plainAttrClass) - ? JPAGPlainAttr.class - : APlainAttr.class.isAssignableFrom(plainAttrClass) - ? JPAAPlainAttr.class - : UPlainAttr.class.isAssignableFrom(plainAttrClass) - ? JPAUPlainAttr.class - : null; - } - - protected final AnyUtilsFactory anyUtilsFactory; - - protected final ExternalResourceDAO resourceDAO; - - public PlainSchemaRepoExtImpl( - final AnyUtilsFactory anyUtilsFactory, - final ExternalResourceDAO resourceDAO, - final EntityManager entityManager) { - - super(entityManager); - this.anyUtilsFactory = anyUtilsFactory; - this.resourceDAO = resourceDAO; - } - - @Override - public List findByAnyTypeClasses(final Collection anyTypeClasses) { - return findByAnyTypeClasses(anyTypeClasses, JPAPlainSchema.class.getSimpleName(), PlainSchema.class); - } - - @Override - public > boolean hasAttrs(final PlainSchema schema, final Class reference) { - String plainAttrTable = getTable(reference); - Query query = entityManager.createNativeQuery( - "SELECT COUNT(" + plainAttrTable + ".id) FROM " + JPAPlainSchema.TABLE - + " JOIN " + plainAttrTable + " ON " + JPAPlainSchema.TABLE + ".id = " + plainAttrTable - + ".schema_id WHERE " + JPAPlainSchema.TABLE + ".id = ?1"); - query.setParameter(1, schema.getKey()); - - return ((Number) query.getSingleResult()).intValue() > 0; - } - - @Override - public PlainSchema save(final PlainSchema schema) { - ((JPAPlainSchema) schema).map2json(); - PlainSchema merged = entityManager.merge(schema); - ((JPAPlainSchema) merged).postSave(); - return merged; - } - - protected > List findAttrs(final PlainSchema schema, final Class reference) { - TypedQuery query = entityManager.createQuery( - "SELECT e FROM " + getEntityReference(reference).getSimpleName() - + " e WHERE e.schema=:schema", reference); - query.setParameter("schema", schema); - - return query.getResultList(); - } - - protected void deleteAttrs(final PlainSchema schema) { - for (AnyTypeKind anyTypeKind : AnyTypeKind.values()) { - findAttrs(schema, anyUtilsFactory.getInstance(anyTypeKind).plainAttrClass()).forEach(this::delete); - } - } - - @Override - public void deleteById(final String key) { - PlainSchema schema = entityManager.find(JPAPlainSchema.class, key); - if (schema == null) { - return; - } - - deleteAttrs(schema); - - resourceDAO.deleteMapping(key); - - Optional.ofNullable(schema.getAnyTypeClass()).ifPresent(c -> c.getPlainSchemas().remove(schema)); - - entityManager.remove(schema); - } - - @Override - @SuppressWarnings("unchecked") - public > void delete(final T plainAttr) { - if (plainAttr.getOwner() != null) { - ((Attributable) plainAttr.getOwner()).remove(plainAttr); - } - - entityManager.remove(plainAttr); - } -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/UserRepo.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/UserRepo.java index 2657743028b..968f01c0657 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/UserRepo.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/UserRepo.java @@ -18,9 +18,53 @@ */ package org.apache.syncope.core.persistence.jpa.dao.repo; +import java.util.List; +import java.util.Optional; +import org.apache.syncope.core.persistence.api.dao.UserDAO; +import org.apache.syncope.core.persistence.api.entity.ExternalResource; +import org.apache.syncope.core.persistence.api.entity.Privilege; +import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; +import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.repository.query.Param; public interface UserRepo - extends PagingAndSortingRepository, UserRepoBase, UserRepoExt { + extends PagingAndSortingRepository, UserRepoExt, UserDAO { + + @Query("SELECT e.id FROM #{#entityName} e WHERE e.username = :username") + @Override + Optional findKey(@Param("username") String username); + + @Query("SELECT e.username FROM #{#entityName} e WHERE e.id = :key") + @Override + Optional findUsername(@Param("key") String key); + + @Query("SELECT e FROM #{#entityName} e WHERE e.token LIKE :token") + @Override + Optional findByToken(@Param("token") String token); + + @Query("SELECT e FROM #{#entityName} e WHERE e.id IN (:keys)") + @Override + List findByKeys(@Param("keys") List keys); + + @Query("SELECT e FROM JPALinkedAccount e " + + "WHERE e.resource = :resource AND e.connObjectKeyValue = :connObjectKeyValue") + @Override + Optional findLinkedAccount( + @Param("resource") ExternalResource resource, + @Param("connObjectKeyValue") String connObjectKeyValue); + + @Query("SELECT e FROM JPALinkedAccount e WHERE e.owner.id = :userKey") + @Override + List findLinkedAccounts(@Param("userKey") String userKey); + + @Query("SELECT e FROM JPALinkedAccount e WHERE :privilege MEMBER OF e.privileges") + @Override + List findLinkedAccountsByPrivilege(@Param("privilege") Privilege privilege); + + @Query("SELECT e FROM JPALinkedAccount e WHERE e.resource = :resource") + @Override + List findLinkedAccountsByResource(@Param("resource") ExternalResource resource); } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/UserRepoBase.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/UserRepoBase.java deleted file mode 100644 index 91eb8d8359a..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/UserRepoBase.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.dao.repo; - -import java.util.List; -import java.util.Optional; -import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.entity.ExternalResource; -import org.apache.syncope.core.persistence.api.entity.Privilege; -import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; -import org.apache.syncope.core.persistence.api.entity.user.User; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface UserRepoBase extends UserDAO { - - @Query("SELECT e.id FROM #{#entityName} e WHERE e.username = :username") - @Override - Optional findKey(@Param("username") String username); - - @Query("SELECT e.username FROM #{#entityName} e WHERE e.id = :key") - @Override - Optional findUsername(@Param("key") String key); - - @Query("SELECT e FROM #{#entityName} e WHERE e.token LIKE :token") - @Override - Optional findByToken(@Param("token") String token); - - @Query("SELECT e FROM #{#entityName} e WHERE e.id IN (:keys)") - @Override - List findByKeys(@Param("keys") List keys); - - @Query("SELECT e FROM JPALinkedAccount e " - + "WHERE e.resource = :resource AND e.connObjectKeyValue = :connObjectKeyValue") - @Override - Optional findLinkedAccount( - @Param("resource") ExternalResource resource, - @Param("connObjectKeyValue") String connObjectKeyValue); - - @Query("SELECT e FROM JPALinkedAccount e WHERE e.owner.id = :userKey") - @Override - List findLinkedAccounts(@Param("userKey") String userKey); - - @Query("SELECT e FROM JPALinkedAccount e WHERE :privilege MEMBER OF e.privileges") - @Override - List findLinkedAccountsByPrivilege(@Param("privilege") Privilege privilege); - - @Query("SELECT e FROM JPALinkedAccount e WHERE e.resource = :resource") - @Override - List findLinkedAccountsByResource(@Param("resource") ExternalResource resource); -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/UserRepoExtImpl.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/UserRepoExtImpl.java index 512ed1615b3..3903f3551dd 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/UserRepoExtImpl.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/repo/UserRepoExtImpl.java @@ -20,7 +20,6 @@ import jakarta.persistence.EntityManager; import jakarta.persistence.Query; -import java.time.OffsetDateTime; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -34,11 +33,9 @@ import org.apache.syncope.common.lib.types.IdRepoEntitlement; import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO; import org.apache.syncope.core.persistence.api.dao.DelegationDAO; -import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO; import org.apache.syncope.core.persistence.api.dao.DynRealmDAO; import org.apache.syncope.core.persistence.api.dao.FIQLQueryDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.RoleDAO; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.ExternalResource; @@ -48,9 +45,9 @@ import org.apache.syncope.core.persistence.api.entity.user.UMembership; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.api.utils.RealmUtils; +import org.apache.syncope.core.persistence.jpa.dao.AnyFinder; import org.apache.syncope.core.persistence.jpa.entity.user.JPALinkedAccount; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.spring.security.DelegatedAdministrationException; import org.apache.syncope.core.spring.security.SecurityProperties; @@ -73,8 +70,6 @@ public class UserRepoExtImpl extends AbstractAnyRepoExt implements UserRep public UserRepoExtImpl( final AnyUtilsFactory anyUtilsFactory, - final PlainSchemaDAO plainSchemaDAO, - final DerSchemaDAO derSchemaDAO, final DynRealmDAO dynRealmDAO, final RoleDAO roleDAO, final AccessTokenDAO accessTokenDAO, @@ -82,13 +77,13 @@ public UserRepoExtImpl( final DelegationDAO delegationDAO, final FIQLQueryDAO fiqlQueryDAO, final SecurityProperties securityProperties, - final EntityManager entityManager) { + final EntityManager entityManager, + final AnyFinder anyFinder) { super( - plainSchemaDAO, - derSchemaDAO, dynRealmDAO, entityManager, + anyFinder, anyUtilsFactory.getInstance(AnyTypeKind.USER)); this.roleDAO = roleDAO; this.accessTokenDAO = accessTokenDAO; @@ -98,12 +93,6 @@ public UserRepoExtImpl( this.securityProperties = securityProperties; } - @Transactional(readOnly = true) - @Override - public Optional findLastChange(final String key) { - return findLastChange(key, JPAUser.TABLE); - } - @Override public Map countByRealm() { Query query = entityManager.createQuery( @@ -182,7 +171,12 @@ public void deleteMembership(final UMembership membership) { } protected Pair, Set>> doSave(final User user) { + entityManager.flush(); User merged = entityManager.merge(user); + + // ensure that entity listeners are invoked at this point + entityManager.flush(); + roleDAO.refreshDynMemberships(merged); Pair, Set> dynGroupMembs = groupDAO.refreshDynMemberships(merged); dynRealmDAO.refreshDynMemberships(merged); @@ -193,11 +187,13 @@ protected Pair, Set>> doSave(final User user) { @Override @SuppressWarnings("unchecked") public S save(final S user) { + checkBeforeSave(user); return (S) doSave(user).getLeft(); } @Override public Pair, Set> saveAndGetDynGroupMembs(final User user) { + checkBeforeSave(user); return doSave(user).getRight(); } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java index ba4f98f0a1f..1a5bb040554 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java @@ -30,7 +30,7 @@ @AnyCheck @MappedSuperclass -public abstract class AbstractAny

> extends AbstractGeneratedKeyEntity implements Any

{ +public abstract class AbstractAny

> extends AbstractAttributable

implements Any

{ private static final long serialVersionUID = -2666540708092702810L; diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jAttributable.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java similarity index 59% rename from core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jAttributable.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java index b4b2832dc06..1f89e06eeef 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jAttributable.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java @@ -16,13 +16,23 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.syncope.core.persistence.neo4j.entity; +package org.apache.syncope.core.persistence.jpa.entity; import java.util.List; -import org.apache.syncope.core.persistence.api.entity.Any; +import org.apache.syncope.core.persistence.api.entity.Attributable; import org.apache.syncope.core.persistence.api.entity.PlainAttr; +import org.apache.syncope.core.persistence.common.validation.AttributableCheck; -public interface Neo4jAttributable> { +@AttributableCheck +public abstract class AbstractAttributable

> + extends AbstractGeneratedKeyEntity + implements Attributable

{ - List> getPlainAttrs(); + private static final long serialVersionUID = -2072949733409392882L; + + public abstract List getPlainAttrsList(); + + public abstract String getPlainAttrsJSON(); + + public abstract void setPlainAttrsJSON(String plainAttrs); } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java similarity index 92% rename from core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java index 6b376e9c28a..9ec154eeb6a 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntityFactory.java @@ -18,7 +18,6 @@ */ package org.apache.syncope.core.persistence.jpa.entity; -import org.apache.syncope.core.persistence.api.dao.AnySearchDAO; import org.apache.syncope.core.persistence.api.entity.AccessToken; import org.apache.syncope.core.persistence.api.entity.AnyAbout; import org.apache.syncope.core.persistence.api.entity.AnyTemplateRealm; @@ -120,16 +119,16 @@ import org.apache.syncope.core.persistence.jpa.entity.am.JPAWAConfigEntry; import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership; import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership; -import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship; import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject; -import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrValue; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JSONAPlainAttr; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JSONAPlainAttrUniqueValue; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JSONAPlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup; import org.apache.syncope.core.persistence.jpa.entity.group.JPATypeExtension; +import org.apache.syncope.core.persistence.jpa.entity.group.JSONGPlainAttr; +import org.apache.syncope.core.persistence.jpa.entity.group.JSONGPlainAttrUniqueValue; +import org.apache.syncope.core.persistence.jpa.entity.group.JSONGPlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.keymaster.JPAConfParam; import org.apache.syncope.core.persistence.jpa.entity.keymaster.JPADomain; import org.apache.syncope.core.persistence.jpa.entity.keymaster.JPANetworkService; @@ -153,21 +152,21 @@ import org.apache.syncope.core.persistence.jpa.entity.task.JPAPullTask; import org.apache.syncope.core.persistence.jpa.entity.task.JPAPushTask; import org.apache.syncope.core.persistence.jpa.entity.task.JPASchedTask; -import org.apache.syncope.core.persistence.jpa.entity.user.JPALAPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.user.JPALAPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.user.JPALAPlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.user.JPALinkedAccount; import org.apache.syncope.core.persistence.jpa.entity.user.JPASecurityQuestion; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser; +import org.apache.syncope.core.persistence.jpa.entity.user.JSONLAPlainAttr; +import org.apache.syncope.core.persistence.jpa.entity.user.JSONLAPlainAttrUniqueValue; +import org.apache.syncope.core.persistence.jpa.entity.user.JSONLAPlainAttrValue; +import org.apache.syncope.core.persistence.jpa.entity.user.JSONUPlainAttr; +import org.apache.syncope.core.persistence.jpa.entity.user.JSONUPlainAttrUniqueValue; +import org.apache.syncope.core.persistence.jpa.entity.user.JSONUPlainAttrValue; import org.apache.syncope.core.spring.security.SecureRandomUtils; -public class JPAEntityFactory implements EntityFactory { +abstract class AbstractEntityFactory implements EntityFactory { @SuppressWarnings("unchecked") @Override @@ -239,33 +238,33 @@ public E newEntity(final Class reference) { } else if (reference.equals(PlainSchema.class)) { result = (E) new JPAPlainSchema(); } else if (reference.equals(APlainAttr.class)) { - result = (E) new JPAAPlainAttr(); + result = (E) new JSONAPlainAttr(); } else if (reference.equals(APlainAttrValue.class)) { - result = (E) new JPAAPlainAttrValue(); + result = (E) new JSONAPlainAttrValue(); } else if (reference.equals(APlainAttrUniqueValue.class)) { - result = (E) new JPAAPlainAttrUniqueValue(); + result = (E) new JSONAPlainAttrUniqueValue(); } else if (reference.equals(UPlainAttr.class)) { - result = (E) new JPAUPlainAttr(); + result = (E) new JSONUPlainAttr(); } else if (reference.equals(UPlainAttrValue.class)) { - result = (E) new JPAUPlainAttrValue(); + result = (E) new JSONUPlainAttrValue(); } else if (reference.equals(UPlainAttrUniqueValue.class)) { - result = (E) new JPAUPlainAttrUniqueValue(); + result = (E) new JSONUPlainAttrUniqueValue(); } else if (reference.equals(LAPlainAttr.class)) { - result = (E) new JPALAPlainAttr(); + result = (E) new JSONLAPlainAttr(); } else if (reference.equals(LAPlainAttrValue.class)) { - result = (E) new JPALAPlainAttrValue(); + result = (E) new JSONLAPlainAttrValue(); } else if (reference.equals(LAPlainAttrUniqueValue.class)) { - result = (E) new JPALAPlainAttrUniqueValue(); + result = (E) new JSONLAPlainAttrUniqueValue(); } else if (reference.equals(DerSchema.class)) { result = (E) new JPADerSchema(); } else if (reference.equals(VirSchema.class)) { result = (E) new JPAVirSchema(); } else if (reference.equals(GPlainAttr.class)) { - result = (E) new JPAGPlainAttr(); + result = (E) new JSONGPlainAttr(); } else if (reference.equals(GPlainAttrValue.class)) { - result = (E) new JPAGPlainAttrValue(); + result = (E) new JSONGPlainAttrValue(); } else if (reference.equals(GPlainAttrUniqueValue.class)) { - result = (E) new JPAGPlainAttrUniqueValue(); + result = (E) new JSONGPlainAttrUniqueValue(); } else if (reference.equals(Report.class)) { result = (E) new JPAReport(); } else if (reference.equals(ReportExec.class)) { @@ -373,9 +372,4 @@ public Class groupClass() { public Class anyObjectClass() { return JPAAnyObject.class; } - - @Override - public Class anySearchDAOClass() { - return null; - } } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGroupableRelatable.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGroupableRelatable.java index 52ccde84e6b..b6c501305b2 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGroupableRelatable.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGroupableRelatable.java @@ -38,70 +38,61 @@ public abstract class AbstractGroupableRelatable< private static final long serialVersionUID = -2269285197388729673L; - protected abstract List internalGetPlainAttrs(); - @Override - public boolean remove(final P attr) { - return internalGetPlainAttrs().remove(attr); + public List getPlainAttrs() { + return getPlainAttrsList().stream(). + filter(attr -> attr.getMembershipKey() == null). + toList(); } @Override public Optional getPlainAttr(final String plainSchema) { - return internalGetPlainAttrs().stream(). - filter(attr -> attr != null && attr.getSchema() != null && attr.getMembership() == null - && plainSchema.equals(attr.getSchema().getKey())). + return getPlainAttrsList().stream(). + filter(attr -> attr.getMembershipKey() == null + && plainSchema.equals(attr.getSchemaKey())). findFirst(); } @Override public Optional getPlainAttr(final String plainSchema, final Membership membership) { - return internalGetPlainAttrs().stream(). - filter(attr -> attr != null && attr.getSchema() != null - && attr.getMembership() != null && attr.getMembership().equals(membership) - && plainSchema.equals(attr.getSchema().getKey())). + return getPlainAttrsList().stream(). + filter(attr -> plainSchema.equals(attr.getSchemaKey()) + && membership.getKey().equals(attr.getMembershipKey())). findFirst(); } - @Override - public List getPlainAttrs() { - return internalGetPlainAttrs().stream(). - filter(attr -> attr != null && attr.getSchema() != null && attr.getMembership() == null). - toList(); - } - @Override public Collection getPlainAttrs(final String plainSchema) { - return internalGetPlainAttrs().stream(). - filter(attr -> attr != null && attr.getSchema() != null - && plainSchema.equals(attr.getSchema().getKey())). + return getPlainAttrsList().stream(). + filter(attr -> plainSchema.equals(attr.getSchemaKey())). toList(); } @Override public Collection getPlainAttrs(final Membership membership) { - return internalGetPlainAttrs().stream(). - filter(attr -> attr != null && attr.getSchema() != null && membership.equals(attr.getMembership())). + return getPlainAttrsList().stream(). + filter(attr -> membership.getKey().equals(attr.getMembershipKey())). toList(); } @Override public Optional getMembership(final String groupKey) { return getMemberships().stream(). - filter(membership -> groupKey != null && groupKey.equals(membership.getRightEnd().getKey())). + filter(membership -> groupKey.equals(membership.getRightEnd().getKey())). findFirst(); } @Override public Collection getRelationships(final RelationshipType relationshipType) { return getRelationships().stream(). - filter(relationship -> relationshipType != null && relationshipType.equals(relationship.getType())). + filter(relationship -> relationshipType.equals(relationship.getType())). toList(); } @Override public Collection getRelationships(final String otherEndKey) { return getRelationships().stream(). - filter(relationship -> otherEndKey != null && otherEndKey.equals(relationship.getRightEnd().getKey())). + filter(relationship -> otherEndKey.equals(relationship.getRightEnd().getKey())). toList(); } } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java index aa13cff0116..a710cc6e408 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java @@ -18,46 +18,79 @@ */ package org.apache.syncope.core.persistence.jpa.entity; -import jakarta.persistence.Column; -import jakarta.persistence.FetchType; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.MappedSuperclass; +import com.fasterxml.jackson.annotation.JsonGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; import jakarta.validation.constraints.NotNull; import java.util.Collections; import java.util.List; +import java.util.Optional; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager; +import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyUtils; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.common.validation.PlainAttrCheck; +import org.apache.syncope.core.spring.ApplicationContextProvider; -@MappedSuperclass -@PlainAttrCheck -public abstract class AbstractPlainAttr> extends AbstractGeneratedKeyEntity implements PlainAttr { +@JsonIgnoreProperties("valuesAsStrings") +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public abstract class AbstractPlainAttr> implements PlainAttr { private static final long serialVersionUID = -9115431608821806124L; + @JsonProperty("schema") @NotNull - @ManyToOne(fetch = FetchType.EAGER) - @Column(name = "schema_id") - protected JPAPlainSchema schema; + private String schemaKey; + @JsonIgnore + @Override + public String getKey() { + return null; + } + + @JsonGetter("schema") + @Override + public String getSchemaKey() { + return schemaKey; + } + + @JsonIgnore @Override public JPAPlainSchema getSchema() { - return schema; + return Optional.ofNullable(schemaKey). + flatMap(s -> ApplicationContextProvider.getBeanFactory().getBean(PlainSchemaDAO.class).findById(s)). + map(JPAPlainSchema.class::cast). + orElse(null); } + @JsonIgnore @Override public void setSchema(final PlainSchema schema) { - checkType(schema, JPAPlainSchema.class); - this.schema = (JPAPlainSchema) schema; + if (schema != null) { + this.schemaKey = schema.getKey(); + } + } + + @JsonSetter("schema") + public void setSchema(final String schemaKey) { + this.schemaKey = schemaKey; } protected abstract boolean addForMultiValue(PlainAttrValue attrValue); + @Override + public void add(final PlainAttrValue attrValue) { + addForMultiValue(attrValue); + } + private void checkNonNullSchema() { if (getSchema() == null) { throw new IllegalStateException("First set owner then schema and finally add values"); @@ -107,4 +140,29 @@ public List getValuesAsStrings() { return Collections.unmodifiableList(result); } + + @Override + public int hashCode() { + return new HashCodeBuilder(). + append(schemaKey). + build(); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + @SuppressWarnings("unchecked") + final AbstractPlainAttr other = (AbstractPlainAttr) obj; + return new EqualsBuilder(). + append(schemaKey, other.schemaKey). + build(); + } } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java index 0e61a7ee929..d7930046e0d 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java @@ -18,8 +18,9 @@ */ package org.apache.syncope.core.persistence.jpa.entity; -import jakarta.persistence.Lob; -import jakarta.persistence.MappedSuperclass; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import java.time.OffsetDateTime; import java.util.Base64; import java.util.Optional; @@ -33,16 +34,19 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.utils.FormatUtils; -import org.apache.syncope.core.persistence.common.validation.PlainAttrValueCheck; import org.apache.syncope.core.spring.ApplicationContextProvider; import org.apache.syncope.core.spring.security.Encryptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -@MappedSuperclass -@PlainAttrValueCheck -public abstract class AbstractPlainAttrValue extends AbstractGeneratedKeyEntity implements PlainAttrValue { +@JsonIgnoreProperties({ "valueAsString", "value" }) +@JsonInclude(JsonInclude.Include.NON_NULL) +public abstract class AbstractPlainAttrValue implements PlainAttrValue { private static final long serialVersionUID = -9141923816611244785L; + protected static final Logger LOG = LoggerFactory.getLogger(PlainAttrValue.class); + private static final Pattern SPRING_ENV_PROPERTY = Pattern.compile("^\\$\\{.*\\}$"); private String stringValue; @@ -55,9 +59,14 @@ public abstract class AbstractPlainAttrValue extends AbstractGeneratedKeyEntity private Double doubleValue; - @Lob private byte[] binaryValue; + @JsonIgnore + @Override + public String getKey() { + return null; + } + @Override public Boolean getBooleanValue() { return booleanValue; diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAJSONEntityListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JSONEntityListener.java similarity index 74% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAJSONEntityListener.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JSONEntityListener.java index 305e9d87723..23ab71351a7 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAJSONEntityListener.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JSONEntityListener.java @@ -21,20 +21,19 @@ import java.util.List; import java.util.Optional; import org.apache.syncope.core.persistence.api.entity.Any; -import org.apache.syncope.core.persistence.api.entity.JSONAttributable; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; +import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; -public abstract class JPAJSONEntityListener> { +public abstract class JSONEntityListener, P extends PlainAttr> { - protected abstract List> getAttrs(String plainAttrsJSON); + protected abstract List getAttrs(String plainAttrsJSON); @SuppressWarnings("unchecked") - protected void json2list(final JSONAttributable entity, final boolean clearFirst) { + protected void json2list(final AbstractAttributable

entity, final boolean clearFirst) { if (clearFirst) { - entity.getPlainAttrList().clear(); + entity.getPlainAttrsList().clear(); } if (entity.getPlainAttrsJSON() != null) { getAttrs(entity.getPlainAttrsJSON()).stream().filter(attr -> attr.getSchema() != null).map(attr -> { @@ -47,13 +46,13 @@ protected void json2list(final JSONAttributable entity, final boolean clearFi attr.getValues().forEach(value -> value.setAttr(attr)); Optional.ofNullable(attr.getUniqueValue()).ifPresent(value -> value.setAttr(attr)); return attr; - }).forEach(entity::add); + }).forEach(attr -> entity.add(attr)); } } - protected void list2json(final JSONAttributable entity) { - entity.setPlainAttrsJSON(entity.getPlainAttrList().isEmpty() + protected void list2json(final AbstractAttributable

entity) { + entity.setPlainAttrsJSON(entity.getPlainAttrsList().isEmpty() ? "[]" - : POJOHelper.serialize(entity.getPlainAttrList())); + : POJOHelper.serialize(entity.getPlainAttrsList())); } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MaJPAJSONEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MariaDBEntityFactory.java similarity index 84% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MaJPAJSONEntityFactory.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MariaDBEntityFactory.java index c509826cf38..d0a8ccd82d3 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MaJPAJSONEntityFactory.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MariaDBEntityFactory.java @@ -19,12 +19,12 @@ package org.apache.syncope.core.persistence.jpa.entity; import org.apache.syncope.core.persistence.api.dao.AnySearchDAO; -import org.apache.syncope.core.persistence.jpa.dao.MaJPAJSONAnySearchDAO; +import org.apache.syncope.core.persistence.jpa.dao.MariaDBJPAAnySearchDAO; -public class MaJPAJSONEntityFactory extends JPAJSONEntityFactory { +public class MariaDBEntityFactory extends AbstractEntityFactory { @Override public Class anySearchDAOClass() { - return MaJPAJSONAnySearchDAO.class; + return MariaDBJPAAnySearchDAO.class; } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/OJPAJSONEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MySQLEntityFactory.java similarity index 85% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/OJPAJSONEntityFactory.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MySQLEntityFactory.java index 0b35c119320..d63807b9567 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/OJPAJSONEntityFactory.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MySQLEntityFactory.java @@ -19,12 +19,12 @@ package org.apache.syncope.core.persistence.jpa.entity; import org.apache.syncope.core.persistence.api.dao.AnySearchDAO; -import org.apache.syncope.core.persistence.jpa.dao.OJPAJSONAnySearchDAO; +import org.apache.syncope.core.persistence.jpa.dao.MySQLJPAAnySearchDAO; -public class OJPAJSONEntityFactory extends JPAJSONEntityFactory { +public class MySQLEntityFactory extends AbstractEntityFactory { @Override public Class anySearchDAOClass() { - return OJPAJSONAnySearchDAO.class; + return MySQLJPAAnySearchDAO.class; } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MyJPAJSONEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/OracleEntityFactory.java similarity index 85% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MyJPAJSONEntityFactory.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/OracleEntityFactory.java index 3429d477d65..49856e923ce 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MyJPAJSONEntityFactory.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/OracleEntityFactory.java @@ -19,12 +19,12 @@ package org.apache.syncope.core.persistence.jpa.entity; import org.apache.syncope.core.persistence.api.dao.AnySearchDAO; -import org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAnySearchDAO; +import org.apache.syncope.core.persistence.jpa.dao.OracleJPAAnySearchDAO; -public class MyJPAJSONEntityFactory extends JPAJSONEntityFactory { +public class OracleEntityFactory extends AbstractEntityFactory { @Override public Class anySearchDAOClass() { - return MyJPAJSONAnySearchDAO.class; + return OracleJPAAnySearchDAO.class; } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/PGJPAJSONEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/PGEntityFactory.java similarity index 84% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/PGJPAJSONEntityFactory.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/PGEntityFactory.java index 9da2e9eb197..917d5815687 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/PGJPAJSONEntityFactory.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/PGEntityFactory.java @@ -19,12 +19,12 @@ package org.apache.syncope.core.persistence.jpa.entity; import org.apache.syncope.core.persistence.api.dao.AnySearchDAO; -import org.apache.syncope.core.persistence.jpa.dao.PGJPAJSONAnySearchDAO; +import org.apache.syncope.core.persistence.jpa.dao.PGJPAAnySearchDAO; -public class PGJPAJSONEntityFactory extends JPAJSONEntityFactory { +public class PGEntityFactory extends AbstractEntityFactory { @Override public Class anySearchDAOClass() { - return PGJPAJSONAnySearchDAO.class; + return PGJPAAnySearchDAO.class; } } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADynGroupMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADynGroupMembership.java index 18d30d28c24..83857fcf3ef 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADynGroupMembership.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAADynGroupMembership.java @@ -20,6 +20,7 @@ import jakarta.persistence.Entity; import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToOne; import jakarta.persistence.Table; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership; @@ -37,7 +38,8 @@ public class JPAADynGroupMembership extends AbstractDynMembership imp public static final String TABLE = "ADynGroupMembership"; - private Group group; + @OneToOne + private JPAGroup group; @ManyToOne private JPAAnyType anyType; diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAMembership.java index 1caaf7022e1..2f9c15e9c89 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAMembership.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAMembership.java @@ -18,7 +18,9 @@ */ package org.apache.syncope.core.persistence.jpa.entity.anyobject; +import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import org.apache.syncope.core.persistence.api.entity.MembershipType; import org.apache.syncope.core.persistence.api.entity.RelationshipType; @@ -36,9 +38,13 @@ public class JPAAMembership extends AbstractGeneratedKeyEntity implements AMembe public static final String TABLE = "AMembership"; - private AnyObject leftEnd; + @ManyToOne + @Column(name = "anyObject_id") + private JPAAnyObject leftEnd; - private Group rightEnd; + @ManyToOne + @Column(name = "group_id") + private JPAGroup rightEnd; @Override public MembershipType getType() { diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java deleted file mode 100644 index 1e55ee4dfae..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttr.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.anyobject; - -import jakarta.persistence.CascadeType; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToMany; -import jakarta.persistence.OneToOne; -import jakarta.persistence.Table; -import jakarta.validation.Valid; -import java.util.ArrayList; -import java.util.List; -import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; -import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; -import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr; - -@Entity -@Table(name = JPAAPlainAttr.TABLE) -public class JPAAPlainAttr extends AbstractPlainAttr implements APlainAttr { - - private static final long serialVersionUID = 8066058729580952116L; - - public static final String TABLE = "APlainAttr"; - - @ManyToOne(fetch = FetchType.EAGER) - private JPAAnyObject owner; - - /** - * The membership of this attribute; might be {@code NULL} if this attribute is not related to a membership. - */ - @ManyToOne(fetch = FetchType.EAGER) - private JPAAMembership membership; - - @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, orphanRemoval = true, mappedBy = "attribute") - @Valid - private List values = new ArrayList<>(); - - @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "attribute") - @Valid - private JPAAPlainAttrUniqueValue uniqueValue; - - @Override - public AnyObject getOwner() { - return owner; - } - - @Override - public void setOwner(final AnyObject owner) { - checkType(owner, JPAAnyObject.class); - this.owner = (JPAAnyObject) owner; - } - - @Override - public AMembership getMembership() { - return membership; - } - - @Override - public void setMembership(final AMembership membership) { - checkType(membership, JPAAMembership.class); - this.membership = (JPAAMembership) membership; - } - - @Override - protected boolean addForMultiValue(final PlainAttrValue attrValue) { - checkType(attrValue, JPAAPlainAttrValue.class); - return values.add((JPAAPlainAttrValue) attrValue); - } - - @Override - public List getValues() { - return values; - } - - @Override - public APlainAttrUniqueValue getUniqueValue() { - return uniqueValue; - } - - @Override - public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) { - checkType(uniqueValue, JPAAPlainAttrUniqueValue.class); - this.uniqueValue = (JPAAPlainAttrUniqueValue) uniqueValue; - } -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttrUniqueValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttrUniqueValue.java deleted file mode 100644 index 4ab111890cd..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttrUniqueValue.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.anyobject; - -import jakarta.persistence.Entity; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToOne; -import jakarta.persistence.Table; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; -import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; -import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema; - -@Entity -@Table(name = JPAAPlainAttrUniqueValue.TABLE) -public class JPAAPlainAttrUniqueValue extends AbstractPlainAttrValue implements APlainAttrUniqueValue { - - private static final long serialVersionUID = -6412206895091662679L; - - public static final String TABLE = "APlainAttrUniqueValue"; - - @OneToOne(optional = false) - private JPAAPlainAttr attribute; - - @ManyToOne(optional = false) - @JoinColumn(name = "schema_id") - private JPAPlainSchema schema; - - @Override - public APlainAttr getAttr() { - return attribute; - } - - @Override - public void setAttr(final PlainAttr attr) { - checkType(attr, JPAAPlainAttr.class); - this.attribute = (JPAAPlainAttr) attr; - } - - @Override - public PlainSchema getSchema() { - return schema; - } - - @Override - public void setSchema(final PlainSchema schema) { - checkType(schema, JPAPlainSchema.class); - this.schema = (JPAPlainSchema) schema; - } -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttrValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttrValue.java deleted file mode 100644 index 6f979456959..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAPlainAttrValue.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.anyobject; - -import jakarta.persistence.Entity; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import jakarta.validation.constraints.NotNull; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; -import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; -import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; - -@Entity -@Table(name = JPAAPlainAttrValue.TABLE) -public class JPAAPlainAttrValue extends AbstractPlainAttrValue implements APlainAttrValue { - - private static final long serialVersionUID = -2965487882824889272L; - - public static final String TABLE = "APlainAttrValue"; - - @ManyToOne - @NotNull - private JPAAPlainAttr attribute; - - @Override - public APlainAttr getAttr() { - return attribute; - } - - @Override - public void setAttr(final PlainAttr attr) { - checkType(attr, JPAAPlainAttr.class); - this.attribute = (JPAAPlainAttr) attr; - } -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAARelationship.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAARelationship.java index e0dbf1bd41d..ca4baa6a690 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAARelationship.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAARelationship.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.core.persistence.jpa.entity.anyobject; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.ManyToOne; @@ -42,9 +43,13 @@ public class JPAARelationship extends AbstractGeneratedKeyEntity implements ARel @ManyToOne(fetch = FetchType.EAGER, optional = false) private JPARelationshipType type; - private AnyObject leftEnd; + @ManyToOne + @Column(name = "left_anyObject_id") + private JPAAnyObject leftEnd; - private AnyObject rightEnd; + @ManyToOne + @Column(name = "right_anyObject_id") + private JPAAnyObject rightEnd; @Override public RelationshipType getType() { diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java index f3ed177cd33..2f187611c14 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java @@ -21,6 +21,7 @@ import jakarta.persistence.Cacheable; import jakarta.persistence.CascadeType; import jakarta.persistence.Entity; +import jakarta.persistence.EntityListeners; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.JoinTable; @@ -28,11 +29,13 @@ import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; +import jakarta.persistence.Transient; import jakarta.persistence.UniqueConstraint; import jakarta.validation.Valid; import jakarta.validation.constraints.Size; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; @@ -51,6 +54,7 @@ @Entity @Table(name = JPAAnyObject.TABLE, uniqueConstraints = @UniqueConstraint(columnNames = { "name", "type_id" })) +@EntityListeners({ JSONAnyObjectListener.class }) @Cacheable @AnyObjectCheck public class JPAAnyObject @@ -67,9 +71,10 @@ public class JPAAnyObject @ManyToOne(fetch = FetchType.EAGER, optional = false) private JPAAnyType type; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner") - @Valid - private List plainAttrs = new ArrayList<>(); + private String plainAttrs; + + @Transient + private final List plainAttrsList = new ArrayList<>(); @ManyToMany(fetch = FetchType.EAGER) @JoinTable(joinColumns = @@ -130,16 +135,33 @@ public List getResources() { } @Override - public boolean add(final APlainAttr attr) { - checkType(attr, JPAAPlainAttr.class); - return plainAttrs.add((JPAAPlainAttr) attr); + public List getPlainAttrsList() { + return plainAttrsList; } @Override - protected List internalGetPlainAttrs() { + public String getPlainAttrsJSON() { return plainAttrs; } + @Override + public void setPlainAttrsJSON(final String plainAttrs) { + this.plainAttrs = plainAttrs; + } + + @Override + public boolean add(final APlainAttr attr) { + checkType(attr, JSONAPlainAttr.class); + return plainAttrsList.add((JSONAPlainAttr) attr); + } + + @Override + public boolean remove(final APlainAttr attr) { + checkType(attr, JSONAPlainAttr.class); + return plainAttrsList.removeIf(jsonAttr -> jsonAttr.getSchemaKey().equals(attr.getSchema().getKey()) + && Objects.equals(jsonAttr.getMembershipKey(), attr.getMembershipKey())); + } + @Override public boolean add(final AnyTypeClass auxClass) { checkType(auxClass, JPAAnyTypeClass.class); @@ -181,6 +203,8 @@ public boolean add(final AMembership membership) { @Override public boolean remove(final AMembership membership) { checkType(membership, JPAAMembership.class); + plainAttrsList.removeIf(attr -> attr.getMembershipKey() != null + && attr.getMembershipKey().equals(membership.getKey())); return this.memberships.remove((JPAAMembership) membership); } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JSONAPlainAttr.java similarity index 59% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAPlainAttr.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JSONAPlainAttr.java index 356af7a2d88..be42f7e3934 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAPlainAttr.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JSONAPlainAttr.java @@ -18,9 +18,8 @@ */ package org.apache.syncope.core.persistence.jpa.entity.anyobject; +import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSetter; import java.util.ArrayList; @@ -29,33 +28,21 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema; import org.apache.syncope.core.spring.ApplicationContextProvider; -@JsonIgnoreProperties("valuesAsStrings") -@JsonInclude(JsonInclude.Include.NON_EMPTY) -public class JPAJSONAPlainAttr extends AbstractPlainAttr implements APlainAttr, JSONPlainAttr { +public class JSONAPlainAttr extends AbstractPlainAttr implements APlainAttr { - private static final long serialVersionUID = 806271775349587902L; + private static final long serialVersionUID = 8066058729580952116L; - /** - * The owner of this attribute. - */ @JsonIgnore - private JPAJSONAnyObject owner; - - @JsonProperty - private String schema; + private JPAAnyObject owner; /** * The membership of this attribute; might be {@code NULL} if this attribute is not related to a membership. @@ -63,16 +50,10 @@ public class JPAJSONAPlainAttr extends AbstractPlainAttr implements A @JsonProperty private String membership; - /** - * Values of this attribute (if schema is not UNIQUE). - */ - private final List values = new ArrayList<>(); + private List values = new ArrayList<>(); - /** - * Value of this attribute (if schema is UNIQUE). - */ @JsonProperty - private JPAJSONAPlainAttrUniqueValue uniqueValue; + private JSONAPlainAttrUniqueValue uniqueValue; @Override public AnyObject getOwner() { @@ -81,55 +62,26 @@ public AnyObject getOwner() { @Override public void setOwner(final AnyObject owner) { - checkType(owner, JPAJSONAnyObject.class); - this.owner = (JPAJSONAnyObject) owner; + this.owner = (JPAAnyObject) owner; } @JsonIgnore @Override - public String getSchemaKey() { - return schema; + public AMembership getMembership() { + return ApplicationContextProvider.getBeanFactory().getBean(AnyObjectDAO.class).findMembership(membership); } - @JsonIgnore @Override - public JPAPlainSchema getSchema() { - return Optional.ofNullable(schema). - flatMap(s -> ApplicationContextProvider.getBeanFactory().getBean(PlainSchemaDAO.class).findById(s)). - map(JPAPlainSchema.class::cast). - orElse(null); + public void setMembership(final AMembership membership) { + this.membership = Optional.ofNullable(membership).map(AMembership::getKey).orElse(null); } + @JsonGetter("membership") @Override - public void setSchema(final PlainSchema schema) { - if (schema != null) { - this.schema = schema.getKey(); - } - } - - @JsonSetter("schema") - public void setSchema(final String schema) { - this.schema = schema; - } - - @JsonIgnore public String getMembershipKey() { return membership; } - @JsonIgnore - @Override - public AMembership getMembership() { - return ApplicationContextProvider.getBeanFactory().getBean(AnyObjectDAO.class).findMembership(membership); - } - - @Override - public void setMembership(final AMembership membership) { - if (membership != null) { - this.membership = membership.getKey(); - } - } - @JsonSetter("membership") public void setMembership(final String membership) { this.membership = membership; @@ -137,13 +89,7 @@ public void setMembership(final String membership) { @Override protected boolean addForMultiValue(final PlainAttrValue attrValue) { - checkType(attrValue, JPAJSONAPlainAttrValue.class); - return values.add((JPAJSONAPlainAttrValue) attrValue); - } - - @Override - public boolean add(final PlainAttrValue value) { - return addForMultiValue(value); + return values.add((JSONAPlainAttrValue) attrValue); } @Override @@ -151,27 +97,21 @@ public List getValues() { return values; } - @JsonIgnore - public List getPGValues() { - return values; - } - @Override - public JPAJSONAPlainAttrUniqueValue getUniqueValue() { + public JSONAPlainAttrUniqueValue getUniqueValue() { return uniqueValue; } @JsonIgnore @Override public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) { - checkType(uniqueValue, JPAJSONAPlainAttrUniqueValue.class); - this.uniqueValue = (JPAJSONAPlainAttrUniqueValue) uniqueValue; + this.uniqueValue = (JSONAPlainAttrUniqueValue) uniqueValue; } @Override public int hashCode() { return new HashCodeBuilder(). - append(schema). + appendSuper(super.hashCode()). append(membership). append(values). append(uniqueValue). @@ -189,9 +129,9 @@ public boolean equals(final Object obj) { if (getClass() != obj.getClass()) { return false; } - final JPAJSONAPlainAttr other = (JPAJSONAPlainAttr) obj; + final JSONAPlainAttr other = (JSONAPlainAttr) obj; return new EqualsBuilder(). - append(schema, other.schema). + appendSuper(super.equals(obj)). append(membership, other.membership). append(values, other.values). append(uniqueValue, other.uniqueValue). diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAPlainAttrUniqueValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JSONAPlainAttrUniqueValue.java similarity index 76% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAPlainAttrUniqueValue.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JSONAPlainAttrUniqueValue.java index cd8247eef2f..e67cf269484 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAPlainAttrUniqueValue.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JSONAPlainAttrUniqueValue.java @@ -19,22 +19,18 @@ package org.apache.syncope.core.persistence.jpa.entity.anyobject; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrUniqueValue; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; -@JsonIgnoreProperties({ "valueAsString", "value" }) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class JPAJSONAPlainAttrUniqueValue extends AbstractPlainAttrValue implements APlainAttrUniqueValue { +public class JSONAPlainAttrUniqueValue extends AbstractPlainAttrValue implements APlainAttrUniqueValue { - private static final long serialVersionUID = -4053996864791245312L; + private static final long serialVersionUID = 4681561795607192855L; @JsonIgnore - private JPAJSONAPlainAttr attr; + private JSONAPlainAttr attr; @Override public APlainAttr getAttr() { @@ -43,8 +39,7 @@ public APlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, JPAJSONAPlainAttr.class); - this.attr = (JPAJSONAPlainAttr) attr; + this.attr = (JSONAPlainAttr) attr; } @JsonIgnore diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAPlainAttrValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JSONAPlainAttrValue.java similarity index 73% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAPlainAttrValue.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JSONAPlainAttrValue.java index d4815d305c0..bdb458064cf 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAPlainAttrValue.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JSONAPlainAttrValue.java @@ -19,21 +19,19 @@ package org.apache.syncope.core.persistence.jpa.entity.anyobject; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; +import jakarta.validation.constraints.NotNull; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; -@JsonIgnoreProperties({ "valueAsString", "value" }) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class JPAJSONAPlainAttrValue extends AbstractPlainAttrValue implements APlainAttrValue { +public class JSONAPlainAttrValue extends AbstractPlainAttrValue implements APlainAttrValue { - private static final long serialVersionUID = 1832825176101443555L; + private static final long serialVersionUID = -766808291128424707L; @JsonIgnore - private JPAJSONAPlainAttr attr; + @NotNull + private JSONAPlainAttr attr; @Override public APlainAttr getAttr() { @@ -42,7 +40,6 @@ public APlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, JPAJSONAPlainAttr.class); - this.attr = (JPAJSONAPlainAttr) attr; + this.attr = (JSONAPlainAttr) attr; } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAnyObjectListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JSONAnyObjectListener.java similarity index 71% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAnyObjectListener.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JSONAnyObjectListener.java index c66f43dc5e4..5f46a9effac 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAJSONAnyObjectListener.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JSONAnyObjectListener.java @@ -25,36 +25,36 @@ import jakarta.persistence.PrePersist; import jakarta.persistence.PreUpdate; import java.util.List; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; +import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; -import org.apache.syncope.core.persistence.jpa.entity.JPAJSONEntityListener; +import org.apache.syncope.core.persistence.jpa.entity.JSONEntityListener; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; -public class JPAJSONAnyObjectListener extends JPAJSONEntityListener { +public class JSONAnyObjectListener extends JSONEntityListener { - protected static final TypeReference> TYPEREF = - new TypeReference>() { + protected static final TypeReference> TYPEREF = + new TypeReference>() { }; @Override - protected List> getAttrs(final String plainAttrsJSON) { + protected List getAttrs(final String plainAttrsJSON) { return POJOHelper.deserialize(plainAttrsJSON, TYPEREF); } @PostLoad - public void read(final JPAJSONAnyObject anyObject) { + public void read(final JPAAnyObject anyObject) { super.json2list(anyObject, false); } @PrePersist @PreUpdate - public void save(final JPAJSONAnyObject anyObject) { + public void save(final JPAAnyObject anyObject) { super.list2json(anyObject); } @PostPersist @PostUpdate - public void readAfterSave(final JPAJSONAnyObject anyObject) { + public void readAfterSave(final JPAAnyObject anyObject) { super.json2list(anyObject, true); } } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrUniqueValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrUniqueValue.java deleted file mode 100644 index a0087dffccd..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrUniqueValue.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.group; - -import jakarta.persistence.Entity; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToOne; -import jakarta.persistence.Table; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; -import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema; - -@Entity -@Table(name = JPAGPlainAttrUniqueValue.TABLE) -public class JPAGPlainAttrUniqueValue extends AbstractPlainAttrValue implements GPlainAttrUniqueValue { - - private static final long serialVersionUID = 4681561795607192855L; - - public static final String TABLE = "GPlainAttrUniqueValue"; - - @OneToOne(optional = false) - private JPAGPlainAttr attribute; - - @ManyToOne(optional = false) - @JoinColumn(name = "schema_id") - private JPAPlainSchema schema; - - @Override - public GPlainAttr getAttr() { - return attribute; - } - - @Override - public void setAttr(final PlainAttr attr) { - checkType(attr, JPAGPlainAttr.class); - this.attribute = (JPAGPlainAttr) attr; - } - - @Override - public PlainSchema getSchema() { - return schema; - } - - @Override - public void setSchema(final PlainSchema schema) { - checkType(schema, JPAPlainSchema.class); - this.schema = (JPAPlainSchema) schema; - } -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrValue.java deleted file mode 100644 index 52bc20d6ace..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttrValue.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.group; - -import jakarta.persistence.Entity; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import jakarta.validation.constraints.NotNull; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; - -@Entity -@Table(name = JPAGPlainAttrValue.TABLE) -public class JPAGPlainAttrValue extends AbstractPlainAttrValue implements GPlainAttrValue { - - private static final long serialVersionUID = -766808291128424707L; - - public static final String TABLE = "GPlainAttrValue"; - - @ManyToOne - @NotNull - private JPAGPlainAttr attribute; - - @Override - public GPlainAttr getAttr() { - return attribute; - } - - @Override - public void setAttr(final PlainAttr attr) { - checkType(attr, JPAGPlainAttr.class); - this.attribute = (JPAGPlainAttr) attr; - } -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java index 5541dd4c123..76a2b79f7ed 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java @@ -22,13 +22,16 @@ import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EntityListeners; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.JoinTable; import jakarta.persistence.ManyToMany; +import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.OneToOne; import jakarta.persistence.Table; +import jakarta.persistence.Transient; import jakarta.persistence.UniqueConstraint; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -56,6 +59,7 @@ @Entity @Table(name = JPAGroup.TABLE) +@EntityListeners({ JSONGroupListener.class }) @Cacheable @GroupCheck public class JPAGroup extends AbstractAny implements Group { @@ -68,13 +72,16 @@ public class JPAGroup extends AbstractAny implements Group { @NotNull private String name; - protected User userOwner; + @ManyToOne + private JPAUser userOwner; - protected Group groupOwner; + @ManyToOne + private JPAGroup groupOwner; - @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "owner") - @Valid - private List plainAttrs = new ArrayList<>(); + private String plainAttrs; + + @Transient + private final List plainAttrsList = new ArrayList<>(); @ManyToMany(fetch = FetchType.LAZY) @JoinTable(joinColumns = @@ -157,28 +164,43 @@ public void setGroupOwner(final Group group) { this.groupOwner = (JPAGroup) group; } + @Override + public List getPlainAttrsList() { + return plainAttrsList; + } + + @Override + public String getPlainAttrsJSON() { + return plainAttrs; + } + + @Override + public void setPlainAttrsJSON(final String plainAttrs) { + this.plainAttrs = plainAttrs; + } + @Override public boolean add(final GPlainAttr attr) { - checkType(attr, JPAGPlainAttr.class); - return plainAttrs.add((JPAGPlainAttr) attr); + checkType(attr, JSONGPlainAttr.class); + return plainAttrsList.add((JSONGPlainAttr) attr); } @Override public boolean remove(final GPlainAttr attr) { - checkType(attr, JPAGPlainAttr.class); - return getPlainAttrs().remove((JPAGPlainAttr) attr); + checkType(attr, JSONGPlainAttr.class); + return plainAttrsList.removeIf(a -> a.getSchemaKey().equals(attr.getSchema().getKey())); } @Override public Optional getPlainAttr(final String plainSchema) { - return getPlainAttrs().stream(). - filter(plainAttr -> plainAttr != null && plainAttr.getSchema() != null - && plainSchema.equals(plainAttr.getSchema().getKey())).findFirst(); + return plainAttrsList.stream(). + filter(attr -> plainSchema.equals(attr.getSchemaKey())). + findFirst(); } @Override public List getPlainAttrs() { - return plainAttrs; + return plainAttrsList.stream().toList(); } @Override diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java index ffce5f8a2f9..fbdc2da7d2b 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPATypeExtension.java @@ -45,7 +45,8 @@ public class JPATypeExtension extends AbstractGeneratedKeyEntity implements Type public static final String TABLE = "TypeExtension"; - private Group group; + @ManyToOne + private JPAGroup group; @ManyToOne private JPAAnyType anyType; @@ -55,7 +56,8 @@ public class JPATypeExtension extends AbstractGeneratedKeyEntity implements Type @JoinColumn(name = "typeExtension_id"), inverseJoinColumns = @JoinColumn(name = "anyTypeClass_id"), - uniqueConstraints = @UniqueConstraint(columnNames = { "typeExtension_id", "anyTypeClass_id" })) + uniqueConstraints = + @UniqueConstraint(columnNames = { "typeExtension_id", "anyTypeClass_id" })) private List auxClasses = new ArrayList<>(); @Override diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JSONGPlainAttr.java similarity index 55% rename from core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JSONGPlainAttr.java index 1b3c7aeb76d..bf29de77a9f 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGPlainAttr.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JSONGPlainAttr.java @@ -18,42 +18,36 @@ */ package org.apache.syncope.core.persistence.jpa.entity.group; -import jakarta.persistence.CascadeType; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToMany; -import jakarta.persistence.OneToOne; -import jakarta.persistence.Table; -import jakarta.validation.Valid; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr; -@Entity -@Table(name = JPAGPlainAttr.TABLE) -public class JPAGPlainAttr extends AbstractPlainAttr implements GPlainAttr { +public class JSONGPlainAttr extends AbstractPlainAttr implements GPlainAttr { private static final long serialVersionUID = 2848159565890995780L; - public static final String TABLE = "GPlainAttr"; - - @ManyToOne(fetch = FetchType.EAGER) + @JsonIgnore private JPAGroup owner; - @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, orphanRemoval = true, mappedBy = "attribute") - @Valid - private List values = new ArrayList<>(); + /** + * Values of this attribute (if schema is not UNIQUE). + */ + private final List values = new ArrayList<>(); - @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "attribute") - @Valid - private JPAGPlainAttrUniqueValue uniqueValue; + /** + * Value of this attribute (if schema is UNIQUE). + */ + @JsonProperty + private JSONGPlainAttrUniqueValue uniqueValue; @Override public Group getOwner() { @@ -62,14 +56,12 @@ public Group getOwner() { @Override public void setOwner(final Group owner) { - checkType(owner, JPAGroup.class); this.owner = (JPAGroup) owner; } @Override protected boolean addForMultiValue(final PlainAttrValue attrValue) { - checkType(attrValue, JPAGPlainAttrValue.class); - return values.add((JPAGPlainAttrValue) attrValue); + return values.add((JSONGPlainAttrValue) attrValue); } @Override @@ -78,13 +70,41 @@ public List getValues() { } @Override - public GPlainAttrUniqueValue getUniqueValue() { + public JSONGPlainAttrUniqueValue getUniqueValue() { return uniqueValue; } + @JsonIgnore @Override public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) { - checkType(uniqueValue, JPAGPlainAttrUniqueValue.class); - this.uniqueValue = (JPAGPlainAttrUniqueValue) uniqueValue; + this.uniqueValue = (JSONGPlainAttrUniqueValue) uniqueValue; + } + + @Override + public int hashCode() { + return new HashCodeBuilder(). + appendSuper(super.hashCode()). + append(values). + append(uniqueValue). + build(); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final JSONGPlainAttr other = (JSONGPlainAttr) obj; + return new EqualsBuilder(). + appendSuper(super.equals(obj)). + append(values, other.values). + append(uniqueValue, other.uniqueValue). + build(); } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGPlainAttrUniqueValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JSONGPlainAttrUniqueValue.java similarity index 76% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGPlainAttrUniqueValue.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JSONGPlainAttrUniqueValue.java index 539e8fb85b1..a8894024005 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGPlainAttrUniqueValue.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JSONGPlainAttrUniqueValue.java @@ -19,22 +19,18 @@ package org.apache.syncope.core.persistence.jpa.entity.group; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrUniqueValue; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; -@JsonIgnoreProperties({ "valueAsString", "value" }) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class JPAJSONGPlainAttrUniqueValue extends AbstractPlainAttrValue implements GPlainAttrUniqueValue { +public class JSONGPlainAttrUniqueValue extends AbstractPlainAttrValue implements GPlainAttrUniqueValue { - private static final long serialVersionUID = -4326417972859745823L; + private static final long serialVersionUID = 4681561795607192855L; @JsonIgnore - private JPAJSONGPlainAttr attr; + private JSONGPlainAttr attr; @Override public GPlainAttr getAttr() { @@ -43,8 +39,7 @@ public GPlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, JPAJSONGPlainAttr.class); - this.attr = (JPAJSONGPlainAttr) attr; + this.attr = (JSONGPlainAttr) attr; } @JsonIgnore diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGPlainAttrValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JSONGPlainAttrValue.java similarity index 73% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGPlainAttrValue.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JSONGPlainAttrValue.java index e662117e2b8..67b1d2a3d18 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGPlainAttrValue.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JSONGPlainAttrValue.java @@ -19,21 +19,17 @@ package org.apache.syncope.core.persistence.jpa.entity.group; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; -@JsonIgnoreProperties({ "valueAsString", "value" }) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class JPAJSONGPlainAttrValue extends AbstractPlainAttrValue implements GPlainAttrValue { +public class JSONGPlainAttrValue extends AbstractPlainAttrValue implements GPlainAttrValue { - private static final long serialVersionUID = 1832825176101443555L; + private static final long serialVersionUID = -766808291128424707L; @JsonIgnore - private JPAJSONGPlainAttr attr; + private JSONGPlainAttr attr; @Override public GPlainAttr getAttr() { @@ -42,7 +38,6 @@ public GPlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, JPAJSONGPlainAttr.class); - this.attr = (JPAJSONGPlainAttr) attr; + this.attr = (JSONGPlainAttr) attr; } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGroupListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JSONGroupListener.java similarity index 72% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGroupListener.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JSONGroupListener.java index 104697a68d1..f3e19d228fa 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAJSONGroupListener.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JSONGroupListener.java @@ -25,36 +25,36 @@ import jakarta.persistence.PrePersist; import jakarta.persistence.PreUpdate; import java.util.List; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; +import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; import org.apache.syncope.core.persistence.api.entity.group.Group; -import org.apache.syncope.core.persistence.jpa.entity.JPAJSONEntityListener; +import org.apache.syncope.core.persistence.jpa.entity.JSONEntityListener; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; -public class JPAJSONGroupListener extends JPAJSONEntityListener { +public class JSONGroupListener extends JSONEntityListener { - protected static final TypeReference> TYPEREF = - new TypeReference>() { + protected static final TypeReference> TYPEREF = + new TypeReference>() { }; @Override - protected List> getAttrs(final String plainAttrsJSON) { + protected List getAttrs(final String plainAttrsJSON) { return POJOHelper.deserialize(plainAttrsJSON, TYPEREF); } @PostLoad - public void read(final JPAJSONGroup group) { + public void read(final JPAGroup group) { super.json2list(group, false); } @PrePersist @PreUpdate - public void save(final JPAJSONGroup group) { + public void save(final JPAGroup group) { super.list2json(group); } @PostPersist @PostUpdate - public void readAfterSave(final JPAJSONGroup group) { + public void readAfterSave(final JPAGroup group) { super.json2list(group, true); } } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALAPlainAttrUniqueValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALAPlainAttrUniqueValue.java deleted file mode 100644 index 50ef6583d73..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALAPlainAttrUniqueValue.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.user; - -import jakarta.persistence.Entity; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToOne; -import jakarta.persistence.Table; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; -import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema; - -@Entity -@Table(name = JPALAPlainAttrUniqueValue.TABLE) -public class JPALAPlainAttrUniqueValue extends AbstractPlainAttrValue implements LAPlainAttrUniqueValue { - - private static final long serialVersionUID = 1200617357906733442L; - - public static final String TABLE = "LAPlainAttrUniqueValue"; - - @OneToOne(optional = false) - private JPALAPlainAttr attribute; - - @ManyToOne(optional = false) - @JoinColumn(name = "schema_id") - private JPAPlainSchema schema; - - @Override - public LAPlainAttr getAttr() { - return attribute; - } - - @Override - public void setAttr(final PlainAttr attr) { - checkType(attr, JPALAPlainAttr.class); - this.attribute = (JPALAPlainAttr) attr; - } - - @Override - public PlainSchema getSchema() { - return schema; - } - - @Override - public void setSchema(final PlainSchema schema) { - checkType(schema, JPAPlainSchema.class); - this.schema = (JPAPlainSchema) schema; - } -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALAPlainAttrValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALAPlainAttrValue.java deleted file mode 100644 index dcda659a1e0..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALAPlainAttrValue.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.user; - -import jakarta.persistence.Entity; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import jakarta.validation.constraints.NotNull; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; - -@Entity -@Table(name = JPALAPlainAttrValue.TABLE) -public class JPALAPlainAttrValue extends AbstractPlainAttrValue implements LAPlainAttrValue { - - private static final long serialVersionUID = 6237793413044604262L; - - public static final String TABLE = "LAPlainAttrValue"; - - @ManyToOne - @NotNull - private JPALAPlainAttr attribute; - - @Override - public LAPlainAttr getAttr() { - return attribute; - } - - @Override - public void setAttr(final PlainAttr attr) { - checkType(attr, JPALAPlainAttr.class); - this.attribute = (JPALAPlainAttr) attr; - } -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALinkedAccount.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALinkedAccount.java index 25d93d67ef6..b22afe2c916 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALinkedAccount.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALinkedAccount.java @@ -18,9 +18,9 @@ */ package org.apache.syncope.core.persistence.jpa.entity.user; -import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EntityListeners; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; @@ -28,8 +28,8 @@ import jakarta.persistence.JoinTable; import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToMany; import jakarta.persistence.Table; +import jakarta.persistence.Transient; import jakarta.persistence.UniqueConstraint; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -45,7 +45,7 @@ import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; import org.apache.syncope.core.persistence.api.entity.user.User; -import org.apache.syncope.core.persistence.jpa.entity.AbstractGeneratedKeyEntity; +import org.apache.syncope.core.persistence.jpa.entity.AbstractAttributable; import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource; import org.apache.syncope.core.persistence.jpa.entity.JPAPrivilege; import org.apache.syncope.core.spring.ApplicationContextProvider; @@ -55,7 +55,8 @@ @Entity @Table(name = JPALinkedAccount.TABLE, uniqueConstraints = @UniqueConstraint(columnNames = { "connObjectKeyValue", "resource_id" })) -public class JPALinkedAccount extends AbstractGeneratedKeyEntity implements LinkedAccount { +@EntityListeners({ JSONLinkedAccountListener.class }) +public class JPALinkedAccount extends AbstractAttributable implements LinkedAccount { private static final long serialVersionUID = -5141654998687601522L; @@ -82,9 +83,10 @@ public class JPALinkedAccount extends AbstractGeneratedKeyEntity implements Link private Boolean suspended = false; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "account") - @Valid - private List plainAttrs = new ArrayList<>(); + private String plainAttrs; + + @Transient + private final List plainAttrsList = new ArrayList<>(); @ManyToMany(fetch = FetchType.EAGER) @JoinTable(joinColumns = @@ -192,28 +194,43 @@ public Boolean isSuspended() { return suspended; } + @Override + public List getPlainAttrsList() { + return plainAttrsList; + } + + @Override + public String getPlainAttrsJSON() { + return plainAttrs; + } + + @Override + public void setPlainAttrsJSON(final String plainAttrs) { + this.plainAttrs = plainAttrs; + } + @Override public boolean add(final LAPlainAttr attr) { - checkType(attr, JPALAPlainAttr.class); - return plainAttrs.add((JPALAPlainAttr) attr); + checkType(attr, JSONLAPlainAttr.class); + return plainAttrsList.add((JSONLAPlainAttr) attr); } @Override public boolean remove(final LAPlainAttr attr) { - checkType(attr, JPALAPlainAttr.class); - return plainAttrs.remove((JPALAPlainAttr) attr); + checkType(attr, JSONLAPlainAttr.class); + return plainAttrsList.removeIf(jsonAttr -> jsonAttr.getSchemaKey().equals(attr.getSchema().getKey())); } @Override public Optional getPlainAttr(final String plainSchema) { - return getPlainAttrs().stream(). - filter(plainAttr -> plainAttr != null && plainAttr.getSchema() != null - && plainSchema.equals(plainAttr.getSchema().getKey())).findFirst(); + return plainAttrsList.stream(). + filter(attr -> plainSchema.equals(attr.getSchemaKey())). + findFirst(); } @Override public List getPlainAttrs() { - return plainAttrs; + return plainAttrsList.stream().toList(); } @Override diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDynGroupMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDynGroupMembership.java index 4eadcb8dd89..1a851cf335e 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDynGroupMembership.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDynGroupMembership.java @@ -19,6 +19,7 @@ package org.apache.syncope.core.persistence.jpa.entity.user; import jakarta.persistence.Entity; +import jakarta.persistence.OneToOne; import jakarta.persistence.Table; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership; @@ -34,7 +35,8 @@ public class JPAUDynGroupMembership extends AbstractDynMembership implemen public static final String TABLE = "UDynGroupMembership"; - private Group group; + @OneToOne + private JPAGroup group; @Override public Group getGroup() { diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMembership.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMembership.java index 81654b6ba5d..a54a3ac9815 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMembership.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMembership.java @@ -18,7 +18,9 @@ */ package org.apache.syncope.core.persistence.jpa.entity.user; +import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import org.apache.syncope.core.persistence.api.entity.MembershipType; import org.apache.syncope.core.persistence.api.entity.RelationshipType; @@ -36,9 +38,13 @@ public class JPAUMembership extends AbstractGeneratedKeyEntity implements UMembe public static final String TABLE = "UMembership"; - private User leftEnd; + @ManyToOne + @Column(name = "user_id") + private JPAUser leftEnd; - private Group rightEnd; + @ManyToOne + @Column(name = "group_id") + private JPAGroup rightEnd; @Override public MembershipType getType() { diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java deleted file mode 100644 index 81106c14ba3..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.user; - -import jakarta.persistence.CascadeType; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToMany; -import jakarta.persistence.OneToOne; -import jakarta.persistence.Table; -import jakarta.validation.Valid; -import java.util.ArrayList; -import java.util.List; -import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.user.UMembership; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.user.User; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr; - -@Entity -@Table(name = JPAUPlainAttr.TABLE) -public class JPAUPlainAttr extends AbstractPlainAttr implements UPlainAttr { - - private static final long serialVersionUID = 6333601983691157406L; - - public static final String TABLE = "UPlainAttr"; - - /** - * The owner of this attribute. - */ - @ManyToOne(fetch = FetchType.EAGER) - private JPAUser owner; - - /** - * The membership of this attribute; might be {@code NULL} if this attribute is not related to a membership. - */ - @ManyToOne(fetch = FetchType.EAGER) - private JPAUMembership membership; - - /** - * Values of this attribute (if schema is not UNIQUE). - */ - @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, orphanRemoval = true, mappedBy = "attribute") - @Valid - private List values = new ArrayList<>(); - - /** - * Value of this attribute (if schema is UNIQUE). - */ - @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "attribute") - @Valid - private JPAUPlainAttrUniqueValue uniqueValue; - - @Override - public User getOwner() { - return owner; - } - - @Override - public void setOwner(final User owner) { - checkType(owner, JPAUser.class); - this.owner = (JPAUser) owner; - } - - @Override - public UMembership getMembership() { - return membership; - } - - @Override - public void setMembership(final UMembership membership) { - checkType(membership, JPAUMembership.class); - this.membership = (JPAUMembership) membership; - } - - @Override - protected boolean addForMultiValue(final PlainAttrValue attrValue) { - checkType(attrValue, JPAUPlainAttrValue.class); - return values.add((JPAUPlainAttrValue) attrValue); - } - - @Override - public List getValues() { - return values; - } - - @Override - public UPlainAttrUniqueValue getUniqueValue() { - return uniqueValue; - } - - @Override - public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) { - checkType(uniqueValue, JPAUPlainAttrUniqueValue.class); - this.uniqueValue = (JPAUPlainAttrUniqueValue) uniqueValue; - } -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrUniqueValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrUniqueValue.java deleted file mode 100644 index 1ea5a11d835..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrUniqueValue.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.user; - -import jakarta.persistence.Entity; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToOne; -import jakarta.persistence.Table; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; -import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema; - -@Entity -@Table(name = JPAUPlainAttrUniqueValue.TABLE) -public class JPAUPlainAttrUniqueValue extends AbstractPlainAttrValue implements UPlainAttrUniqueValue { - - private static final long serialVersionUID = -64080804563305387L; - - public static final String TABLE = "UPlainAttrUniqueValue"; - - @OneToOne(optional = false) - private JPAUPlainAttr attribute; - - @ManyToOne(optional = false) - @JoinColumn(name = "schema_id") - private JPAPlainSchema schema; - - @Override - public UPlainAttr getAttr() { - return attribute; - } - - @Override - public void setAttr(final PlainAttr attr) { - checkType(attr, JPAUPlainAttr.class); - this.attribute = (JPAUPlainAttr) attr; - } - - @Override - public PlainSchema getSchema() { - return schema; - } - - @Override - public void setSchema(final PlainSchema schema) { - checkType(schema, JPAPlainSchema.class); - this.schema = (JPAPlainSchema) schema; - } -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrValue.java deleted file mode 100644 index acb62a18b42..00000000000 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrValue.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.entity.user; - -import jakarta.persistence.Entity; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import jakarta.validation.constraints.NotNull; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; - -@Entity -@Table(name = JPAUPlainAttrValue.TABLE) -public class JPAUPlainAttrValue extends AbstractPlainAttrValue implements UPlainAttrValue { - - private static final long serialVersionUID = -6259576015647897446L; - - public static final String TABLE = "UPlainAttrValue"; - - @ManyToOne - @NotNull - private JPAUPlainAttr attribute; - - @Override - public UPlainAttr getAttr() { - return attribute; - } - - @Override - public void setAttr(final PlainAttr attr) { - checkType(attr, JPAUPlainAttr.class); - this.attribute = (JPAUPlainAttr) attr; - } -} diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAURelationship.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAURelationship.java index a7c920a3995..f92a002a162 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAURelationship.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAURelationship.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.core.persistence.jpa.entity.user; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.ManyToOne; @@ -44,9 +45,13 @@ public class JPAURelationship extends AbstractGeneratedKeyEntity implements URel @ManyToOne(fetch = FetchType.EAGER, optional = false) private JPARelationshipType type; - private User leftEnd; + @ManyToOne + @Column(name = "user_id") + private JPAUser leftEnd; - private AnyObject rightEnd; + @ManyToOne + @Column(name = "anyObject_id") + private JPAAnyObject rightEnd; @Override public RelationshipType getType() { diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java index fd1593701bf..c2e50be621d 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java @@ -23,6 +23,7 @@ import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EntityListeners; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; @@ -33,12 +34,14 @@ import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; +import jakarta.persistence.Transient; import jakarta.persistence.UniqueConstraint; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; import org.apache.syncope.common.keymaster.client.api.ConfParamOps; import org.apache.syncope.common.lib.types.CipherAlgorithm; @@ -67,6 +70,7 @@ @Entity @Table(name = JPAUser.TABLE) +@EntityListeners({ JSONUserListener.class }) @Cacheable public class JPAUser extends AbstractGroupableRelatable @@ -93,9 +97,10 @@ public class JPAUser @UniqueConstraint(columnNames = { "user_id", "role_id" })) protected List roles = new ArrayList<>(); - @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner") - @Valid - protected List plainAttrs = new ArrayList<>(); + private String plainAttrs; + + @Transient + private final List plainAttrsList = new ArrayList<>(); @Lob protected String token; @@ -254,16 +259,33 @@ public boolean canDecodeSecrets() { } @Override - public boolean add(final UPlainAttr attr) { - checkType(attr, JPAUPlainAttr.class); - return plainAttrs.add((JPAUPlainAttr) attr); + public List getPlainAttrsList() { + return plainAttrsList; } @Override - protected List internalGetPlainAttrs() { + public String getPlainAttrsJSON() { return plainAttrs; } + @Override + public void setPlainAttrsJSON(final String plainAttrs) { + this.plainAttrs = plainAttrs; + } + + @Override + public boolean add(final UPlainAttr attr) { + checkType(attr, JSONUPlainAttr.class); + return plainAttrsList.add((JSONUPlainAttr) attr); + } + + @Override + public boolean remove(final UPlainAttr attr) { + checkType(attr, JSONUPlainAttr.class); + return plainAttrsList.removeIf(jsonAttr -> jsonAttr.getSchemaKey().equals(attr.getSchema().getKey()) + && Objects.equals(jsonAttr.getMembershipKey(), attr.getMembershipKey())); + } + @Override public void generateToken(final int tokenLength, final int tokenExpireTime) { this.token = SecureRandomUtils.generateRandomPassword(tokenLength); @@ -451,6 +473,8 @@ public boolean add(final UMembership membership) { @Override public boolean remove(final UMembership membership) { checkType(membership, JPAUMembership.class); + plainAttrsList.removeIf(attr -> attr.getMembershipKey() != null + && attr.getMembershipKey().equals(membership.getKey())); return this.memberships.remove((JPAUMembership) membership); } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALAPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONLAPlainAttr.java similarity index 62% rename from core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALAPlainAttr.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONLAPlainAttr.java index 6152ea25429..e0cfebfb774 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPALAPlainAttr.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONLAPlainAttr.java @@ -18,55 +18,43 @@ */ package org.apache.syncope.core.persistence.jpa.entity.user; -import jakarta.persistence.CascadeType; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToMany; -import jakarta.persistence.OneToOne; -import jakarta.persistence.Table; -import jakarta.validation.Valid; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttrValue; import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr; -@Entity -@Table(name = JPALAPlainAttr.TABLE) -public class JPALAPlainAttr extends AbstractPlainAttr implements LAPlainAttr { +public class JSONLAPlainAttr extends AbstractPlainAttr implements LAPlainAttr { private static final long serialVersionUID = 7827533741035423694L; - public static final String TABLE = "LAPlainAttr"; - /** * The owner of this attribute. */ - @ManyToOne(fetch = FetchType.EAGER) + @JsonIgnore private JPAUser owner; - @ManyToOne(fetch = FetchType.EAGER) + @JsonIgnore private JPALinkedAccount account; /** * Values of this attribute (if schema is not UNIQUE). */ - @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute") - @Valid - private List values = new ArrayList<>(); + private List values = new ArrayList<>(); /** * Value of this attribute (if schema is UNIQUE). */ - @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "attribute") - @Valid - private JPALAPlainAttrUniqueValue uniqueValue; + @JsonProperty + private JSONLAPlainAttrUniqueValue uniqueValue; @Override public User getOwner() { @@ -75,7 +63,6 @@ public User getOwner() { @Override public void setOwner(final User owner) { - checkType(owner, JPAUser.class); this.owner = (JPAUser) owner; } @@ -86,14 +73,12 @@ public LinkedAccount getAccount() { @Override public void setAccount(final LinkedAccount account) { - checkType(account, JPALinkedAccount.class); this.account = (JPALinkedAccount) account; } @Override protected boolean addForMultiValue(final PlainAttrValue attrValue) { - checkType(attrValue, JPALAPlainAttrValue.class); - return values.add((JPALAPlainAttrValue) attrValue); + return values.add((JSONLAPlainAttrValue) attrValue); } @Override @@ -102,13 +87,43 @@ public List getValues() { } @Override - public LAPlainAttrUniqueValue getUniqueValue() { + public JSONLAPlainAttrUniqueValue getUniqueValue() { return uniqueValue; } + @JsonIgnore @Override public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) { - checkType(uniqueValue, JPALAPlainAttrUniqueValue.class); - this.uniqueValue = (JPALAPlainAttrUniqueValue) uniqueValue; + this.uniqueValue = (JSONLAPlainAttrUniqueValue) uniqueValue; + } + + @Override + public int hashCode() { + return new HashCodeBuilder(). + appendSuper(super.hashCode()). + append(account). + append(values). + append(uniqueValue). + build(); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final JSONLAPlainAttr other = (JSONLAPlainAttr) obj; + return new EqualsBuilder(). + appendSuper(super.equals(obj)). + append(account, other.account). + append(values, other.values). + append(uniqueValue, other.uniqueValue). + build(); } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLAPlainAttrUniqueValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONLAPlainAttrUniqueValue.java similarity index 76% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLAPlainAttrUniqueValue.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONLAPlainAttrUniqueValue.java index eba787c6e98..2d408e37919 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLAPlainAttrUniqueValue.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONLAPlainAttrUniqueValue.java @@ -19,22 +19,18 @@ package org.apache.syncope.core.persistence.jpa.entity.user; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttrUniqueValue; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; -@JsonIgnoreProperties({ "valueAsString", "value" }) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class JPAJSONLAPlainAttrUniqueValue extends AbstractPlainAttrValue implements LAPlainAttrUniqueValue { +public class JSONLAPlainAttrUniqueValue extends AbstractPlainAttrValue implements LAPlainAttrUniqueValue { - private static final long serialVersionUID = 4005916774320343497L; + private static final long serialVersionUID = 1200617357906733442L; @JsonIgnore - private JPAJSONLAPlainAttr attr; + private JSONLAPlainAttr attr; @Override public LAPlainAttr getAttr() { @@ -43,8 +39,7 @@ public LAPlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, JPAJSONLAPlainAttr.class); - this.attr = (JPAJSONLAPlainAttr) attr; + this.attr = (JSONLAPlainAttr) attr; } @JsonIgnore diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLAPlainAttrValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONLAPlainAttrValue.java similarity index 72% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLAPlainAttrValue.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONLAPlainAttrValue.java index 7a3c299bf4d..4e592bdbb45 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLAPlainAttrValue.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONLAPlainAttrValue.java @@ -19,21 +19,17 @@ package org.apache.syncope.core.persistence.jpa.entity.user; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; -@JsonIgnoreProperties({ "valueAsString", "value" }) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class JPAJSONLAPlainAttrValue extends AbstractPlainAttrValue implements LAPlainAttrValue { +public class JSONLAPlainAttrValue extends AbstractPlainAttrValue implements LAPlainAttrValue { - private static final long serialVersionUID = -7049546275798013346L; + private static final long serialVersionUID = 6237793413044604262L; @JsonIgnore - private JPAJSONLAPlainAttr attr; + private JSONLAPlainAttr attr; @Override public LAPlainAttr getAttr() { @@ -42,7 +38,6 @@ public LAPlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, JPAJSONLAPlainAttr.class); - this.attr = (JPAJSONLAPlainAttr) attr; + this.attr = (JSONLAPlainAttr) attr; } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLinkedAccountListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONLinkedAccountListener.java similarity index 65% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLinkedAccountListener.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONLinkedAccountListener.java index 2ddf7ee9a7c..ba2a1924762 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONLinkedAccountListener.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONLinkedAccountListener.java @@ -25,36 +25,36 @@ import jakarta.persistence.PrePersist; import jakarta.persistence.PreUpdate; import java.util.List; -import org.apache.syncope.core.persistence.api.entity.JSONLAPlainAttr; +import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.User; -import org.apache.syncope.core.persistence.jpa.entity.JPAJSONEntityListener; +import org.apache.syncope.core.persistence.jpa.entity.JSONEntityListener; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; -public class JPAJSONLinkedAccountListener extends JPAJSONEntityListener { +public class JSONLinkedAccountListener extends JSONEntityListener { - protected static final TypeReference> TYPEREF = - new TypeReference>() { + protected static final TypeReference> TYPEREF = + new TypeReference>() { }; @Override - protected List getAttrs(final String plainAttrsJSON) { + protected List getAttrs(final String plainAttrsJSON) { return POJOHelper.deserialize(plainAttrsJSON, TYPEREF); } @PostLoad - public void read(final JPAJSONLinkedAccount account) { - super.json2list(account, false); + public void read(final JPALinkedAccount linkedAccount) { + super.json2list(linkedAccount, false); } @PrePersist @PreUpdate - public void save(final JPAJSONLinkedAccount account) { - super.list2json(account); + public void save(final JPALinkedAccount linkedAccount) { + super.list2json(linkedAccount); } @PostPersist @PostUpdate - public void readAfterSave(final JPAJSONLinkedAccount account) { - super.json2list(account, true); + public void readAfterSave(final JPALinkedAccount linkedAccount) { + super.json2list(linkedAccount, true); } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUPlainAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONUPlainAttr.java similarity index 62% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUPlainAttr.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONUPlainAttr.java index 18d10951250..9c503676f63 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUPlainAttr.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONUPlainAttr.java @@ -18,9 +18,8 @@ */ package org.apache.syncope.core.persistence.jpa.entity.user; +import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSetter; import java.util.ArrayList; @@ -28,34 +27,22 @@ import java.util.Optional; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; -import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.user.UMembership; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema; import org.apache.syncope.core.spring.ApplicationContextProvider; -@JsonIgnoreProperties("valuesAsStrings") -@JsonInclude(JsonInclude.Include.NON_EMPTY) -public class JPAJSONUPlainAttr extends AbstractPlainAttr implements UPlainAttr, JSONPlainAttr { +public class JSONUPlainAttr extends AbstractPlainAttr implements UPlainAttr { - private static final long serialVersionUID = 806271775349587902L; + private static final long serialVersionUID = 8066058729580952116L; - /** - * The owner of this attribute. - */ @JsonIgnore - private JPAJSONUser owner; - - @JsonProperty - private String schema; + private User owner; /** * The membership of this attribute; might be {@code NULL} if this attribute is not related to a membership. @@ -66,13 +53,13 @@ public class JPAJSONUPlainAttr extends AbstractPlainAttr implements UPlain /** * Values of this attribute (if schema is not UNIQUE). */ - private final List values = new ArrayList<>(); + private List values = new ArrayList<>(); /** * Value of this attribute (if schema is UNIQUE). */ @JsonProperty - private JPAJSONUPlainAttrUniqueValue uniqueValue; + private JSONUPlainAttrUniqueValue uniqueValue; @Override public User getOwner() { @@ -81,55 +68,26 @@ public User getOwner() { @Override public void setOwner(final User owner) { - checkType(owner, JPAJSONUser.class); - this.owner = (JPAJSONUser) owner; + this.owner = (JPAUser) owner; } @JsonIgnore @Override - public String getSchemaKey() { - return schema; + public UMembership getMembership() { + return ApplicationContextProvider.getBeanFactory().getBean(UserDAO.class).findMembership(membership); } - @JsonIgnore @Override - public JPAPlainSchema getSchema() { - return Optional.ofNullable(schema). - flatMap(s -> ApplicationContextProvider.getBeanFactory().getBean(PlainSchemaDAO.class).findById(s)). - map(JPAPlainSchema.class::cast). - orElse(null); + public void setMembership(final UMembership membership) { + this.membership = Optional.ofNullable(membership).map(UMembership::getKey).orElse(null); } + @JsonGetter("membership") @Override - public void setSchema(final PlainSchema schema) { - if (schema != null) { - this.schema = schema.getKey(); - } - } - - @JsonSetter("schema") - public void setSchema(final String schema) { - this.schema = schema; - } - - @JsonIgnore public String getMembershipKey() { return membership; } - @JsonIgnore - @Override - public UMembership getMembership() { - return ApplicationContextProvider.getBeanFactory().getBean(UserDAO.class).findMembership(membership); - } - - @Override - public void setMembership(final UMembership membership) { - if (membership != null) { - this.membership = membership.getKey(); - } - } - @JsonSetter("membership") public void setMembership(final String membership) { this.membership = membership; @@ -137,13 +95,7 @@ public void setMembership(final String membership) { @Override protected boolean addForMultiValue(final PlainAttrValue attrValue) { - checkType(attrValue, JPAJSONUPlainAttrValue.class); - return values.add((JPAJSONUPlainAttrValue) attrValue); - } - - @Override - public boolean add(final PlainAttrValue value) { - return addForMultiValue(value); + return values.add((JSONUPlainAttrValue) attrValue); } @Override @@ -152,21 +104,20 @@ public List getValues() { } @Override - public JPAJSONUPlainAttrUniqueValue getUniqueValue() { + public JSONUPlainAttrUniqueValue getUniqueValue() { return uniqueValue; } @JsonIgnore @Override public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) { - checkType(uniqueValue, JPAJSONUPlainAttrUniqueValue.class); - this.uniqueValue = (JPAJSONUPlainAttrUniqueValue) uniqueValue; + this.uniqueValue = (JSONUPlainAttrUniqueValue) uniqueValue; } @Override public int hashCode() { return new HashCodeBuilder(). - append(schema). + appendSuper(super.hashCode()). append(membership). append(values). append(uniqueValue). @@ -184,9 +135,9 @@ public boolean equals(final Object obj) { if (getClass() != obj.getClass()) { return false; } - final JPAJSONUPlainAttr other = (JPAJSONUPlainAttr) obj; + final JSONUPlainAttr other = (JSONUPlainAttr) obj; return new EqualsBuilder(). - append(schema, other.schema). + appendSuper(super.equals(obj)). append(membership, other.membership). append(values, other.values). append(uniqueValue, other.uniqueValue). diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUPlainAttrUniqueValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONUPlainAttrUniqueValue.java similarity index 76% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUPlainAttrUniqueValue.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONUPlainAttrUniqueValue.java index ab4a8f42ba2..5a825c9c711 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUPlainAttrUniqueValue.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONUPlainAttrUniqueValue.java @@ -19,22 +19,18 @@ package org.apache.syncope.core.persistence.jpa.entity.user; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; -@JsonIgnoreProperties({ "valueAsString", "value" }) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class JPAJSONUPlainAttrUniqueValue extends AbstractPlainAttrValue implements UPlainAttrUniqueValue { +public class JSONUPlainAttrUniqueValue extends AbstractPlainAttrValue implements UPlainAttrUniqueValue { - private static final long serialVersionUID = -4053996864791245312L; + private static final long serialVersionUID = 4681561795607192855L; @JsonIgnore - private JPAJSONUPlainAttr attr; + private JSONUPlainAttr attr; @Override public UPlainAttr getAttr() { @@ -43,8 +39,7 @@ public UPlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, JPAJSONUPlainAttr.class); - this.attr = (JPAJSONUPlainAttr) attr; + this.attr = (JSONUPlainAttr) attr; } @JsonIgnore diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUPlainAttrValue.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONUPlainAttrValue.java similarity index 73% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUPlainAttrValue.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONUPlainAttrValue.java index 4a4415b1152..c9dac6988c6 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUPlainAttrValue.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONUPlainAttrValue.java @@ -19,21 +19,17 @@ package org.apache.syncope.core.persistence.jpa.entity.user; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue; -@JsonIgnoreProperties({ "valueAsString", "value" }) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class JPAJSONUPlainAttrValue extends AbstractPlainAttrValue implements UPlainAttrValue { +public class JSONUPlainAttrValue extends AbstractPlainAttrValue implements UPlainAttrValue { - private static final long serialVersionUID = 1832825176101443555L; + private static final long serialVersionUID = -766808291128424707L; @JsonIgnore - private JPAJSONUPlainAttr attr; + private JSONUPlainAttr attr; @Override public UPlainAttr getAttr() { @@ -42,7 +38,6 @@ public UPlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, JPAJSONUPlainAttr.class); - this.attr = (JPAJSONUPlainAttr) attr; + this.attr = (JSONUPlainAttr) attr; } } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUserListener.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONUserListener.java similarity index 72% rename from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUserListener.java rename to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONUserListener.java index 710944b7be8..9bfc856d961 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAJSONUserListener.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JSONUserListener.java @@ -25,36 +25,36 @@ import jakarta.persistence.PrePersist; import jakarta.persistence.PreUpdate; import java.util.List; -import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr; +import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.User; -import org.apache.syncope.core.persistence.jpa.entity.JPAJSONEntityListener; +import org.apache.syncope.core.persistence.jpa.entity.JSONEntityListener; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; -public class JPAJSONUserListener extends JPAJSONEntityListener { +public class JSONUserListener extends JSONEntityListener { - protected static final TypeReference> TYPEREF = - new TypeReference>() { + protected static final TypeReference> TYPEREF = + new TypeReference>() { }; @Override - protected List> getAttrs(final String plainAttrsJSON) { + protected List getAttrs(final String plainAttrsJSON) { return POJOHelper.deserialize(plainAttrsJSON, TYPEREF); } @PostLoad - public void read(final JPAJSONUser user) { + public void read(final JPAUser user) { super.json2list(user, false); } @PrePersist @PreUpdate - public void save(final JPAJSONUser user) { + public void save(final JPAUser user) { super.list2json(user); } @PostPersist @PostUpdate - public void readAfterSave(final JPAJSONUser user) { + public void readAfterSave(final JPAUser user) { super.json2list(user, true); } } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainRoutingEntityManagerFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainRoutingEntityManagerFactory.java index dceb3ce314d..2c39769c2c2 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainRoutingEntityManagerFactory.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainRoutingEntityManagerFactory.java @@ -28,16 +28,11 @@ import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.metamodel.Metamodel; import java.io.Closeable; -import java.util.Collection; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import javax.sql.DataSource; -import org.apache.openjpa.jdbc.conf.JDBCConfiguration; -import org.apache.openjpa.jdbc.meta.MappingRepository; -import org.apache.openjpa.jdbc.meta.MappingTool; -import org.apache.openjpa.lib.conf.Configurations; -import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI; import org.apache.syncope.common.keymaster.client.api.model.JPADomain; import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.core.persistence.jpa.PersistenceProperties; @@ -59,6 +54,22 @@ public DomainRoutingEntityManagerFactory(final CommonEntityManagerFactoryConf co protected final Map delegates = new ConcurrentHashMap<>(); + protected void addToJpaPropertyMap( + final DomainEntityManagerFactoryBean emf, + final OpenJpaVendorAdapter vendorAdapter, + final String dbSchema, + final String orm, + final String metadataFactory) { + + emf.getJpaPropertyMap().putAll(vendorAdapter.getJpaPropertyMap()); + + Optional.ofNullable(dbSchema). + ifPresent(s -> emf.getJpaPropertyMap().put("openjpa.jdbc.Schema", s)); + + Optional.ofNullable(metadataFactory). + ifPresent(m -> emf.getJpaPropertyMap().put("openjpa.MetaDataFactory", m.replace("##orm##", orm))); + } + public void master( final PersistenceProperties props, final JndiObjectFactoryBean dataSource) { @@ -69,19 +80,20 @@ public void master( vendorAdapter.setDatabasePlatform(props.getDomain().get(0).getDatabasePlatform()); DomainEntityManagerFactoryBean emf = new DomainEntityManagerFactoryBean(); - emf.setMappingResources(props.getDomain().get(0).getOrm()); emf.setPersistenceUnitName(SyncopeConstants.MASTER_DOMAIN); + emf.setMappingResources(props.getDomain().get(0).getOrm()); emf.setDataSource(Objects.requireNonNull((DataSource) dataSource.getObject())); emf.setJpaVendorAdapter(vendorAdapter); emf.setCommonEntityManagerFactoryConf(commonEMFConf); emf.setConnectorManagerRemoteCommitListener( new ConnectorManagerRemoteCommitListener(SyncopeConstants.MASTER_DOMAIN)); - if (props.getMetaDataFactory() != null) { - emf.setJpaPropertyMap(Map.of( - "openjpa.MetaDataFactory", - props.getMetaDataFactory().replace("##orm##", props.getDomain().get(0).getOrm()))); - } + addToJpaPropertyMap( + emf, + vendorAdapter, + props.getDomain().get(0).getDbSchema(), + props.getDomain().get(0).getOrm(), + props.getMetaDataFactory()); emf.afterPropertiesSet(); @@ -99,18 +111,14 @@ public void domain( vendorAdapter.setDatabasePlatform(domain.getDatabasePlatform()); DomainEntityManagerFactoryBean emf = new DomainEntityManagerFactoryBean(); - emf.setMappingResources(domain.getOrm()); emf.setPersistenceUnitName(domain.getKey()); + emf.setMappingResources(domain.getOrm()); emf.setDataSource(dataSource); emf.setJpaVendorAdapter(vendorAdapter); emf.setCommonEntityManagerFactoryConf(commonEMFConf); emf.setConnectorManagerRemoteCommitListener(new ConnectorManagerRemoteCommitListener(domain.getKey())); - if (metadataFactory != null) { - emf.setJpaPropertyMap(Map.of( - "openjpa.MetaDataFactory", - metadataFactory.replace("##orm##", domain.getOrm()))); - } + addToJpaPropertyMap(emf, vendorAdapter, domain.getDbSchema(), domain.getOrm(), metadataFactory); emf.afterPropertiesSet(); @@ -128,25 +136,6 @@ protected EntityManagerFactory delegate() { }); } - public void initJPASchema() { - OpenJPAEntityManagerFactorySPI emfspi = delegate().unwrap(OpenJPAEntityManagerFactorySPI.class); - JDBCConfiguration jdbcConf = (JDBCConfiguration) emfspi.getConfiguration(); - - MappingRepository mappingRepo = jdbcConf.getMappingRepositoryInstance(); - Collection> classes = mappingRepo.loadPersistentTypes(false, getClass().getClassLoader()); - - String action = "buildSchema(ForeignKeys=true)"; - String props = Configurations.getProperties(action); - action = Configurations.getClassName(action); - MappingTool mappingTool = new MappingTool(jdbcConf, action, false, getClass().getClassLoader()); - Configurations.configureInstance(mappingTool, jdbcConf, props, "SynchronizeMappings"); - - // initialize the schema - classes.forEach(mappingTool::run); - - mappingTool.record(); - } - @Override public EntityManager createEntityManager() { return delegate().createEntityManager(); diff --git a/core/persistence-jpa-json/src/main/resources/pgjsonb/indexes.xml b/core/persistence-jpa/src/main/resources/META-INF/indexes.xml similarity index 100% rename from core/persistence-jpa-json/src/main/resources/pgjsonb/indexes.xml rename to core/persistence-jpa/src/main/resources/META-INF/indexes.xml diff --git a/core/persistence-jpa-json/src/main/resources/majson/indexes.xml b/core/persistence-jpa/src/main/resources/META-INF/mariadb/indexes.xml similarity index 100% rename from core/persistence-jpa-json/src/main/resources/majson/indexes.xml rename to core/persistence-jpa/src/main/resources/META-INF/mariadb/indexes.xml diff --git a/core/persistence-jpa/src/main/resources/META-INF/mariadb/spring-orm.xml b/core/persistence-jpa/src/main/resources/META-INF/mariadb/spring-orm.xml new file mode 100644 index 00000000000..408169e456b --- /dev/null +++ b/core/persistence-jpa/src/main/resources/META-INF/mariadb/spring-orm.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/persistence-jpa-json/src/main/resources/majson/views.xml b/core/persistence-jpa/src/main/resources/META-INF/mariadb/views.xml similarity index 100% rename from core/persistence-jpa-json/src/main/resources/majson/views.xml rename to core/persistence-jpa/src/main/resources/META-INF/mariadb/views.xml diff --git a/core/persistence-jpa-json/src/main/resources/myjson/indexes.xml b/core/persistence-jpa/src/main/resources/META-INF/mysql/indexes.xml similarity index 100% rename from core/persistence-jpa-json/src/main/resources/myjson/indexes.xml rename to core/persistence-jpa/src/main/resources/META-INF/mysql/indexes.xml diff --git a/core/persistence-jpa/src/main/resources/META-INF/mysql/spring-orm.xml b/core/persistence-jpa/src/main/resources/META-INF/mysql/spring-orm.xml new file mode 100644 index 00000000000..408169e456b --- /dev/null +++ b/core/persistence-jpa/src/main/resources/META-INF/mysql/spring-orm.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/persistence-jpa-json/src/main/resources/myjson/views.xml b/core/persistence-jpa/src/main/resources/META-INF/mysql/views.xml similarity index 100% rename from core/persistence-jpa-json/src/main/resources/myjson/views.xml rename to core/persistence-jpa/src/main/resources/META-INF/mysql/views.xml diff --git a/core/persistence-jpa-json/src/main/resources/ojson/indexes.xml b/core/persistence-jpa/src/main/resources/META-INF/oracle/indexes.xml similarity index 100% rename from core/persistence-jpa-json/src/main/resources/ojson/indexes.xml rename to core/persistence-jpa/src/main/resources/META-INF/oracle/indexes.xml diff --git a/core/persistence-jpa/src/main/resources/META-INF/oracle/spring-orm.xml b/core/persistence-jpa/src/main/resources/META-INF/oracle/spring-orm.xml new file mode 100644 index 00000000000..ec51dcfa7e1 --- /dev/null +++ b/core/persistence-jpa/src/main/resources/META-INF/oracle/spring-orm.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/persistence-jpa-json/src/main/resources/ojson/views.xml b/core/persistence-jpa/src/main/resources/META-INF/oracle/views.xml similarity index 100% rename from core/persistence-jpa-json/src/main/resources/ojson/views.xml rename to core/persistence-jpa/src/main/resources/META-INF/oracle/views.xml diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml deleted file mode 100644 index 836556d2f84..00000000000 --- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml deleted file mode 100644 index e51b9b1da7b..00000000000 --- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - booleanValue - dateValue - stringValue - doubleValue - longValue - schema_id - -
-
- - - - booleanValue - dateValue - stringValue - doubleValue - longValue - schema_id - -
-
- - - - booleanValue - dateValue - stringValue - doubleValue - longValue - schema_id - -
-
-
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml index 1602fecee37..1ae2eed60dd 100644 --- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml +++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml @@ -33,142 +33,40 @@ under the License. - - + + - - + + + + - - + + - + + + + - - - - - - - - - - - - - - - - + - - - - - - + + + + - + - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - booleanValue - schema_id - - - dateValue - schema_id - - - stringValue - schema_id - - - doubleValue - schema_id - - - longValue - schema_id - -
-
- - - - booleanValue - schema_id - - - dateValue - schema_id - - - stringValue - schema_id - - - doubleValue - schema_id - - - longValue - schema_id - -
-
- - - - booleanValue - schema_id - - - dateValue - schema_id - - - stringValue - schema_id - - - doubleValue - schema_id - - - longValue - schema_id - -
-
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/core/persistence-jpa/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 9465bce8be3..0a01ae2b4d6 100644 --- a/core/persistence-jpa/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/core/persistence-jpa/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -16,3 +16,7 @@ # under the License. org.apache.syncope.core.persistence.jpa.PersistenceContext org.apache.syncope.core.persistence.jpa.MasterDomain +org.apache.syncope.core.persistence.jpa.PGPersistenceContext +org.apache.syncope.core.persistence.jpa.MySQLPersistenceContext +org.apache.syncope.core.persistence.jpa.MariaDBPersistenceContext +org.apache.syncope.core.persistence.jpa.OraclePersistenceContext diff --git a/core/persistence-jpa-json/src/main/resources/pgjsonb/views.xml b/core/persistence-jpa/src/main/resources/META-INF/views.xml similarity index 100% rename from core/persistence-jpa-json/src/main/resources/pgjsonb/views.xml rename to core/persistence-jpa/src/main/resources/META-INF/views.xml diff --git a/core/persistence-jpa/src/main/resources/domains/MasterContent.xml b/core/persistence-jpa/src/main/resources/domains/MasterContent.xml index eef05108cf7..256e121b740 100644 --- a/core/persistence-jpa/src/main/resources/domains/MasterContent.xml +++ b/core/persistence-jpa/src/main/resources/domains/MasterContent.xml @@ -8,7 +8,7 @@ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an @@ -18,7 +18,7 @@ specific language governing permissions and limitations under the License. --> - + @@ -28,13 +28,14 @@ under the License. + - + diff --git a/core/persistence-jpa/src/main/resources/indexes.xml b/core/persistence-jpa/src/main/resources/indexes.xml deleted file mode 100644 index 496730805df..00000000000 --- a/core/persistence-jpa/src/main/resources/indexes.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - - - Additional indexes (in respect to JPA's) - - CREATE INDEX Realm_parent_id ON Realm(parent_id) - - CREATE INDEX SyncopeUser_realm_id ON SyncopeUser(realm_id) - CREATE UNIQUE INDEX SyncopeUser_username ON SyncopeUser(username) - - CREATE INDEX SyncopeGroup_realm_id ON SyncopeGroup(realm_id) - CREATE UNIQUE INDEX SyncopeGroup_name ON SyncopeGroup(name) - - CREATE INDEX AnyObject_realm_id ON AnyObject(realm_id) - CREATE UNIQUE INDEX AnyObject_name ON AnyObject(type_id,name) - - CREATE INDEX UDynGroupMembers_any_id ON UDynGroupMembers(any_id) - CREATE INDEX UDynGroupMembers_group_id ON UDynGroupMembers(group_id) - CREATE INDEX ADynGroupMembers_any_id ON ADynGroupMembers(any_id) - CREATE INDEX ADynGroupMembers_group_id ON ADynGroupMembers(group_id) - - CREATE INDEX DynRoleMembers_any_id ON DynRoleMembers(any_id) - CREATE INDEX DynRoleMembers_role_id ON DynRoleMembers(role_id) - - CREATE INDEX DynRealmMembers_any_id ON DynRealmMembers(any_id) - CREATE INDEX DynRealmMembers_dynRealm_id ON DynRealmMembers(dynRealm_id) - - CREATE INDEX UAttrValue_stringvalueIndex ON UPlainAttrValue(stringvalue) - CREATE INDEX UAttrValue_datevalueIndex ON UPlainAttrValue(datevalue) - CREATE INDEX UAttrValue_longvalueIndex ON UPlainAttrValue(longvalue) - CREATE INDEX UAttrValue_doublevalueIndex ON UPlainAttrValue(doublevalue) - CREATE INDEX UAttrValue_booleanvalueIndex ON UPlainAttrValue(booleanvalue) - - CREATE INDEX AAttrValue_stringvalueIndex ON APlainAttrValue(stringvalue) - CREATE INDEX AAttrValue_datevalueIndex ON APlainAttrValue(datevalue) - CREATE INDEX AAttrValue_longvalueIndex ON APlainAttrValue(longvalue) - CREATE INDEX AAttrValue_doublevalueIndex ON APlainAttrValue(doublevalue) - CREATE INDEX AAttrValue_booleanvalueIndex ON APlainAttrValue(booleanvalue) - - CREATE INDEX GAttrValue_stringvalueIndex ON GPlainAttrValue(stringvalue) - CREATE INDEX GAttrValue_datevalueIndex ON GPlainAttrValue(datevalue) - CREATE INDEX GAttrValue_longvalueIndex ON GPlainAttrValue(longvalue) - CREATE INDEX GAttrValue_doublevalueIndex ON GPlainAttrValue(doublevalue) - CREATE INDEX GAttrValue_booleanvalueIndex ON GPlainAttrValue(booleanvalue) - - CREATE INDEX UMembership_GroupIndex ON UMembership(group_id) - CREATE INDEX UMembership_UserIndex ON UMembership(user_id) - CREATE INDEX AMembership_GroupIndex ON AMembership(group_id) - CREATE INDEX AMembership_AnyObjectIndex ON AMembership(anyObject_id) - - CREATE INDEX URelationship_RightIndex ON URelationship(anyObject_id) - CREATE INDEX URelationship_LeftIndex ON URelationship(user_id) - CREATE INDEX ARelationship_RightIndex ON ARelationship(right_anyObject_id) - CREATE INDEX ARelationship_AnyObjectIndex ON ARelationship(left_anyObject_id) - - CREATE INDEX UPlainAttrValue_attrIndex on UPlainAttrValue(attribute_id) - CREATE INDEX UPAttrUniqueValue_attrIndex on UPlainAttrUniqueValue(attribute_id) - - CREATE INDEX GPlainAttrValue_attrIndex on GPlainAttrValue(attribute_id) - CREATE INDEX GPAttrUniqueValue_attrIndex on GPlainAttrUniqueValue(attribute_id) - - CREATE INDEX APlainAttrValue_attrIndex on APlainAttrValue(attribute_id) - CREATE INDEX APAttrUniqueValue_attrIndex on APlainAttrUniqueValue(attribute_id) - - CREATE INDEX UPlainAttr_owner_Index on UPlainAttr(owner_id) - CREATE INDEX UPlainAttr_schema_Index on UPlainAttr(schema_id) - CREATE INDEX UPlainAttr_membership_Index on UPlainAttr(membership_id) - - CREATE INDEX GPlainAttr_owner_Index on GPlainAttr(owner_id) - CREATE INDEX GPlainAttr_schema_Index on GPlainAttr(schema_id) - - CREATE INDEX APlainAttr_owner_Index on APlainAttr(owner_id) - CREATE INDEX APlainAttr_schema_Index on APlainAttr(schema_id) - CREATE INDEX APlainAttr_membership_Index on APlainAttr(membership_id) - - CREATE INDEX Task_executedIndex ON NotificationTask(executed) - CREATE INDEX TaskExec1_TaskIdIndex ON PropagationTaskExec(task_id) - CREATE INDEX TaskExec2_TaskIdIndex ON PullTaskExec(task_id) - CREATE INDEX TaskExec3_TaskIdIndex ON PushTaskExec(task_id) - CREATE INDEX TaskExec4_TaskIdIndex ON NotificationTaskExec(task_id) - CREATE INDEX TaskExec5_TaskIdIndex ON SchedTaskExec(task_id) - CREATE INDEX ATPullTask_PullTaskIndex ON AnyTemplatePullTask(pullTask_id) - diff --git a/core/persistence-jpa/src/main/resources/oracle_indexes.xml b/core/persistence-jpa/src/main/resources/oracle_indexes.xml deleted file mode 100644 index 91b43e44676..00000000000 --- a/core/persistence-jpa/src/main/resources/oracle_indexes.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - Additional indexes (in respect to JPA's) - - CREATE INDEX Realm_parent_id ON Realm(parent_id) - - CREATE INDEX SyncopeUser_realm_id ON SyncopeUser(realm_id) - CREATE INDEX SyncopeUser_lower_username ON SyncopeUser(LOWER(username)) - - CREATE INDEX SyncopeGroup_realm_id ON SyncopeGroup(realm_id) - CREATE INDEX SyncopeGroup_lower_name ON SyncopeGroup(LOWER(name)) - - CREATE INDEX AnyObject_realm_id ON AnyObject(realm_id) - CREATE INDEX AnyObject_lower_name ON AnyObject(type_id,LOWER(name)) - - CREATE UNIQUE INDEX APlainAttrUniqueValue_U on APlainAttrUniqueValue(booleanValue, dateValue, stringValue, doubleValue, longValue, schema_id) - CREATE UNIQUE INDEX UPlainAttrUniqueValue_U on UPlainAttrUniqueValue(booleanValue, dateValue, stringValue, doubleValue, longValue, schema_id) - CREATE UNIQUE INDEX GPlainAttrUniqueValue_U on GPlainAttrUniqueValue(booleanValue, dateValue, stringValue, doubleValue, longValue, schema_id) - - CREATE INDEX UDynGroupMembers_any_id ON UDynGroupMembers(any_id) - CREATE INDEX UDynGroupMembers_group_id ON UDynGroupMembers(group_id) - CREATE INDEX ADynGroupMembers_any_id ON ADynGroupMembers(any_id) - CREATE INDEX ADynGroupMembers_group_id ON ADynGroupMembers(group_id) - - CREATE INDEX DynRoleMembers_any_id ON DynRoleMembers(any_id) - CREATE INDEX DynRoleMembers_role_id ON DynRoleMembers(role_id) - - CREATE INDEX DynRealmMembers_any_id ON DynRealmMembers(any_id) - CREATE INDEX DynRealmMembers_dynRealm_id ON DynRealmMembers(dynRealm_id) - - CREATE INDEX UAttrValue_stringvalueIndex ON UPlainAttrValue(stringvalue) - CREATE INDEX UAttrValue_datevalueIndex ON UPlainAttrValue(datevalue) - CREATE INDEX UAttrValue_longvalueIndex ON UPlainAttrValue(longvalue) - CREATE INDEX UAttrValue_doublevalueIndex ON UPlainAttrValue(doublevalue) - CREATE INDEX UAttrValue_booleanvalueIndex ON UPlainAttrValue(booleanvalue) - - CREATE INDEX AAttrValue_stringvalueIndex ON APlainAttrValue(stringvalue) - CREATE INDEX AAttrValue_datevalueIndex ON APlainAttrValue(datevalue) - CREATE INDEX AAttrValue_longvalueIndex ON APlainAttrValue(longvalue) - CREATE INDEX AAttrValue_doublevalueIndex ON APlainAttrValue(doublevalue) - CREATE INDEX AAttrValue_booleanvalueIndex ON APlainAttrValue(booleanvalue) - - CREATE INDEX GAttrValue_stringvalueIndex ON GPlainAttrValue(stringvalue) - CREATE INDEX GAttrValue_datevalueIndex ON GPlainAttrValue(datevalue) - CREATE INDEX GAttrValue_longvalueIndex ON GPlainAttrValue(longvalue) - CREATE INDEX GAttrValue_doublevalueIndex ON GPlainAttrValue(doublevalue) - CREATE INDEX GAttrValue_booleanvalueIndex ON GPlainAttrValue(booleanvalue) - - CREATE INDEX UMembership_GroupIndex ON UMembership(group_id) - CREATE INDEX UMembership_UserIndex ON UMembership(user_id) - CREATE INDEX AMembership_GroupIndex ON AMembership(group_id) - CREATE INDEX AMembership_AnyObjectIndex ON AMembership(anyObject_id) - - CREATE INDEX URelationship_RightIndex ON URelationship(anyObject_id) - CREATE INDEX URelationship_LeftIndex ON URelationship(user_id) - CREATE INDEX ARelationship_RightIndex ON ARelationship(right_anyObject_id) - CREATE INDEX ARelationship_AnyObjectIndex ON ARelationship(left_anyObject_id) - - CREATE INDEX UPlainAttrValue_attrIndex on UPlainAttrValue(attribute_id) - CREATE INDEX UPAttrUniqueValue_attrIndex on UPlainAttrUniqueValue(attribute_id) - - CREATE INDEX GPlainAttrValue_attrIndex on GPlainAttrValue(attribute_id) - CREATE INDEX GPAttrUniqueValue_attrIndex on GPlainAttrUniqueValue(attribute_id) - - CREATE INDEX APlainAttrValue_attrIndex on APlainAttrValue(attribute_id) - CREATE INDEX APAttrUniqueValue_attrIndex on APlainAttrUniqueValue(attribute_id) - - CREATE INDEX UPlainAttr_owner_Index on UPlainAttr(owner_id) - CREATE INDEX UPlainAttr_schema_Index on UPlainAttr(schema_id) - CREATE INDEX UPlainAttr_membership_Index on UPlainAttr(membership_id) - - CREATE INDEX GPlainAttr_owner_Index on GPlainAttr(owner_id) - CREATE INDEX GPlainAttr_schema_Index on GPlainAttr(schema_id) - - CREATE INDEX APlainAttr_owner_Index on APlainAttr(owner_id) - CREATE INDEX APlainAttr_schema_Index on APlainAttr(schema_id) - CREATE INDEX APlainAttr_membership_Index on APlainAttr(membership_id) - - CREATE INDEX Task_executedIndex ON NotificationTask(executed) - CREATE INDEX TaskExec1_TaskIdIndex ON PropagationTaskExec(task_id) - CREATE INDEX TaskExec2_TaskIdIndex ON PullTaskExec(task_id) - CREATE INDEX TaskExec3_TaskIdIndex ON PushTaskExec(task_id) - CREATE INDEX TaskExec4_TaskIdIndex ON NotificationTaskExec(task_id) - CREATE INDEX TaskExec5_TaskIdIndex ON SchedTaskExec(task_id) - CREATE INDEX ATPullTask_PullTaskIndex ON AnyTemplatePullTask(pullTask_id) - diff --git a/core/persistence-jpa/src/main/resources/sqlserver_views.xml b/core/persistence-jpa/src/main/resources/sqlserver_views.xml deleted file mode 100644 index 83dd7873a66..00000000000 --- a/core/persistence-jpa/src/main/resources/sqlserver_views.xml +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - - CREATE TABLE UDynGroupMembers( - any_id CHAR(36), - group_id CHAR(36), - UNIQUE(any_id, group_id)) - - - CREATE TABLE ADynGroupMembers( - anyType_id VARCHAR(255), - any_id CHAR(36), - group_id CHAR(36), - UNIQUE(anyType_id, any_id, group_id)) - - - CREATE TABLE DynRoleMembers( - any_id CHAR(36), - role_id VARCHAR(255), - UNIQUE(any_id, role_id)) - - - CREATE TABLE DynRealmMembers( - any_id CHAR(36), - dynRealm_id VARCHAR(255), - UNIQUE(any_id, dynRealm_id)) - - - - - CREATE VIEW user_search AS - - SELECT u.id as any_id, u.* FROM SyncopeUser u - - - CREATE VIEW user_search_unique_attr AS - - SELECT ua.owner_id AS any_id, - ua.schema_id AS schema_id, - uav.booleanvalue AS booleanvalue, - uav.datevalue AS datevalue, - uav.doublevalue AS doublevalue, - uav.longvalue AS longvalue, - uav.stringvalue AS stringvalue - FROM UPlainAttrUniqueValue uav, UPlainAttr ua - WHERE uav.attribute_id = ua.id - - - CREATE VIEW user_search_attr AS - - SELECT ua.owner_id AS any_id, - ua.schema_id AS schema_id, - uav.booleanvalue AS booleanvalue, - uav.datevalue AS datevalue, - uav.doublevalue AS doublevalue, - uav.longvalue AS longvalue, - uav.stringvalue AS stringvalue - FROM UPlainAttrValue uav, UPlainAttr ua - WHERE uav.attribute_id = ua.id - - - CREATE VIEW user_search_urelationship AS - - SELECT m.user_id AS any_id, m.anyObject_id AS right_any_id, m.type_id AS type - FROM URelationship m - - - CREATE VIEW user_search_umembership AS - - SELECT m.user_id AS any_id, g.id AS group_id, g.name AS group_name - FROM UMembership m, SyncopeGroup g - WHERE m.group_id = g.id - - - CREATE VIEW user_search_role AS - - SELECT ss.user_id AS any_id, ss.role_id AS role_id - FROM SyncopeUser_SyncopeRole ss - - - CREATE VIEW user_search_priv AS - - SELECT ss.user_id AS any_id, sp.privilege_id AS privilege_id - FROM SyncopeUser_SyncopeRole ss, SyncopeRole_Privilege sp - WHERE ss.role_id = sp.role_id - - - CREATE VIEW user_search_dynpriv AS - - SELECT any_id, privilege_id - FROM DynRoleMembers drm, SyncopeRole_Privilege rp - WHERE drm.role_id = rp.role_id - - - CREATE VIEW user_search_auxClass AS - - SELECT st.user_id AS any_id, st.anyTypeClass_id AS anyTypeClass_id - FROM SyncopeUser_AnyTypeClass st - - - CREATE VIEW user_search_resource AS - - SELECT st.user_id AS any_id, st.resource_id AS resource_id - FROM SyncopeUser_ExternalResource st - - - CREATE VIEW user_search_group_res AS - - SELECT m.user_id AS any_id, st.resource_id AS resource_id - FROM UMembership m, SyncopeGroup r, SyncopeGroup_ExternalResource st - WHERE m.group_id = r.id AND st.group_id = r.id - - - - - CREATE VIEW anyObject_search AS - - SELECT a.id as any_id, a.* FROM AnyObject a - - - CREATE VIEW anyObject_search_unique_attr AS - - SELECT ua.owner_id AS any_id, - ua.schema_id AS schema_id, - uav.booleanvalue AS booleanvalue, - uav.datevalue AS datevalue, - uav.doublevalue AS doublevalue, - uav.longvalue AS longvalue, - uav.stringvalue AS stringvalue - FROM APlainAttrUniqueValue uav, APlainAttr ua - WHERE uav.attribute_id = ua.id - - - CREATE VIEW anyObject_search_attr AS - - SELECT ua.owner_id AS any_id, - ua.schema_id AS schema_id, - uav.booleanvalue AS booleanvalue, - uav.datevalue AS datevalue, - uav.doublevalue AS doublevalue, - uav.longvalue AS longvalue, - uav.stringvalue AS stringvalue - FROM APlainAttrValue uav, APlainAttr ua - WHERE uav.attribute_id = ua.id - - - CREATE VIEW anyObject_search_arelationship AS - - SELECT m.left_anyObject_id AS any_id, m.right_anyObject_id AS right_any_id, m.type_id AS type - FROM ARelationship m - - - CREATE VIEW anyObject_search_amembership AS - - SELECT m.anyObject_id AS any_id, g.id AS group_id, g.name AS group_name - FROM AMembership m, SyncopeGroup g - WHERE m.group_id = g.id - - - CREATE VIEW anyObject_search_auxClass AS - - SELECT st.anyObject_id AS any_id, st.anyTypeClass_id AS anyTypeClass_id - FROM AnyObject_AnyTypeClass st - - - CREATE VIEW anyObject_search_resource AS - - SELECT st.anyObject_id AS any_id, st.resource_id AS resource_id - FROM AnyObject_ExternalResource st - - - CREATE VIEW anyObject_search_group_res AS - - SELECT m.anyObject_id AS any_id, st.resource_id AS resource_id - FROM AMembership m, SyncopeGroup r, SyncopeGroup_ExternalResource st - WHERE m.group_id = r.id AND st.group_id = r.id - - - - - CREATE VIEW group_search AS - - SELECT r.id as any_id, r.* FROM SyncopeGroup r - - - CREATE VIEW group_search_unique_attr AS - - SELECT ua.owner_id AS any_id, - ua.schema_id AS schema_id, - uav.booleanvalue AS booleanvalue, - uav.datevalue AS datevalue, - uav.doublevalue AS doublevalue, - uav.longvalue AS longvalue, - uav.stringvalue AS stringvalue - FROM GPlainAttrUniqueValue uav, GPlainAttr ua - WHERE uav.attribute_id = ua.id - - - CREATE VIEW group_search_attr AS - - SELECT ua.owner_id AS any_id, - ua.schema_id AS schema_id, - uav.booleanvalue AS booleanvalue, - uav.datevalue AS datevalue, - uav.doublevalue AS doublevalue, - uav.longvalue AS longvalue, - uav.stringvalue AS stringvalue - FROM GPlainAttrValue uav, GPlainAttr ua - WHERE uav.attribute_id = ua.id - - - CREATE VIEW group_search_auxClass AS - - SELECT st.group_id AS any_id, st.anyTypeClass_id AS anyTypeClass_id - FROM SyncopeGroup_AnyTypeClass st - - - CREATE VIEW group_search_resource AS - - SELECT st.group_id AS any_id, st.resource_id AS resource_id - FROM SyncopeGroup_ExternalResource st - - - diff --git a/core/persistence-jpa/src/main/resources/views.xml b/core/persistence-jpa/src/main/resources/views.xml deleted file mode 100644 index e242f0ff922..00000000000 --- a/core/persistence-jpa/src/main/resources/views.xml +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - - CREATE TABLE UDynGroupMembers( - any_id CHAR(36), - group_id CHAR(36), - UNIQUE(any_id, group_id)) - - - CREATE TABLE ADynGroupMembers( - anyType_id VARCHAR(255), - any_id CHAR(36), - group_id CHAR(36), - UNIQUE(anyType_id, any_id, group_id)) - - - CREATE TABLE DynRoleMembers( - any_id CHAR(36), - role_id VARCHAR(255), - UNIQUE(any_id, role_id)) - - - CREATE TABLE DynRealmMembers( - any_id CHAR(36), - dynRealm_id VARCHAR(255), - UNIQUE(any_id, dynRealm_id)) - - - - - CREATE VIEW user_search AS - - SELECT u.id as any_id, u.* FROM SyncopeUser u - - - CREATE VIEW user_search_unique_attr AS - - SELECT ua.owner_id AS any_id, - ua.schema_id AS schema_id, - uav.booleanvalue AS booleanvalue, - uav.datevalue AS datevalue, - uav.doublevalue AS doublevalue, - uav.longvalue AS longvalue, - uav.stringvalue AS stringvalue - FROM UPlainAttrUniqueValue uav, UPlainAttr ua - WHERE uav.attribute_id = ua.id - - - CREATE VIEW user_search_attr AS - - SELECT ua.owner_id AS any_id, - ua.schema_id AS schema_id, - uav.booleanvalue AS booleanvalue, - uav.datevalue AS datevalue, - uav.doublevalue AS doublevalue, - uav.longvalue AS longvalue, - uav.stringvalue AS stringvalue - FROM UPlainAttrValue uav, UPlainAttr ua - WHERE uav.attribute_id = ua.id - - - CREATE VIEW user_search_urelationship AS - - SELECT m.user_id AS any_id, m.anyObject_id AS right_any_id, m.type_id AS type - FROM URelationship m - - - CREATE VIEW user_search_umembership AS - - SELECT m.user_id AS any_id, g.id AS group_id, g.name AS group_name - FROM UMembership m, SyncopeGroup g - WHERE m.group_id = g.id - - - CREATE VIEW user_search_role AS - - SELECT ss.user_id AS any_id, ss.role_id AS role_id - FROM SyncopeUser_SyncopeRole ss - - - CREATE VIEW user_search_priv AS - - SELECT ss.user_id AS any_id, sp.privilege_id AS privilege_id - FROM SyncopeUser_SyncopeRole ss, SyncopeRole_Privilege sp - WHERE ss.role_id = sp.role_id - - - CREATE VIEW user_search_dynpriv AS - - SELECT any_id, privilege_id - FROM DynRoleMembers drm, SyncopeRole_Privilege rp - WHERE drm.role_id = rp.role_id - - - CREATE VIEW user_search_auxClass AS - - SELECT st.user_id AS any_id, st.anyTypeClass_id AS anyTypeClass_id - FROM SyncopeUser_AnyTypeClass st - - - CREATE VIEW user_search_resource AS - - SELECT st.user_id AS any_id, st.resource_id AS resource_id - FROM SyncopeUser_ExternalResource st - - - CREATE VIEW user_search_group_res AS - - SELECT m.user_id AS any_id, st.resource_id AS resource_id - FROM UMembership m, SyncopeGroup r, SyncopeGroup_ExternalResource st - WHERE m.group_id = r.id AND st.group_id = r.id - - - - - CREATE VIEW anyObject_search AS - - SELECT a.id as any_id, a.* FROM AnyObject a - - - CREATE VIEW anyObject_search_unique_attr AS - - SELECT ua.owner_id AS any_id, - ua.schema_id AS schema_id, - uav.booleanvalue AS booleanvalue, - uav.datevalue AS datevalue, - uav.doublevalue AS doublevalue, - uav.longvalue AS longvalue, - uav.stringvalue AS stringvalue - FROM APlainAttrUniqueValue uav, APlainAttr ua - WHERE uav.attribute_id = ua.id - - - CREATE VIEW anyObject_search_attr AS - - SELECT ua.owner_id AS any_id, - ua.schema_id AS schema_id, - uav.booleanvalue AS booleanvalue, - uav.datevalue AS datevalue, - uav.doublevalue AS doublevalue, - uav.longvalue AS longvalue, - uav.stringvalue AS stringvalue - FROM APlainAttrValue uav, APlainAttr ua - WHERE uav.attribute_id = ua.id - - - CREATE VIEW anyObject_search_arelationship AS - - SELECT m.left_anyObject_id AS any_id, m.right_anyObject_id AS right_any_id, m.type_id AS type - FROM ARelationship m - - - CREATE VIEW anyObject_search_amembership AS - - SELECT m.anyObject_id AS any_id, g.id AS group_id, g.name AS group_name - FROM AMembership m, SyncopeGroup g - WHERE m.group_id = g.id - - - CREATE VIEW anyObject_search_auxClass AS - - SELECT st.anyObject_id AS any_id, st.anyTypeClass_id AS anyTypeClass_id - FROM AnyObject_AnyTypeClass st - - - CREATE VIEW anyObject_search_resource AS - - SELECT st.anyObject_id AS any_id, st.resource_id AS resource_id - FROM AnyObject_ExternalResource st - - - CREATE VIEW anyObject_search_group_res AS - - SELECT m.anyObject_id AS any_id, st.resource_id AS resource_id - FROM AMembership m, SyncopeGroup r, SyncopeGroup_ExternalResource st - WHERE m.group_id = r.id AND st.group_id = r.id - - - - - CREATE VIEW group_search AS - - SELECT r.id as any_id, r.* FROM SyncopeGroup r - - - CREATE VIEW group_search_unique_attr AS - - SELECT ua.owner_id AS any_id, - ua.schema_id AS schema_id, - uav.booleanvalue AS booleanvalue, - uav.datevalue AS datevalue, - uav.doublevalue AS doublevalue, - uav.longvalue AS longvalue, - uav.stringvalue AS stringvalue - FROM GPlainAttrUniqueValue uav, GPlainAttr ua - WHERE uav.attribute_id = ua.id - - - CREATE VIEW group_search_attr AS - - SELECT ua.owner_id AS any_id, - ua.schema_id AS schema_id, - uav.booleanvalue AS booleanvalue, - uav.datevalue AS datevalue, - uav.doublevalue AS doublevalue, - uav.longvalue AS longvalue, - uav.stringvalue AS stringvalue - FROM GPlainAttrValue uav, GPlainAttr ua - WHERE uav.attribute_id = ua.id - - - CREATE VIEW group_search_auxClass AS - - SELECT st.group_id AS any_id, st.anyTypeClass_id AS anyTypeClass_id - FROM SyncopeGroup_AnyTypeClass st - - - CREATE VIEW group_search_resource AS - - SELECT st.group_id AS any_id, st.resource_id AS resource_id - FROM SyncopeGroup_ExternalResource st - - - \ No newline at end of file diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java index ab726501f8a..ce7c865b48d 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/AbstractTest.java @@ -18,22 +18,194 @@ */ package org.apache.syncope.core.persistence.jpa; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.fail; + +import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; import jakarta.persistence.EntityManager; -import java.util.Optional; +import java.io.InputStream; +import java.util.Map; +import java.util.Properties; +import java.util.function.Supplier; +import java.util.stream.Stream; import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; import org.apache.syncope.core.persistence.api.entity.EntityFactory; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; -import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; -import org.apache.syncope.core.persistence.jpa.dao.JPAPlainAttrValueDAO; -import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExtImpl; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.annotation.DirtiesContext; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import org.testcontainers.containers.MariaDBContainer; +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.oracle.OracleContainer; @SpringJUnitConfig(classes = { MasterDomain.class, PersistenceTestContext.class }) -@DirtiesContext public abstract class AbstractTest { + private static String JDBC_DRIVER; + + private static String DATABASE_PLATFORM; + + private static String ORM = "META-INF/spring-orm.xml"; + + private static String INDEXES = "classpath:META-INF/indexes.xml"; + + private static String VIEWS = "classpath:META-INF/views.xml"; + + private static Supplier JDBC_URL_SUPPLIER; + + private static Supplier JDBC2_URL_SUPPLIER; + + private static Supplier DB_USER_SUPPLIER = () -> "syncope"; + + private static Supplier DB_PWD_SUPPLIER = () -> "syncope"; + + private static Supplier DB2_USER_SUPPLIER = () -> "syncope"; + + private static Supplier DB2_PWD_SUPPLIER = () -> "syncope"; + + private static boolean classExists(final String name) { + try { + Class.forName(name, false, AbstractTest.class.getClassLoader()); + return true; + } catch (ClassNotFoundException e) { + // ignore + return false; + } + } + + static { + String dockerMySQLVersion = null; + String dockerMariaDBVersion = null; + String dockerOracleVersion = null; + try (InputStream propStream = AbstractTest.class.getResourceAsStream("/test.properties")) { + Properties props = new Properties(); + props.load(propStream); + + dockerMySQLVersion = props.getProperty("docker.mysql.version"); + dockerMariaDBVersion = props.getProperty("docker.mariadb.version"); + dockerOracleVersion = props.getProperty("docker.oracle.version"); + } catch (Exception e) { + fail("Could not load /test.properties", e); + } + assertNotNull(dockerMySQLVersion); + assertNotNull(dockerMariaDBVersion); + assertNotNull(dockerOracleVersion); + + if (classExists("org.postgresql.Driver")) { + JDBC_DRIVER = "org.postgresql.Driver"; + DATABASE_PLATFORM = "org.apache.openjpa.jdbc.sql.PostgresDictionary"; + ORM = "META-INF/spring-orm.xml"; + INDEXES = "classpath:META-INF/indexes.xml"; + VIEWS = "classpath:META-INF/views.xml"; + + try { + EmbeddedPostgres pg = EmbeddedPostgres.builder().start(); + JdbcTemplate jdbcTemplate = new JdbcTemplate(pg.getPostgresDatabase()); + Stream.of("syncope", "syncopetwo").forEach(key -> { + jdbcTemplate.execute("CREATE DATABASE " + key); + + jdbcTemplate.execute("CREATE USER " + key + " WITH PASSWORD '" + key + "'"); + jdbcTemplate.execute("ALTER DATABASE " + key + " OWNER TO " + key); + }); + + JDBC_URL_SUPPLIER = () -> pg.getJdbcUrl("syncope", "syncope") + "&stringtype=unspecified"; + JDBC2_URL_SUPPLIER = () -> pg.getJdbcUrl("syncopetwo", "syncopetwo") + "&stringtype=unspecified"; + DB2_USER_SUPPLIER = () -> "syncopetwo"; + DB2_PWD_SUPPLIER = () -> "syncopetwo"; + } catch (Exception e) { + fail("Could not setup PostgreSQL databases", e); + } + } else if (classExists("com.mysql.cj.jdbc.Driver")) { + JDBC_DRIVER = "com.mysql.cj.jdbc.Driver"; + DATABASE_PLATFORM = "org.apache.openjpa.jdbc.sql.MySQLDictionary(" + + "blobTypeName=LONGBLOB,dateFractionDigits=3,useSetStringForClobs=true)"; + ORM = "META-INF/mysql/spring-orm.xml"; + INDEXES = "classpath:META-INF/mysql/indexes.xml"; + VIEWS = "classpath:META-INF/mysql/views.xml"; + + MySQLContainer masterDomain = new MySQLContainer<>("mysql:" + dockerMySQLVersion). + withTmpFs(Map.of("/var/lib/mysql", "rw")). + withDatabaseName("syncope").withPassword("syncope").withUsername("syncope"). + withUrlParam("characterEncoding", "UTF-8"). + withReuse(true); + masterDomain.start(); + JDBC_URL_SUPPLIER = () -> masterDomain.getJdbcUrl(); + + MySQLContainer twoDomain = new MySQLContainer<>("mysql:" + dockerMySQLVersion). + withTmpFs(Map.of("/var/lib/mysql", "rw")). + withDatabaseName("syncope").withPassword("syncope").withUsername("syncope"). + withUrlParam("characterEncoding", "UTF-8"). + withReuse(true); + twoDomain.start(); + JDBC2_URL_SUPPLIER = () -> twoDomain.getJdbcUrl(); + } else if (classExists("org.mariadb.jdbc.Driver")) { + JDBC_DRIVER = "org.mariadb.jdbc.Driver"; + DATABASE_PLATFORM = "org.apache.openjpa.jdbc.sql.MariaDBDictionary(" + + "blobTypeName=LONGBLOB,dateFractionDigits=3)"; + ORM = "META-INF/mariadb/spring-orm.xml"; + INDEXES = "classpath:META-INF/mariadb/indexes.xml"; + VIEWS = "classpath:META-INF/mariadb/views.xml"; + + MariaDBContainer masterDomain = new MariaDBContainer<>("mariadb:" + dockerMariaDBVersion). + withTmpFs(Map.of("/var/lib/mysql", "rw")). + withDatabaseName("syncope").withPassword("syncope").withUsername("syncope"). + withUrlParam("characterEncoding", "UTF-8"). + withReuse(true); + masterDomain.start(); + JDBC_URL_SUPPLIER = () -> masterDomain.getJdbcUrl(); + + MariaDBContainer twoDomain = new MariaDBContainer<>("mariadb:" + dockerMariaDBVersion). + withTmpFs(Map.of("/var/lib/mysql", "rw")). + withDatabaseName("syncope").withPassword("syncope").withUsername("syncope"). + withUrlParam("characterEncoding", "UTF-8"). + withReuse(true); + twoDomain.start(); + JDBC2_URL_SUPPLIER = () -> twoDomain.getJdbcUrl(); + + // https://jira.mariadb.org/browse/MDEV-27898 + DB_USER_SUPPLIER = () -> "root"; + DB_PWD_SUPPLIER = () -> "syncope"; + DB2_USER_SUPPLIER = () -> "root"; + DB2_PWD_SUPPLIER = () -> "syncope"; + } else if (classExists("oracle.jdbc.OracleDriver")) { + JDBC_DRIVER = "oracle.jdbc.OracleDriver"; + DATABASE_PLATFORM = "org.apache.openjpa.jdbc.sql.OracleDictionary"; + ORM = "META-INF/oracle/spring-orm.xml"; + INDEXES = "classpath:META-INF/oracle/indexes.xml"; + VIEWS = "classpath:META-INF/oracle/views.xml"; + + OracleContainer masterDomain = new OracleContainer("gvenzl/oracle-free:" + dockerOracleVersion). + withDatabaseName("syncope").withPassword("syncope").withUsername("syncope"). + withReuse(true); + masterDomain.start(); + JDBC_URL_SUPPLIER = () -> masterDomain.getJdbcUrl(); + + OracleContainer twoDomain = new OracleContainer("gvenzl/oracle-free:" + dockerOracleVersion). + withDatabaseName("syncope").withPassword("syncope").withUsername("syncope"). + withReuse(true); + twoDomain.start(); + JDBC2_URL_SUPPLIER = () -> twoDomain.getJdbcUrl(); + } + } + + @DynamicPropertySource + static void configureProperties(final DynamicPropertyRegistry registry) { + registry.add("JDBC_DRIVER", () -> JDBC_DRIVER); + registry.add("DATABASE_PLATFORM", () -> DATABASE_PLATFORM); + registry.add("ORM", () -> ORM); + registry.add("INDEXES", () -> INDEXES); + registry.add("VIEWS", () -> VIEWS); + + registry.add("DB_URL", JDBC_URL_SUPPLIER::get); + registry.add("DB_USER", DB_USER_SUPPLIER::get); + registry.add("DB_PASSWORD", DB_PWD_SUPPLIER::get); + + registry.add("DB2_URL", JDBC2_URL_SUPPLIER::get); + registry.add("DB2_USER", DB2_USER_SUPPLIER::get); + registry.add("DB2_PASSWORD", DB2_PWD_SUPPLIER::get); + } + @Autowired protected EntityFactory entityFactory; @@ -43,13 +215,4 @@ public abstract class AbstractTest { @Autowired protected EntityManager entityManager; - protected > Optional findPlainAttr(final String key, final Class reference) { - return Optional.ofNullable( - reference.cast(entityManager.find(PlainSchemaRepoExtImpl.getEntityReference(reference), key))); - } - - protected Optional findPlainAttrValue(final String key, final Class reference) { - return Optional.ofNullable( - reference.cast(entityManager.find(JPAPlainAttrValueDAO.getEntityReference(reference), key))); - } } diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/PersistenceTestContext.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/PersistenceTestContext.java index d5ee6024f4a..6859a52e996 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/PersistenceTestContext.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/PersistenceTestContext.java @@ -47,7 +47,13 @@ import org.springframework.core.io.Resource; import org.springframework.jndi.JndiObjectFactoryBean; -@Import(PersistenceContext.class) +@Import({ + PersistenceContext.class, + PGPersistenceContext.class, + MySQLPersistenceContext.class, + MariaDBPersistenceContext.class, + OraclePersistenceContext.class +}) @Configuration(proxyBeanMethods = false) public class PersistenceTestContext { diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/TestInitializer.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/TestInitializer.java index 30c64e217af..abe1fb7de3a 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/TestInitializer.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/TestInitializer.java @@ -65,7 +65,7 @@ public void afterPropertiesSet() throws Exception { contentLoader.load(SyncopeConstants.MASTER_DOMAIN); if (domainHolder.getDomains().containsKey("Two")) { - AuthContextUtils.runAsAdmin("Two", () -> entityManagerFactory.initJPASchema()); + AuthContextUtils.runAsAdmin("Two", () -> entityManagerFactory.createEntityManager()); AuthContextUtils.runAsAdmin("Two", () -> contentLoader.load("Two")); } diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AttrRepoTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AttrRepoTest.java index 766178f8a97..bad9bcb9f3c 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AttrRepoTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AttrRepoTest.java @@ -142,7 +142,7 @@ public void saveWithLdapRepo() { public void saveWithJDBCRepo() { JDBCAttrRepoConf conf = new JDBCAttrRepoConf(); conf.setSql("SELECT * FROM table WHERE name=?"); - conf.setUrl("jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1"); + conf.setUrl("jdbc:tc:postgresql:16-alpine:///db"); conf.setUser("username"); conf.setPassword("password"); diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java index cb8084b779b..a559e28e623 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/MultitenancyTest.java @@ -36,10 +36,12 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.transaction.annotation.Transactional; -@Transactional @Tag("multitenancy") +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) +@Transactional public class MultitenancyTest extends AbstractTest { static { diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java index 2777fcb6ca3..b42adcd0ae7 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java @@ -42,12 +42,10 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.jpa.AbstractTest; import org.apache.syncope.core.spring.security.Encryptor; import org.apache.syncope.core.spring.security.SecureRandomUtils; -import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; @@ -67,21 +65,6 @@ public class PlainAttrTest extends AbstractTest { @Autowired private PlainAttrValidationManager validator; - @Tag("plainAttrTable") - @Test - public void findByKey() { - assertTrue(findPlainAttr("01f22fbd-b672-40af-b528-686d9b27ebc4", UPlainAttr.class).isPresent()); - assertTrue(findPlainAttr("9d0d9e40-1b18-488e-9482-37dab82163c9", UPlainAttr.class).isPresent()); - } - - @Tag("plainAttrTable") - @Test - public void read() { - UPlainAttr attribute = findPlainAttr("01f22fbd-b672-40af-b528-686d9b27ebc4", UPlainAttr.class).orElseThrow(); - assertTrue(attribute.getValues().isEmpty()); - assertNotNull(attribute.getUniqueValue()); - } - @Test public void save() throws ClassNotFoundException { User user = userDAO.findById("1417acbe-cbf6-4277-9372-e75e04f97000").orElseThrow(); @@ -133,42 +116,6 @@ public void invalidValueList() { assertTrue(iee.hasViolation(EntityViolationType.InvalidValueList)); } - @Tag("plainAttrTable") - @Test - public void invalidPlainAttr() { - User user = userDAO.findById("1417acbe-cbf6-4277-9372-e75e04f97000").orElseThrow(); - - PlainSchema emailSchema = plainSchemaDAO.findById("email").orElseThrow(); - - PlainSchema fullnameSchema = plainSchemaDAO.findById("fullname").orElseThrow(); - - UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class); - attr.setOwner(user); - attr.setSchema(emailSchema); - - UPlainAttrUniqueValue uauv = entityFactory.newEntity(UPlainAttrUniqueValue.class); - uauv.setAttr(attr); - uauv.setSchema(fullnameSchema); - uauv.setStringValue("a value"); - - attr.setUniqueValue(uauv); - - user.add(attr); - - InvalidEntityException iee = null; - try { - userDAO.save(user); - fail("This should not happen"); - } catch (InvalidEntityException e) { - iee = e; - } - assertNotNull(iee); - // for attr because no values are set - assertTrue(iee.hasViolation(EntityViolationType.InvalidValueList)); - // for uauv because uauv.schema and uauv.attr.schema are different - assertTrue(iee.hasViolation(EntityViolationType.InvalidPlainAttr)); - } - @Test public void saveWithEncrypted() throws Exception { User user = userDAO.findById("1417acbe-cbf6-4277-9372-e75e04f97000").orElseThrow(); @@ -265,15 +212,4 @@ public void saveWithBinary() throws UnsupportedEncodingException { assertEquals(1, photo.getValues().size()); assertTrue(Arrays.equals(bytes, photo.getValues().get(0).getBinaryValue())); } - - @Tag("plainAttrTable") - @Test - public void delete() { - UPlainAttr attribute = findPlainAttr("9d0d9e40-1b18-488e-9482-37dab82163c9", UPlainAttr.class).orElseThrow(); - String attrSchemaName = attribute.getSchema().getKey(); - - plainSchemaDAO.delete(attribute); - - assertTrue(plainSchemaDAO.findById(attrSchemaName).isPresent()); - } } diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java index 3cdecd4d57c..b18c27c427a 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java @@ -49,7 +49,6 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; -import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.group.TypeExtension; import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership; @@ -62,8 +61,10 @@ import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.transaction.annotation.Transactional; +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) @Transactional public class GroupTest extends AbstractTest { @@ -222,8 +223,6 @@ public void delete() { assertTrue(groupDAO.findById("b1f7c12d-ec83-441f-a50e-1691daaedf3b").isEmpty()); assertEquals(before - 1, userDAO.findAllGroups(userDAO.findByUsername("verdi").orElseThrow()).size()); - assertTrue(findPlainAttr("f82fc61f-8e74-4a4b-9f9e-b8a41f38aad9", GPlainAttr.class).isEmpty()); - assertTrue(findPlainAttrValue("49f35879-2510-4f11-a901-24152f753538", GPlainAttrValue.class).isEmpty()); assertTrue(plainSchemaDAO.findById("icon").isPresent()); } diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainAttrTest.java deleted file mode 100644 index e913040b6d0..00000000000 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainAttrTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.jpa.outer; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -import org.apache.syncope.common.lib.types.AnyTypeKind; -import org.apache.syncope.core.persistence.api.attrvalue.InvalidEntityException; -import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO; -import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue; -import org.apache.syncope.core.persistence.jpa.AbstractTest; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; - -@Tag("plainAttrTable") -@Transactional -public class PlainAttrTest extends AbstractTest { - - @Autowired - private PlainSchemaDAO plainSchemaDAO; - - @Autowired - private PlainAttrValueDAO plainAttrValueDAO; - - @Test - public void deleteAttr() { - plainSchemaDAO.delete(findPlainAttr("35f407a2-d254-4890-9e45-5a7dd8c8df7d", UPlainAttr.class).orElseThrow()); - - entityManager.flush(); - - assertTrue(findPlainAttr("35f407a2-d254-4890-9e45-5a7dd8c8df7d", UPlainAttr.class).isEmpty()); - assertTrue(findPlainAttrValue("0c67225a-030a-4c56-b337-17cf7a311f0f", UPlainAttrValue.class).isEmpty()); - } - - @Test - public void deleteAllAttValues() { - UPlainAttrValue value = findPlainAttrValue( - "7034de3b-3687-4db5-8454-363468f1a9de", UPlainAttrValue.class).orElseThrow(); - assertNotNull(value); - - plainAttrValueDAO.deleteAll(value.getAttr(), anyUtilsFactory.getInstance(AnyTypeKind.USER)); - - assertTrue(findPlainAttrValue("7034de3b-3687-4db5-8454-363468f1a9de", UPlainAttrValue.class).isEmpty()); - - // by removing all values, the related attribute is not valid any more - try { - entityManager.flush(); - fail(); - } catch (InvalidEntityException e) { - assertNotNull(e); - } - } -} diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java index 77867e6e7a1..7eab4b605cb 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java @@ -26,7 +26,6 @@ import jakarta.persistence.EntityExistsException; import java.util.List; -import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.syncope.common.lib.SyncopeConstants; @@ -41,7 +40,6 @@ import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; import org.apache.syncope.core.persistence.jpa.AbstractTest; import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails; import org.apache.syncope.core.spring.security.SyncopeGrantedAuthority; @@ -160,8 +158,6 @@ public void deleteFullname() { mapItems = getMappingItems("fullname"); assertTrue(mapItems.isEmpty()); - assertTrue(findPlainAttr("01f22fbd-b672-40af-b528-686d9b27ebc4", UPlainAttr.class).isEmpty()); - assertTrue(findPlainAttr(UUID.randomUUID().toString(), UPlainAttr.class).isEmpty()); assertFalse(userDAO.findByUsername("rossini").orElseThrow().getPlainAttr("fullname").isPresent()); assertFalse(userDAO.findByUsername("vivaldi").orElseThrow().getPlainAttr("fullname").isPresent()); } diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java index 3a282dd0edd..48501b12473 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java @@ -43,24 +43,20 @@ import org.apache.syncope.core.persistence.api.entity.AnyUtils; import org.apache.syncope.core.persistence.api.entity.Delegation; import org.apache.syncope.core.persistence.api.entity.DerSchema; -import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.Role; import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; import org.apache.syncope.core.persistence.api.entity.user.UMembership; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; -import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue; import org.apache.syncope.core.persistence.api.entity.user.URelationship; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.jpa.AbstractTest; -import org.apache.syncope.core.persistence.jpa.entity.user.JPALAPlainAttr; -import org.apache.syncope.core.persistence.jpa.entity.user.JPALAPlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.user.JPALinkedAccount; -import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.transaction.annotation.Transactional; +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) @Transactional public class UserTest extends AbstractTest { @@ -108,8 +104,6 @@ public void delete() { entityManager.flush(); assertTrue(userDAO.findByUsername("bellini").isEmpty()); - assertTrue(findPlainAttr(UUID.randomUUID().toString(), UPlainAttr.class).isEmpty()); - assertTrue(findPlainAttrValue(UUID.randomUUID().toString(), UPlainAttrValue.class).isEmpty()); assertTrue(plainSchemaDAO.findById("loginDate").isPresent()); memberships = groupDAO.findUMemberships(groupDAO.findByName("managingDirector").orElseThrow()); @@ -219,29 +213,6 @@ public void findLinkedAccount() { assertEquals(account, accounts.get(0)); } - @Tag("plainAttrTable") - @Test - public void deleteLinkedAccountUserCascade() { - LinkedAccount account = newLinkedAccount("deleteLinkedAccountUserCascade"); - assertNotNull(account.getKey()); - - LAPlainAttr plainAttr = account.getPlainAttrs().get(0); - assertNotNull(entityManager.find(JPALAPlainAttr.class, plainAttr.getKey())); - - PlainAttrValue plainAttrValue = account.getPlainAttrs().get(0).getValues().get(0); - assertNotNull(entityManager.find(JPALAPlainAttrValue.class, plainAttrValue.getKey())); - - LinkedAccount found = entityManager.find(JPALinkedAccount.class, account.getKey()); - assertEquals(account, found); - - userDAO.delete(account.getOwner()); - entityManager.flush(); - - assertNull(entityManager.find(JPALinkedAccount.class, account.getKey())); - assertNull(entityManager.find(JPALAPlainAttr.class, plainAttr.getKey())); - assertNull(entityManager.find(JPALAPlainAttrValue.class, plainAttrValue.getKey())); - } - @Test public void deleteLinkedAccountResourceCascade() { LinkedAccount account = newLinkedAccount("deleteLinkedAccountResourceCascade"); diff --git a/core/persistence-jpa/src/test/resources/core-test.properties b/core/persistence-jpa/src/test/resources/core-test.properties index 4fdf1f95b4a..41ce20b0c7d 100644 --- a/core/persistence-jpa/src/test/resources/core-test.properties +++ b/core/persistence-jpa/src/test/resources/core-test.properties @@ -20,21 +20,26 @@ security.anonymousUser=${anonymousUser} security.jwsKey=${jwsKey} security.secretKey=${secretKey} +persistence.indexesXML=${INDEXES} +persistence.viewsXML=${VIEWS} + persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=org.h2.Driver -persistence.domain[0].jdbcURL=jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1 -persistence.domain[0].dbUsername=sa -persistence.domain[0].dbPassword= -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.H2Dictionary +persistence.domain[0].jdbcDriver=${JDBC_DRIVER} +persistence.domain[0].jdbcURL=${DB_URL} +persistence.domain[0].dbUsername=${DB_USER} +persistence.domain[0].dbPassword=${DB_PASSWORD} +persistence.domain[0].databasePlatform=${DATABASE_PLATFORM} +persistence.domain[0].orm=${ORM} persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 persistence.domain[1].key=Two -persistence.domain[1].jdbcDriver=org.h2.Driver -persistence.domain[1].jdbcURL=jdbc:h2:mem:syncopetwo;DB_CLOSE_DELAY=-1 -persistence.domain[1].dbUsername=sa -persistence.domain[1].dbPassword= -persistence.domain[1].databasePlatform=org.apache.openjpa.jdbc.sql.H2Dictionary +persistence.domain[1].jdbcDriver=${JDBC_DRIVER} +persistence.domain[1].jdbcURL=${DB2_URL} +persistence.domain[1].dbUsername=${DB2_USER} +persistence.domain[1].dbPassword=${DB2_PASSWORD} +persistence.domain[1].databasePlatform=${DATABASE_PLATFORM} +persistence.domain[1].orm=${ORM} persistence.domain[1].poolMaxActive=20 persistence.domain[1].poolMinIdle=5 persistence.domain[1].adminPassword=2AA60A8FF7FCD473D321E0146AFD9E26DF395147 diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml index b4bb9f766e1..4b3244d4393 100644 --- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml @@ -61,7 +61,7 @@ under the License. jsonConf='{"_class":"org.apache.syncope.common.lib.policy.DefaultAttrReleasePolicyConf","releaseAttrs":{},"allowedAttrs":[],"excludedAttrs":[],"includeOnlyAttrs":[],"principalIdAttr":null,"principalAttrRepoConf":{"mergingStrategy":"MULTIVALUED","ignoreResolvedAttributes":false,"expiration":0,"timeUnit":"HOURS","attrRepos":[]}}'/> - + - @@ -120,6 +120,138 @@ under the License. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" + plainAttrs="[{"values":[{"stringValue":"Canon MFC8030"}],"schema":"model"},{"values":[{"stringValue":"1st floor"}],"schema":"location"}]"/> + creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" + plainAttrs="[{"values":[{"stringValue":"HP Laserjet 1300n"}],"schema":"model"},{"values":[{"stringValue":"2nd floor"}],"schema":"location"}]"/> - + creationDate="2021-04-15 12:45:00" lastChangeDate="2010-10-20 11:00:00" + plainAttrs="[]"/> + @@ -179,41 +314,49 @@ under the License. password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1" realm_id="c5b75db1-fce7-470f-b780-3b9934d82a9d" username="rossini" creator="admin" lastModifier="admin" - creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0"/> + creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0" + plainAttrs='[{"values":[{"stringValue":"G"}],"schema":"ctype"},{"values":[{"stringValue":"Gioacchino"}],"schema":"firstname"},{"values":[{"stringValue":"Rossini"}],"schema":"surname"},{"values":[{"dateValue":"2009-05-26T00:00:00+02:00"},{"dateValue":"2010-05-26T00:00:00+02:00"}],"schema":"loginDate"},{"uniqueValue":{"stringValue":"Gioacchino Rossini"},"schema":"fullname"},{"uniqueValue":{"stringValue":"rossini@apache.org"},"schema":"userId"}]'/> + creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0" + plainAttrs='[{"values":[{"stringValue":"Giuseppe"}],"schema":"firstname"},{"values":[{"stringValue":"Verdi"}],"schema":"surname"},{"values":[{"stringValue":"verdi@syncope.org"}],"schema":"email"},{"uniqueValue":{"stringValue":"Giuseppe Verdi"},"schema":"fullname"},{"uniqueValue":{"stringValue":"verdi@apache.org"},"schema":"userId"}]'/> + creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0" + plainAttrs='[{"values":[{"stringValue":"Antonio"}],"schema":"firstname"},{"values":[{"stringValue":"Vivaldi"}],"schema":"surname"},{"values":[{"stringValue":"vivaldi@syncope.org"}],"schema":"email"},{"values":[{"stringValue":"F"}],"schema":"ctype"},{"uniqueValue":{"stringValue":"Antonio Vivaldi"},"schema":"fullname"},{"uniqueValue":{"stringValue":"vivaldi@apache.org"},"schema":"userId"}]'/> + creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" + lastLoginDate="2016-03-03 15:21:22" suspended="0" + plainAttrs='[{"values":[{"stringValue":"Vincenzo"}],"schema":"firstname"},{"values":[{"stringValue":"Bellini"}],"schema":"surname"},{"values":[{"dateValue":"2009-06-24T00:00:00+02:00"}],"schema":"loginDate"},{"values":[{"booleanValue":true}],"schema":"cool"},{"values":[{"stringValue":"M"}],"schema":"gender"},{"uniqueValue":{"stringValue":"Vincenzo Bellini"},"schema":"fullname"},{"uniqueValue":{"stringValue":"bellini@apache.org"},"schema":"userId"}]'/> + creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" suspended="0" + plainAttrs='[{"values":[{"stringValue":"Giacomo"}],"schema":"firstname"},{"values":[{"stringValue":"Puccini"}],"schema":"surname"},{"uniqueValue":{"stringValue":"Giacomo Puccini"},"schema":"fullname"},{"uniqueValue":{"stringValue":"puccini@apache.org"},"schema":"userId"}]'/> + creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" + plainAttrs='[{"values":[{"stringValue":"niceIcon"}],"schema":"icon"},{"values":[{"booleanValue":true}],"schema":"show"},{"values":[{"stringValue":"sx"}],"schema":"rderived_sx"},{"values":[{"stringValue":"dx"}],"schema":"rderived_dx"}]'/> + creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" + plainAttrs="[{"values":[{"stringValue":"badIcon"}],"schema":"icon"}]"/> + creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" + plainAttrs="[{"values":[{"stringValue":"icon4"}],"schema":"icon"}]"/> + creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" + plainAttrs="[{"values":[{"stringValue":"icon6"}],"schema":"icon"}]"/> + creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" + plainAttrs="[{"values":[{"stringValue":"r12"}],"schema":"title"}]"/> + creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00" + plainAttrs="[{"values":[{"stringValue":"r13"}],"schema":"title"}]"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -545,7 +460,7 @@ under the License. body='{"_class":"org.apache.syncope.common.lib.policy.DefaultPushCorrelationRuleConf","name":"org.apache.syncope.common.lib.policy.DefaultPushCorrelationRuleConf","schemas":["surname"]}'/> - + + enforceMandatoryCondition="1" overrideCapabilities="0" + propagationPriority="0" provisions='[{"anyType":"USER","objectClass":"__ACCOUNT__","auxClasses":[],"syncToken":null,"ignoreCaseMatch":false,"uidOnCreate":null,"mapping":{"connObjectLink":null,"items":[{"intAttrName":"firstname","extAttrName":"firstName","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"key","extAttrName":"key","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"password","extAttrName":"__PASSWORD__","connObjectKey":false,"password":true,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"username","extAttrName":"username","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"email","extAttrName":"email","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]},{"intAttrName":"surname","extAttrName":"surname","connObjectKey":false,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}],"linkingItems":[],"connObjectKeyItem":{"intAttrName":"key","extAttrName":"key","connObjectKey":true,"password":false,"mandatoryCondition":"true","purpose":"BOTH","propagationJEXLTransformer":null,"pullJEXLTransformer":null,"transformers":[]}},"virSchemas":[]}]'/> @@ -759,7 +674,7 @@ under the License. - + @@ -771,7 +686,7 @@ under the License. - + @@ -1038,7 +953,7 @@ $$ } traceLevel="FAILURES" recipientsFIQL="$groups==7" recipientAttrName="email" active="1" events='["[CUSTOM]:[]:[]:[unexisting1]:[FAILURE]", "[CUSTOM]:[]:[]:[unexisting2]:[SUCCESS]"]'/> - + + @@ -1097,5 +1013,4 @@ $$ } - diff --git a/core/persistence-jpa/src/test/resources/simplelogger.properties b/core/persistence-jpa/src/test/resources/simplelogger.properties index 929ded23352..828cc0f1057 100644 --- a/core/persistence-jpa/src/test/resources/simplelogger.properties +++ b/core/persistence-jpa/src/test/resources/simplelogger.properties @@ -19,4 +19,6 @@ # Possible values: "trace", "debug", "info", "warn", or "error" org.slf4j.simpleLogger.defaultLogLevel=debug org.slf4j.simpleLogger.log.org.springframework.jdbc.core.JdbcTemplate=error +org.slf4j.simpleLogger.log.org.springframework.jdbc.datasource.DataSourceUtils=error +org.slf4j.simpleLogger.log.com.github.dockerjava.zerodep.shaded=error diff --git a/core/persistence-jpa-json/src/test/resources/simplelogger.properties b/core/persistence-jpa/src/test/resources/test.properties similarity index 75% rename from core/persistence-jpa-json/src/test/resources/simplelogger.properties rename to core/persistence-jpa/src/test/resources/test.properties index 4f528c65c98..e772d2ea882 100644 --- a/core/persistence-jpa-json/src/test/resources/simplelogger.properties +++ b/core/persistence-jpa/src/test/resources/test.properties @@ -14,8 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. - -# See http://www.slf4j.org/api/org/slf4j/impl/SimpleLogger.html -# Possible values: "trace", "debug", "info", "warn", or "error" -org.slf4j.simpleLogger.defaultLogLevel=debug -org.slf4j.simpleLogger.log.org.springframework.jdbc.core.JdbcTemplate=error +docker.mysql.version=${docker.mysql.version} +docker.mariadb.version=${docker.mariadb.version} +docker.oracle.version=${docker.oracle.version} diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java index 30d54ef4dd5..f5a716fa907 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java @@ -211,13 +211,13 @@ import org.apache.syncope.core.persistence.neo4j.entity.Neo4jRealm; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jRole; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jVirSchema; -import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jAPlainAttr; +import org.apache.syncope.core.persistence.neo4j.entity.anyobject.JSONAPlainAttr; import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jAnyObject; -import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jGPlainAttr; +import org.apache.syncope.core.persistence.neo4j.entity.group.JSONGPlainAttr; import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jGroup; import org.apache.syncope.core.persistence.neo4j.entity.task.Neo4jTaskUtilsFactory; -import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jLAPlainAttr; -import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jUPlainAttr; +import org.apache.syncope.core.persistence.neo4j.entity.user.JSONLAPlainAttr; +import org.apache.syncope.core.persistence.neo4j.entity.user.JSONUPlainAttr; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jUser; import org.apache.syncope.core.persistence.neo4j.spring.CacheCleaningTransactionExecutionListener; import org.apache.syncope.core.persistence.neo4j.spring.DomainRoutingDriver; @@ -356,23 +356,23 @@ public PlatformTransactionManager transactionManager( } @Bean(name = "uPlainAttrsConverter") - public Neo4jPersistentPropertyToMapConverter> uPlainAttrsConverter() { - return new PlainAttrsConverter<>(Neo4jUPlainAttr.class); + public Neo4jPersistentPropertyToMapConverter> uPlainAttrsConverter() { + return new PlainAttrsConverter<>(JSONUPlainAttr.class); } @Bean(name = "laPlainAttrsConverter") - public Neo4jPersistentPropertyToMapConverter> laPlainAttrsConverter() { - return new PlainAttrsConverter<>(Neo4jLAPlainAttr.class); + public Neo4jPersistentPropertyToMapConverter> laPlainAttrsConverter() { + return new PlainAttrsConverter<>(JSONLAPlainAttr.class); } @Bean(name = "gPlainAttrsConverter") - public Neo4jPersistentPropertyToMapConverter> gPlainAttrsConverter() { - return new PlainAttrsConverter<>(Neo4jGPlainAttr.class); + public Neo4jPersistentPropertyToMapConverter> gPlainAttrsConverter() { + return new PlainAttrsConverter<>(JSONGPlainAttr.class); } @Bean(name = "aPlainAttrsConverter") - public Neo4jPersistentPropertyToMapConverter> aPlainAttrsConverter() { - return new PlainAttrsConverter<>(Neo4jAPlainAttr.class); + public Neo4jPersistentPropertyToMapConverter> aPlainAttrsConverter() { + return new PlainAttrsConverter<>(JSONAPlainAttr.class); } @ConditionalOnMissingBean diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AbstractAnyRepoExt.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AbstractAnyRepoExt.java index 11a84440b1e..c342094a1c7 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AbstractAnyRepoExt.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/AbstractAnyRepoExt.java @@ -63,11 +63,8 @@ import org.apache.syncope.core.persistence.neo4j.entity.EntityCacheKey; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jDynRealm; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jExternalResource; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainAttr; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; import org.apache.syncope.core.spring.security.AuthContextUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.data.neo4j.core.Neo4jClient; import org.springframework.data.neo4j.core.Neo4jTemplate; import org.springframework.transaction.annotation.Propagation; @@ -76,8 +73,6 @@ public abstract class AbstractAnyRepoExt, N extends AbstractAny> extends AbstractDAO implements AnyRepoExt { - protected static final Logger LOG = LoggerFactory.getLogger(AnyRepoExt.class); - /** * Split an attribute value recurring on provided literals/tokens. * @@ -196,7 +191,7 @@ public List findByPlainAttrValue( if (attrValue instanceof PlainAttrUniqueValue plainAttrUniqueValue) { attr.setUniqueValue(plainAttrUniqueValue); } else { - ((Neo4jPlainAttr) attr).add(attrValue); + attr.add(attrValue); } String op; @@ -315,7 +310,7 @@ public List findByDerAttrValue(final DerSchema derSchema, final String value, } else { PlainAttrValue attrValue = anyUtils.newPlainAttrValue(); attrValue.setStringValue(attrValues.get(i)); - ((Neo4jPlainAttr) attr).add(attrValue); + attr.add(attrValue); } String op; @@ -467,13 +462,13 @@ public List findByResourcesContaining(final ExternalResource resource) { protected void checkBeforeSave(final A any) { // check UNIQUE constraints any.getPlainAttrs().stream().filter(attr -> attr.getUniqueValue() != null).forEach(attr -> { - PlainSchema schema = attr.getSchema(); - Optional other = findByPlainAttrUniqueValue(schema, attr.getUniqueValue(), false); + Optional other = findByPlainAttrUniqueValue(attr.getSchema(), attr.getUniqueValue(), false); if (other.isEmpty() || other.get().getKey().equals(any.getKey())) { - LOG.debug("No duplicate value found for {}", attr.getUniqueValue().getValueAsString()); + LOG.debug("No duplicate value found for {}={}", + attr.getSchema().getKey(), attr.getUniqueValue().getValueAsString()); } else { - throw new DuplicateException( - "Value " + attr.getUniqueValue().getValueAsString() + " existing for " + schema.getKey()); + throw new DuplicateException("Duplicate value found for " + + attr.getSchema().getKey() + "=" + attr.getUniqueValue().getValueAsString()); } }); diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/PlainSchemaRepoExtImpl.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/PlainSchemaRepoExtImpl.java index 35ae122a3fb..1801040b9c4 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/PlainSchemaRepoExtImpl.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/repo/PlainSchemaRepoExtImpl.java @@ -29,13 +29,14 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.Schema; +import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; +import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; +import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; import org.apache.syncope.core.persistence.neo4j.entity.EntityCacheKey; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jImplementation; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainSchema; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jSchema; -import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jAPlainAttr; import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jAnyObject; -import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jGPlainAttr; import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jGroup; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jLinkedAccount; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jUser; @@ -92,11 +93,11 @@ public List findByAnyTypeClasses(final Collection> boolean hasAttrs(final PlainSchema schema, final Class reference) { String label; - if (reference.isAssignableFrom(Neo4jGPlainAttr.class)) { + if (GPlainAttr.class.isAssignableFrom(reference)) { label = Neo4jGroup.NODE; - } else if (reference.isAssignableFrom(Neo4jAPlainAttr.class)) { + } else if (APlainAttr.class.isAssignableFrom(reference)) { label = Neo4jAnyObject.NODE; - } else if (reference.isAssignableFrom(Neo4jAPlainAttr.class)) { + } else if (LAPlainAttr.class.isAssignableFrom(reference)) { label = Neo4jLinkedAccount.NODE; } else { label = Neo4jUser.NODE; diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractAny.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractAny.java index 5ec435f3d8d..0ee52709ed1 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractAny.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractAny.java @@ -154,18 +154,25 @@ public void setStatus(final String status) { this.status = status; } - protected abstract Map>> plainAttrs(); + protected abstract Map plainAttrs(); + + @Override + public Optional

getPlainAttr(final String plainSchema) { + return Optional.ofNullable(plainAttrs().get(plainSchema)); + } + + protected abstract void setPlainAttrOwner(P plainAttr); @SuppressWarnings("unchecked") - protected void doComplete(final Map>> plainAttrs) { + protected void doComplete(final Map plainAttrs) { for (var itor = plainAttrs.entrySet().iterator(); itor.hasNext();) { var entry = itor.next(); Optional.ofNullable(entry.getValue()).ifPresent(attr -> { - attr.setSchemaKey(entry.getKey()); + ((AbstractPlainAttr) attr).setSchema(entry.getKey()); if (attr.getSchema() == null) { itor.remove(); } else { - ((Neo4jPlainAttr) attr).setOwner(this); + setPlainAttrOwner(attr); attr.getValues().forEach(value -> value.setAttr(attr)); Optional.ofNullable(attr.getUniqueValue()).ifPresent(value -> value.setAttr(attr)); } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractGroupableRelatable.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractGroupableRelatable.java index 3ae320a11fb..d2e428f3345 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractGroupableRelatable.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractGroupableRelatable.java @@ -46,15 +46,13 @@ public abstract class AbstractGroupableRelatable< @Override public boolean remove(final P attr) { - Neo4jPlainAttr neo4jAttr = (Neo4jPlainAttr) attr; - - if (neo4jAttr.getMembershipKey() == null) { - return plainAttrs().put(neo4jAttr.getSchemaKey(), null) != null; + if (attr.getMembershipKey() == null) { + return plainAttrs().put(attr.getSchemaKey(), null) != null; } return memberships().stream(). - filter(m -> m.getKey().equals(neo4jAttr.getMembershipKey())).findFirst(). - map(membership -> membership.plainAttrs().put(neo4jAttr.getSchemaKey(), null) != null). + filter(m -> m.getKey().equals(attr.getMembershipKey())).findFirst(). + map(membership -> membership.plainAttrs().put(attr.getSchemaKey(), null) != null). orElse(false); } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractMembership.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractMembership.java index 1ec2dbce14f..a7da8b1ed69 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractMembership.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractMembership.java @@ -31,8 +31,8 @@ public abstract class AbstractMembership, P extends PlainAttr>> plainAttrs(); - + protected abstract Map plainAttrs(); + public abstract List getPlainAttrs(); public abstract Optional getPlainAttr(String plainSchema); diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractPlainAttr.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractPlainAttr.java index 6c7ec437768..fade9522ddb 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractPlainAttr.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractPlainAttr.java @@ -21,12 +21,12 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; import jakarta.validation.constraints.NotNull; import java.util.Collections; import java.util.List; import java.util.Optional; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.entity.Any; @@ -35,36 +35,28 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; -import org.apache.syncope.core.persistence.common.validation.PlainAttrCheck; import org.apache.syncope.core.spring.ApplicationContextProvider; @JsonIgnoreProperties("valuesAsStrings") @JsonInclude(JsonInclude.Include.NON_EMPTY) -@PlainAttrCheck -public abstract class AbstractPlainAttr> - extends AbstractProvidedKeyNode - implements PlainAttr, Neo4jPlainAttr { +public abstract class AbstractPlainAttr> implements PlainAttr { private static final long serialVersionUID = -9115431608821806124L; @JsonIgnore @NotNull - protected String schemaKey; - - /** - * The membership of this attribute; might be {@code NULL} if this attribute is not related to a membership. - */ - @JsonProperty("membership") - protected String membershipKey; + private String schemaKey; + @JsonIgnore @Override - public String getSchemaKey() { - return schemaKey; + public String getKey() { + return null; } + @JsonIgnore @Override - public void setSchemaKey(final String schemaKey) { - this.schemaKey = schemaKey; + public String getSchemaKey() { + return schemaKey; } @JsonIgnore @@ -79,25 +71,23 @@ public Neo4jPlainSchema getSchema() { @JsonIgnore @Override public void setSchema(final PlainSchema schema) { - checkType(schema, Neo4jPlainSchema.class); if (schema != null) { this.schemaKey = schema.getKey(); } } - @Override - public String getMembershipKey() { - return membershipKey; + @JsonIgnore + public void setSchema(final String schemaKey) { + this.schemaKey = schemaKey; } - @JsonSetter("membership") + protected abstract boolean addForMultiValue(PlainAttrValue attrValue); + @Override - public void setMembershipKey(final String membershipKey) { - this.membershipKey = membershipKey; + public void add(final PlainAttrValue attrValue) { + addForMultiValue(attrValue); } - protected abstract boolean addForMultiValue(PlainAttrValue attrValue); - private void checkNonNullSchema() { if (getSchema() == null) { throw new IllegalStateException("First set owner then schema and finally add values"); @@ -147,4 +137,29 @@ public List getValuesAsStrings() { return Collections.unmodifiableList(result); } + + @Override + public int hashCode() { + return new HashCodeBuilder(). + append(schemaKey). + build(); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + @SuppressWarnings("unchecked") + final AbstractPlainAttr other = (AbstractPlainAttr) obj; + return new EqualsBuilder(). + append(schemaKey, other.schemaKey). + build(); + } } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractPlainAttrValue.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractPlainAttrValue.java index 5f248a91bde..ca7e752af1a 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractPlainAttrValue.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AbstractPlainAttrValue.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.core.persistence.neo4j.entity; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import java.time.OffsetDateTime; @@ -33,17 +34,19 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.utils.FormatUtils; -import org.apache.syncope.core.persistence.common.validation.PlainAttrValueCheck; import org.apache.syncope.core.spring.ApplicationContextProvider; import org.apache.syncope.core.spring.security.Encryptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @JsonIgnoreProperties({ "valueAsString", "value" }) @JsonInclude(JsonInclude.Include.NON_NULL) -@PlainAttrValueCheck -public abstract class AbstractPlainAttrValue extends AbstractProvidedKeyNode implements PlainAttrValue { +public abstract class AbstractPlainAttrValue implements PlainAttrValue { private static final long serialVersionUID = -9141923816611244785L; + protected static final Logger LOG = LoggerFactory.getLogger(PlainAttrValue.class); + private static final Pattern SPRING_ENV_PROPERTY = Pattern.compile("^\\$\\{.*\\}$"); private String stringValue; @@ -58,6 +61,12 @@ public abstract class AbstractPlainAttrValue extends AbstractProvidedKeyNode imp private byte[] binaryValue; + @JsonIgnore + @Override + public String getKey() { + return null; + } + @Override public Boolean getBooleanValue() { return booleanValue; @@ -100,15 +109,7 @@ public void setLongValue(final Long longValue) { @Override public String getStringValue() { - // workaround for Oracle DB considering empty string values as NULL (SYNCOPE-664) - return dateValue == null - && booleanValue == null - && longValue == null - && doubleValue == null - && binaryValue == null - && stringValue == null - ? StringUtils.EMPTY - : stringValue; + return stringValue; } @Override diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AttributableValidator.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AttributableValidator.java deleted file mode 100644 index 2f4f4d63b7e..00000000000 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/AttributableValidator.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.neo4j.entity; - -import jakarta.validation.ConstraintValidatorContext; -import java.util.concurrent.atomic.AtomicReference; -import org.apache.syncope.core.persistence.common.validation.AbstractValidator; -import org.apache.syncope.core.persistence.common.validation.PlainAttrValidator; -import org.apache.syncope.core.persistence.common.validation.PlainAttrValueValidator; - -public class AttributableValidator extends AbstractValidator> { - - private static final PlainAttrValidator ATTR_VALIDATOR = new PlainAttrValidator(); - - private static final PlainAttrValueValidator ATTR_VALUE_VALIDATOR = new PlainAttrValueValidator(); - - @Override - public boolean isValid(final Neo4jAttributable entity, final ConstraintValidatorContext context) { - context.disableDefaultConstraintViolation(); - - AtomicReference isValid = new AtomicReference<>(Boolean.TRUE); - entity.getPlainAttrs().forEach(attr -> { - isValid.getAndSet(isValid.get() && ATTR_VALIDATOR.isValid(attr, context)); - attr.getValues().forEach( - value -> isValid.getAndSet(isValid.get() && ATTR_VALUE_VALIDATOR.isValid(value, context))); - }); - - return isValid.get(); - } -} diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java index 5c8932c111b..10b0a5a71b4 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jEntityFactory.java @@ -118,16 +118,16 @@ import org.apache.syncope.core.persistence.neo4j.entity.am.Neo4jSAML2SPClientApp; import org.apache.syncope.core.persistence.neo4j.entity.am.Neo4jSAML2SPEntity; import org.apache.syncope.core.persistence.neo4j.entity.am.Neo4jWAConfigEntry; +import org.apache.syncope.core.persistence.neo4j.entity.anyobject.JSONAPlainAttr; +import org.apache.syncope.core.persistence.neo4j.entity.anyobject.JSONAPlainAttrUniqueValue; +import org.apache.syncope.core.persistence.neo4j.entity.anyobject.JSONAPlainAttrValue; import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jADynGroupMembership; import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jAMembership; -import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jAPlainAttr; -import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jAPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jAPlainAttrValue; import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jARelationship; import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jAnyObject; -import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jGPlainAttr; -import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jGPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jGPlainAttrValue; +import org.apache.syncope.core.persistence.neo4j.entity.group.JSONGPlainAttr; +import org.apache.syncope.core.persistence.neo4j.entity.group.JSONGPlainAttrUniqueValue; +import org.apache.syncope.core.persistence.neo4j.entity.group.JSONGPlainAttrValue; import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jGroup; import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jTypeExtension; import org.apache.syncope.core.persistence.neo4j.entity.keymaster.Neo4jConfParam; @@ -153,16 +153,16 @@ import org.apache.syncope.core.persistence.neo4j.entity.task.Neo4jPullTask; import org.apache.syncope.core.persistence.neo4j.entity.task.Neo4jPushTask; import org.apache.syncope.core.persistence.neo4j.entity.task.Neo4jSchedTask; -import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jLAPlainAttr; -import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jLAPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jLAPlainAttrValue; +import org.apache.syncope.core.persistence.neo4j.entity.user.JSONLAPlainAttr; +import org.apache.syncope.core.persistence.neo4j.entity.user.JSONLAPlainAttrUniqueValue; +import org.apache.syncope.core.persistence.neo4j.entity.user.JSONLAPlainAttrValue; +import org.apache.syncope.core.persistence.neo4j.entity.user.JSONUPlainAttr; +import org.apache.syncope.core.persistence.neo4j.entity.user.JSONUPlainAttrUniqueValue; +import org.apache.syncope.core.persistence.neo4j.entity.user.JSONUPlainAttrValue; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jLinkedAccount; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jSecurityQuestion; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jUDynGroupMembership; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jUMembership; -import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jUPlainAttr; -import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jUPlainAttrUniqueValue; -import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jUPlainAttrValue; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jURelationship; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jUser; import org.apache.syncope.core.spring.security.SecureRandomUtils; @@ -239,33 +239,33 @@ public E newEntity(final Class reference) { } else if (reference.equals(PlainSchema.class)) { result = (E) new Neo4jPlainSchema(); } else if (reference.equals(APlainAttr.class)) { - result = (E) new Neo4jAPlainAttr(); + result = (E) new JSONAPlainAttr(); } else if (reference.equals(APlainAttrValue.class)) { - result = (E) new Neo4jAPlainAttrValue(); + result = (E) new JSONAPlainAttrValue(); } else if (reference.equals(APlainAttrUniqueValue.class)) { - result = (E) new Neo4jAPlainAttrUniqueValue(); + result = (E) new JSONAPlainAttrUniqueValue(); } else if (reference.equals(UPlainAttr.class)) { - result = (E) new Neo4jUPlainAttr(); + result = (E) new JSONUPlainAttr(); } else if (reference.equals(UPlainAttrValue.class)) { - result = (E) new Neo4jUPlainAttrValue(); + result = (E) new JSONUPlainAttrValue(); } else if (reference.equals(UPlainAttrUniqueValue.class)) { - result = (E) new Neo4jUPlainAttrUniqueValue(); + result = (E) new JSONUPlainAttrUniqueValue(); } else if (reference.equals(LAPlainAttr.class)) { - result = (E) new Neo4jLAPlainAttr(); + result = (E) new JSONLAPlainAttr(); } else if (reference.equals(LAPlainAttrValue.class)) { - result = (E) new Neo4jLAPlainAttrValue(); + result = (E) new JSONLAPlainAttrValue(); } else if (reference.equals(LAPlainAttrUniqueValue.class)) { - result = (E) new Neo4jLAPlainAttrUniqueValue(); + result = (E) new JSONLAPlainAttrUniqueValue(); } else if (reference.equals(DerSchema.class)) { result = (E) new Neo4jDerSchema(); } else if (reference.equals(VirSchema.class)) { result = (E) new Neo4jVirSchema(); } else if (reference.equals(GPlainAttr.class)) { - result = (E) new Neo4jGPlainAttr(); + result = (E) new JSONGPlainAttr(); } else if (reference.equals(GPlainAttrValue.class)) { - result = (E) new Neo4jGPlainAttrValue(); + result = (E) new JSONGPlainAttrValue(); } else if (reference.equals(GPlainAttrUniqueValue.class)) { - result = (E) new Neo4jGPlainAttrUniqueValue(); + result = (E) new JSONGPlainAttrUniqueValue(); } else if (reference.equals(Report.class)) { result = (E) new Neo4jReport(); } else if (reference.equals(ReportExec.class)) { diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jPlainAttr.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jPlainAttr.java deleted file mode 100644 index dcaa0f56af4..00000000000 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/Neo4jPlainAttr.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.neo4j.entity; - -import org.apache.syncope.core.persistence.api.entity.Any; -import org.apache.syncope.core.persistence.api.entity.PlainAttr; -import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; - -public interface Neo4jPlainAttr> extends PlainAttr { - - String getSchemaKey(); - - void setSchemaKey(String schemaKey); - - String getMembershipKey(); - - void setMembershipKey(String membershipKey); - - boolean add(PlainAttrValue value); -} diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAPlainAttr.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/JSONAPlainAttr.java similarity index 72% rename from core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAPlainAttr.java rename to core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/JSONAPlainAttr.java index 24bccca19b1..f68d0ea0c2b 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAPlainAttr.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/JSONAPlainAttr.java @@ -18,10 +18,13 @@ */ package org.apache.syncope.core.persistence.neo4j.entity.anyobject; +import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; @@ -32,10 +35,9 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.neo4j.entity.AbstractPlainAttr; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainAttr; import org.apache.syncope.core.spring.ApplicationContextProvider; -public class Neo4jAPlainAttr extends AbstractPlainAttr implements APlainAttr, Neo4jPlainAttr { +public class JSONAPlainAttr extends AbstractPlainAttr implements APlainAttr { private static final long serialVersionUID = 806271775349587902L; @@ -45,16 +47,22 @@ public class Neo4jAPlainAttr extends AbstractPlainAttr implements APl @JsonIgnore private Neo4jAnyObject owner; + /** + * The membership of this attribute; might be {@code NULL} if this attribute is not related to a membership. + */ + @JsonProperty + private String membership; + /** * Values of this attribute (if schema is not UNIQUE). */ - private final List values = new ArrayList<>(); + private final List values = new ArrayList<>(); /** * Value of this attribute (if schema is UNIQUE). */ @JsonProperty - private Neo4jAPlainAttrUniqueValue uniqueValue; + private JSONAPlainAttrUniqueValue uniqueValue; @Override public AnyObject getOwner() { @@ -63,34 +71,34 @@ public AnyObject getOwner() { @Override public void setOwner(final AnyObject owner) { - checkType(owner, Neo4jAnyObject.class); this.owner = (Neo4jAnyObject) owner; } @JsonIgnore @Override public AMembership getMembership() { - return ApplicationContextProvider.getBeanFactory().getBean(AnyObjectDAO.class).findMembership(membershipKey); + return ApplicationContextProvider.getBeanFactory().getBean(AnyObjectDAO.class).findMembership(membership); } - @JsonIgnore @Override public void setMembership(final AMembership membership) { - checkType(membership, Neo4jAMembership.class); - if (membership != null) { - this.membershipKey = membership.getKey(); - } + this.membership = Optional.ofNullable(membership).map(AMembership::getKey).orElse(null); } + @JsonGetter("membership") @Override - protected boolean addForMultiValue(final PlainAttrValue attrValue) { - checkType(attrValue, Neo4jAPlainAttrValue.class); - return values.add((Neo4jAPlainAttrValue) attrValue); + public String getMembershipKey() { + return membership; + } + + @JsonSetter("membership") + public void setMembership(final String membership) { + this.membership = membership; } @Override - public boolean add(final PlainAttrValue value) { - return addForMultiValue(value); + protected boolean addForMultiValue(final PlainAttrValue attrValue) { + return values.add((JSONAPlainAttrValue) attrValue); } @Override @@ -99,22 +107,21 @@ public List getValues() { } @Override - public Neo4jAPlainAttrUniqueValue getUniqueValue() { + public JSONAPlainAttrUniqueValue getUniqueValue() { return uniqueValue; } @JsonIgnore @Override public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) { - checkType(uniqueValue, Neo4jAPlainAttrUniqueValue.class); - this.uniqueValue = (Neo4jAPlainAttrUniqueValue) uniqueValue; + this.uniqueValue = (JSONAPlainAttrUniqueValue) uniqueValue; } @Override public int hashCode() { return new HashCodeBuilder(). - append(schemaKey). - append(membershipKey). + appendSuper(super.hashCode()). + append(membership). append(values). append(uniqueValue). build(); @@ -131,10 +138,10 @@ public boolean equals(final Object obj) { if (getClass() != obj.getClass()) { return false; } - final Neo4jAPlainAttr other = (Neo4jAPlainAttr) obj; + final JSONAPlainAttr other = (JSONAPlainAttr) obj; return new EqualsBuilder(). - append(schemaKey, other.schemaKey). - append(membershipKey, other.membershipKey). + appendSuper(super.equals(obj)). + append(membership, other.membership). append(values, other.values). append(uniqueValue, other.uniqueValue). build(); diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAPlainAttrUniqueValue.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/JSONAPlainAttrUniqueValue.java similarity index 88% rename from core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAPlainAttrUniqueValue.java rename to core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/JSONAPlainAttrUniqueValue.java index f06ec68dcb3..a87fcefa6f8 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAPlainAttrUniqueValue.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/JSONAPlainAttrUniqueValue.java @@ -26,13 +26,13 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrUniqueValue; import org.apache.syncope.core.persistence.neo4j.entity.AbstractPlainAttrValue; -public class Neo4jAPlainAttrUniqueValue extends AbstractPlainAttrValue implements APlainAttrUniqueValue { +public class JSONAPlainAttrUniqueValue extends AbstractPlainAttrValue implements APlainAttrUniqueValue { private static final long serialVersionUID = -4053996864791245312L; @JsonIgnore @NotNull - private Neo4jAPlainAttr attr; + private JSONAPlainAttr attr; @Override public APlainAttr getAttr() { @@ -41,8 +41,7 @@ public APlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, Neo4jAPlainAttr.class); - this.attr = (Neo4jAPlainAttr) attr; + this.attr = (JSONAPlainAttr) attr; } @JsonIgnore diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAPlainAttrValue.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/JSONAPlainAttrValue.java similarity index 87% rename from core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAPlainAttrValue.java rename to core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/JSONAPlainAttrValue.java index 4eb20001d3f..2dd35cedea8 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAPlainAttrValue.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/JSONAPlainAttrValue.java @@ -25,13 +25,13 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue; import org.apache.syncope.core.persistence.neo4j.entity.AbstractPlainAttrValue; -public class Neo4jAPlainAttrValue extends AbstractPlainAttrValue implements APlainAttrValue { +public class JSONAPlainAttrValue extends AbstractPlainAttrValue implements APlainAttrValue { private static final long serialVersionUID = -8657212700294416428L; @JsonIgnore @NotNull - private Neo4jAPlainAttr attr; + private JSONAPlainAttr attr; @Override public APlainAttr getAttr() { @@ -40,7 +40,6 @@ public APlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, Neo4jAPlainAttr.class); - this.attr = (Neo4jAPlainAttr) attr; + this.attr = (JSONAPlainAttr) attr; } } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAMembership.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAMembership.java index f5a84898672..e4acc9ad69e 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAMembership.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAMembership.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.MembershipType; import org.apache.syncope.core.persistence.api.entity.RelationshipType; import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; @@ -31,7 +30,6 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.neo4j.entity.AbstractMembership; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainAttr; import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jGroup; import org.springframework.data.neo4j.core.schema.CompositeProperty; import org.springframework.data.neo4j.core.schema.Node; @@ -51,7 +49,7 @@ public class Neo4jAMembership extends AbstractMembership private Neo4jGroup rightEnd; @CompositeProperty(converterRef = "aPlainAttrsConverter") - protected Map plainAttrs = new HashMap<>(); + protected Map plainAttrs = new HashMap<>(); @Override public MembershipType getType() { @@ -86,12 +84,12 @@ public void setRightEnd(final Group rightEnd) { } @Override - protected Map>> plainAttrs() { + protected Map plainAttrs() { return plainAttrs; } @Override - public List getPlainAttrs() { + public List getPlainAttrs() { return plainAttrs.entrySet().stream(). filter(e -> e.getValue() != null). sorted(Comparator.comparing(Map.Entry::getKey)). @@ -99,14 +97,14 @@ public List getPlainAttrs() { } @Override - public Optional getPlainAttr(final String plainSchema) { + public Optional getPlainAttr(final String plainSchema) { return Optional.ofNullable(plainAttrs.get(plainSchema)); } @Override public boolean add(final APlainAttr attr) { - checkType(attr, Neo4jAPlainAttr.class); - Neo4jAPlainAttr neo4jAttr = (Neo4jAPlainAttr) attr; + checkType(attr, JSONAPlainAttr.class); + JSONAPlainAttr neo4jAttr = (JSONAPlainAttr) attr; return getKey().equals(neo4jAttr.getMembershipKey()) && plainAttrs.put(neo4jAttr.getSchemaKey(), neo4jAttr) != null; } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAnyObject.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAnyObject.java index 57dec17fa98..851c52b1acf 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAnyObject.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/anyobject/Neo4jAnyObject.java @@ -24,7 +24,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.ExternalResource; @@ -34,13 +33,11 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.common.validation.AnyObjectCheck; +import org.apache.syncope.core.persistence.common.validation.AttributableCheck; import org.apache.syncope.core.persistence.neo4j.entity.AbstractGroupableRelatable; -import org.apache.syncope.core.persistence.neo4j.entity.AttributableCheck; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jAnyType; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jAnyTypeClass; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jAttributable; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jExternalResource; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainAttr; import org.springframework.data.neo4j.core.schema.CompositeProperty; import org.springframework.data.neo4j.core.schema.Node; import org.springframework.data.neo4j.core.schema.Relationship; @@ -50,7 +47,7 @@ @AttributableCheck public class Neo4jAnyObject extends AbstractGroupableRelatable - implements AnyObject, Neo4jAttributable { + implements AnyObject { private static final long serialVersionUID = -3905046855521446823L; @@ -63,7 +60,7 @@ public class Neo4jAnyObject public static final String ANY_OBJECT_AUX_CLASSES_REL = "ANY_OBJECT_AUX_CLASSES"; @CompositeProperty(converterRef = "aPlainAttrsConverter") - protected Map plainAttrs = new HashMap<>(); + protected Map plainAttrs = new HashMap<>(); @NotNull(message = "Blank name") protected String name; @@ -88,7 +85,7 @@ public class Neo4jAnyObject protected List memberships = new ArrayList<>(); @Override - protected Map>> plainAttrs() { + protected Map plainAttrs() { return plainAttrs; } @@ -125,14 +122,14 @@ public List getResources() { } @Override - public Optional getPlainAttr(final String plainSchema) { - return Optional.ofNullable(plainAttrs.get(plainSchema)); + protected void setPlainAttrOwner(final APlainAttr plainAttr) { + plainAttr.setOwner(this); } @Override public boolean add(final APlainAttr attr) { - checkType(attr, Neo4jAPlainAttr.class); - Neo4jAPlainAttr neo4jAttr = (Neo4jAPlainAttr) attr; + checkType(attr, JSONAPlainAttr.class); + JSONAPlainAttr neo4jAttr = (JSONAPlainAttr) attr; if (neo4jAttr.getMembershipKey() == null) { return plainAttrs.put(neo4jAttr.getSchemaKey(), neo4jAttr) != null; diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGPlainAttr.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/JSONGPlainAttr.java similarity index 76% rename from core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGPlainAttr.java rename to core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/JSONGPlainAttr.java index de002b13b2b..42f03bc18a1 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGPlainAttr.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/JSONGPlainAttr.java @@ -30,9 +30,8 @@ import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.neo4j.entity.AbstractPlainAttr; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainAttr; -public class Neo4jGPlainAttr extends AbstractPlainAttr implements GPlainAttr, Neo4jPlainAttr { +public class JSONGPlainAttr extends AbstractPlainAttr implements GPlainAttr { private static final long serialVersionUID = 806271775349587902L; @@ -45,13 +44,13 @@ public class Neo4jGPlainAttr extends AbstractPlainAttr implements GPlainA /** * Values of this attribute (if schema is not UNIQUE). */ - private final List values = new ArrayList<>(); + private final List values = new ArrayList<>(); /** * Value of this attribute (if schema is UNIQUE). */ @JsonProperty - private Neo4jGPlainAttrUniqueValue uniqueValue; + private JSONGPlainAttrUniqueValue uniqueValue; @Override public Group getOwner() { @@ -60,19 +59,12 @@ public Group getOwner() { @Override public void setOwner(final Group owner) { - checkType(owner, Neo4jGroup.class); this.owner = (Neo4jGroup) owner; } @Override protected boolean addForMultiValue(final PlainAttrValue attrValue) { - checkType(attrValue, Neo4jGPlainAttrValue.class); - return values.add((Neo4jGPlainAttrValue) attrValue); - } - - @Override - public boolean add(final PlainAttrValue value) { - return addForMultiValue(value); + return values.add((JSONGPlainAttrValue) attrValue); } @Override @@ -81,21 +73,20 @@ public List getValues() { } @Override - public Neo4jGPlainAttrUniqueValue getUniqueValue() { + public JSONGPlainAttrUniqueValue getUniqueValue() { return uniqueValue; } @JsonIgnore @Override public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) { - checkType(uniqueValue, Neo4jGPlainAttrUniqueValue.class); - this.uniqueValue = (Neo4jGPlainAttrUniqueValue) uniqueValue; + this.uniqueValue = (JSONGPlainAttrUniqueValue) uniqueValue; } @Override public int hashCode() { return new HashCodeBuilder(). - append(schemaKey). + appendSuper(super.hashCode()). append(values). append(uniqueValue). build(); @@ -112,9 +103,9 @@ public boolean equals(final Object obj) { if (getClass() != obj.getClass()) { return false; } - final Neo4jGPlainAttr other = (Neo4jGPlainAttr) obj; + final JSONGPlainAttr other = (JSONGPlainAttr) obj; return new EqualsBuilder(). - append(schemaKey, other.schemaKey). + appendSuper(super.equals(obj)). append(values, other.values). append(uniqueValue, other.uniqueValue). build(); diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGPlainAttrUniqueValue.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/JSONGPlainAttrUniqueValue.java similarity index 88% rename from core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGPlainAttrUniqueValue.java rename to core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/JSONGPlainAttrUniqueValue.java index f17ec0929ea..266d0db5102 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGPlainAttrUniqueValue.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/JSONGPlainAttrUniqueValue.java @@ -26,13 +26,13 @@ import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrUniqueValue; import org.apache.syncope.core.persistence.neo4j.entity.AbstractPlainAttrValue; -public class Neo4jGPlainAttrUniqueValue extends AbstractPlainAttrValue implements GPlainAttrUniqueValue { +public class JSONGPlainAttrUniqueValue extends AbstractPlainAttrValue implements GPlainAttrUniqueValue { private static final long serialVersionUID = -4053996864791245312L; @JsonIgnore @NotNull - private Neo4jGPlainAttr attr; + private JSONGPlainAttr attr; @Override public GPlainAttr getAttr() { @@ -41,8 +41,7 @@ public GPlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, Neo4jGPlainAttr.class); - this.attr = (Neo4jGPlainAttr) attr; + this.attr = (JSONGPlainAttr) attr; } @JsonIgnore diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGPlainAttrValue.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/JSONGPlainAttrValue.java similarity index 87% rename from core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGPlainAttrValue.java rename to core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/JSONGPlainAttrValue.java index 7861d0892df..b26279515fe 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGPlainAttrValue.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/JSONGPlainAttrValue.java @@ -25,13 +25,13 @@ import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue; import org.apache.syncope.core.persistence.neo4j.entity.AbstractPlainAttrValue; -public class Neo4jGPlainAttrValue extends AbstractPlainAttrValue implements GPlainAttrValue { +public class JSONGPlainAttrValue extends AbstractPlainAttrValue implements GPlainAttrValue { private static final long serialVersionUID = -8657212700294416428L; @JsonIgnore @NotNull - private Neo4jGPlainAttr attr; + private JSONGPlainAttr attr; @Override public GPlainAttr getAttr() { @@ -40,7 +40,6 @@ public GPlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, Neo4jGPlainAttr.class); - this.attr = (Neo4jGPlainAttr) attr; + this.attr = (JSONGPlainAttr) attr; } } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGroup.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGroup.java index 94a386cd390..fa01175bb64 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGroup.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/group/Neo4jGroup.java @@ -26,7 +26,6 @@ import java.util.Map; import java.util.Optional; import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; -import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.ExternalResource; @@ -36,13 +35,11 @@ import org.apache.syncope.core.persistence.api.entity.group.TypeExtension; import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership; import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.persistence.common.validation.AttributableCheck; import org.apache.syncope.core.persistence.common.validation.GroupCheck; import org.apache.syncope.core.persistence.neo4j.entity.AbstractAny; -import org.apache.syncope.core.persistence.neo4j.entity.AttributableCheck; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jAnyTypeClass; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jAttributable; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jExternalResource; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainAttr; import org.apache.syncope.core.persistence.neo4j.entity.anyobject.Neo4jADynGroupMembership; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jUDynGroupMembership; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jUser; @@ -54,7 +51,7 @@ @Node(Neo4jGroup.NODE) @GroupCheck @AttributableCheck -public class Neo4jGroup extends AbstractAny implements Group, Neo4jAttributable { +public class Neo4jGroup extends AbstractAny implements Group { private static final long serialVersionUID = -5281258853142421875L; @@ -74,7 +71,7 @@ public class Neo4jGroup extends AbstractAny implements Group, Neo4jA private String name; @CompositeProperty(converterRef = "gPlainAttrsConverter") - protected Map plainAttrs = new HashMap<>(); + protected Map plainAttrs = new HashMap<>(); @Relationship(type = USER_OWNER_REL, direction = Relationship.Direction.OUTGOING) protected Neo4jUser userOwner; @@ -101,7 +98,7 @@ public class Neo4jGroup extends AbstractAny implements Group, Neo4jA private List typeExtensions = new ArrayList<>(); @Override - protected Map>> plainAttrs() { + protected Map plainAttrs() { return plainAttrs; } @@ -159,20 +156,20 @@ public void setGroupOwner(final Group group) { } @Override - public boolean add(final GPlainAttr attr) { - checkType(attr, Neo4jGPlainAttr.class); - Neo4jGPlainAttr neo4jAttr = (Neo4jGPlainAttr) attr; - return plainAttrs.put(neo4jAttr.getSchemaKey(), neo4jAttr) != null; + protected void setPlainAttrOwner(final GPlainAttr plainAttr) { + plainAttr.setOwner(this); } @Override - public boolean remove(final GPlainAttr attr) { - return plainAttrs.put(((Neo4jGPlainAttr) attr).getSchemaKey(), null) != null; + public boolean add(final GPlainAttr attr) { + checkType(attr, JSONGPlainAttr.class); + JSONGPlainAttr neo4jAttr = (JSONGPlainAttr) attr; + return plainAttrs.put(neo4jAttr.getSchemaKey(), neo4jAttr) != null; } @Override - public Optional getPlainAttr(final String plainSchema) { - return Optional.ofNullable(plainAttrs.get(plainSchema)); + public boolean remove(final GPlainAttr attr) { + return plainAttrs.put(((JSONGPlainAttr) attr).getSchemaKey(), null) != null; } @Override diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jLAPlainAttr.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONLAPlainAttr.java similarity index 78% rename from core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jLAPlainAttr.java rename to core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONLAPlainAttr.java index 4523e4ff62d..2e6daeed97f 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jLAPlainAttr.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONLAPlainAttr.java @@ -30,9 +30,8 @@ import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.neo4j.entity.AbstractPlainAttr; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainAttr; -public class Neo4jLAPlainAttr extends AbstractPlainAttr implements LAPlainAttr, Neo4jPlainAttr { +public class JSONLAPlainAttr extends AbstractPlainAttr implements LAPlainAttr { private static final long serialVersionUID = 7827533741035423694L; @@ -48,13 +47,13 @@ public class Neo4jLAPlainAttr extends AbstractPlainAttr implements LAPlain /** * Values of this attribute (if schema is not UNIQUE). */ - private List values = new ArrayList<>(); + private List values = new ArrayList<>(); /** * Value of this attribute (if schema is UNIQUE). */ @JsonProperty - private Neo4jLAPlainAttrUniqueValue uniqueValue; + private JSONLAPlainAttrUniqueValue uniqueValue; @Override public User getOwner() { @@ -63,7 +62,6 @@ public User getOwner() { @Override public void setOwner(final User owner) { - checkType(owner, Neo4jUser.class); this.owner = (Neo4jUser) owner; } @@ -74,19 +72,12 @@ public LinkedAccount getAccount() { @Override public void setAccount(final LinkedAccount account) { - checkType(account, Neo4jLinkedAccount.class); this.account = (Neo4jLinkedAccount) account; } @Override protected boolean addForMultiValue(final PlainAttrValue attrValue) { - checkType(attrValue, Neo4jLAPlainAttrValue.class); - return values.add((Neo4jLAPlainAttrValue) attrValue); - } - - @Override - public boolean add(final PlainAttrValue value) { - return addForMultiValue(value); + return values.add((JSONLAPlainAttrValue) attrValue); } @Override @@ -102,7 +93,6 @@ public LAPlainAttrUniqueValue getUniqueValue() { @JsonIgnore @Override public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) { - checkType(uniqueValue, Neo4jLAPlainAttrUniqueValue.class); - this.uniqueValue = (Neo4jLAPlainAttrUniqueValue) uniqueValue; + this.uniqueValue = (JSONLAPlainAttrUniqueValue) uniqueValue; } } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jLAPlainAttrUniqueValue.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONLAPlainAttrUniqueValue.java similarity index 88% rename from core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jLAPlainAttrUniqueValue.java rename to core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONLAPlainAttrUniqueValue.java index e4ea06d9128..1f7940df984 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jLAPlainAttrUniqueValue.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONLAPlainAttrUniqueValue.java @@ -26,7 +26,7 @@ import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttrUniqueValue; import org.apache.syncope.core.persistence.neo4j.entity.AbstractPlainAttrValue; -public class Neo4jLAPlainAttrUniqueValue extends AbstractPlainAttrValue implements LAPlainAttrUniqueValue { +public class JSONLAPlainAttrUniqueValue extends AbstractPlainAttrValue implements LAPlainAttrUniqueValue { private static final long serialVersionUID = 1200617357906733442L; @@ -34,7 +34,7 @@ public class Neo4jLAPlainAttrUniqueValue extends AbstractPlainAttrValue implemen @JsonIgnore @NotNull - private Neo4jLAPlainAttr attr; + private JSONLAPlainAttr attr; @Override public LAPlainAttr getAttr() { @@ -43,8 +43,7 @@ public LAPlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, Neo4jLAPlainAttr.class); - this.attr = (Neo4jLAPlainAttr) attr; + this.attr = (JSONLAPlainAttr) attr; } @JsonIgnore diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jLAPlainAttrValue.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONLAPlainAttrValue.java similarity index 87% rename from core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jLAPlainAttrValue.java rename to core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONLAPlainAttrValue.java index d5df4730f6c..c38a1334aa3 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jLAPlainAttrValue.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONLAPlainAttrValue.java @@ -25,13 +25,13 @@ import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttrValue; import org.apache.syncope.core.persistence.neo4j.entity.AbstractPlainAttrValue; -public class Neo4jLAPlainAttrValue extends AbstractPlainAttrValue implements LAPlainAttrValue { +public class JSONLAPlainAttrValue extends AbstractPlainAttrValue implements LAPlainAttrValue { private static final long serialVersionUID = 6237793413044604262L; @JsonIgnore @NotNull - private Neo4jLAPlainAttr attr; + private JSONLAPlainAttr attr; @Override public LAPlainAttr getAttr() { @@ -40,7 +40,6 @@ public LAPlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, Neo4jLAPlainAttr.class); - this.attr = (Neo4jLAPlainAttr) attr; + this.attr = (JSONLAPlainAttr) attr; } } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUPlainAttr.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONUPlainAttr.java similarity index 71% rename from core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUPlainAttr.java rename to core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONUPlainAttr.java index 0b8a58fe720..c1e96e9be11 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUPlainAttr.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONUPlainAttr.java @@ -18,10 +18,13 @@ */ package org.apache.syncope.core.persistence.neo4j.entity.user; +import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.syncope.core.persistence.api.dao.UserDAO; @@ -32,10 +35,9 @@ import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.neo4j.entity.AbstractPlainAttr; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainAttr; import org.apache.syncope.core.spring.ApplicationContextProvider; -public class Neo4jUPlainAttr extends AbstractPlainAttr implements UPlainAttr, Neo4jPlainAttr { +public class JSONUPlainAttr extends AbstractPlainAttr implements UPlainAttr { private static final long serialVersionUID = 806271775349587902L; @@ -43,18 +45,24 @@ public class Neo4jUPlainAttr extends AbstractPlainAttr implements UPlainAt * The owner of this attribute. */ @JsonIgnore - private Neo4jUser owner; + private User owner; + + /** + * The membership of this attribute; might be {@code NULL} if this attribute is not related to a membership. + */ + @JsonProperty + private String membership; /** * Values of this attribute (if schema is not UNIQUE). */ - private final List values = new ArrayList<>(); + private final List values = new ArrayList<>(); /** * Value of this attribute (if schema is UNIQUE). */ @JsonProperty - private Neo4jUPlainAttrUniqueValue uniqueValue; + private JSONUPlainAttrUniqueValue uniqueValue; @Override public User getOwner() { @@ -63,34 +71,34 @@ public User getOwner() { @Override public void setOwner(final User owner) { - checkType(owner, Neo4jUser.class); - this.owner = (Neo4jUser) owner; + this.owner = owner; } @JsonIgnore @Override public UMembership getMembership() { - return ApplicationContextProvider.getBeanFactory().getBean(UserDAO.class).findMembership(membershipKey); + return ApplicationContextProvider.getBeanFactory().getBean(UserDAO.class).findMembership(membership); } - @JsonIgnore @Override public void setMembership(final UMembership membership) { - checkType(membership, Neo4jUMembership.class); - if (membership != null) { - this.membershipKey = membership.getKey(); - } + this.membership = Optional.ofNullable(membership).map(UMembership::getKey).orElse(null); } + @JsonGetter("membership") @Override - protected boolean addForMultiValue(final PlainAttrValue attrValue) { - checkType(attrValue, Neo4jUPlainAttrValue.class); - return values.add((Neo4jUPlainAttrValue) attrValue); + public String getMembershipKey() { + return membership; + } + + @JsonSetter("membership") + public void setMembership(final String membership) { + this.membership = membership; } @Override - public boolean add(final PlainAttrValue value) { - return addForMultiValue(value); + protected boolean addForMultiValue(final PlainAttrValue attrValue) { + return values.add((JSONUPlainAttrValue) attrValue); } @Override @@ -99,22 +107,21 @@ public List getValues() { } @Override - public Neo4jUPlainAttrUniqueValue getUniqueValue() { + public JSONUPlainAttrUniqueValue getUniqueValue() { return uniqueValue; } @JsonIgnore @Override public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) { - checkType(uniqueValue, Neo4jUPlainAttrUniqueValue.class); - this.uniqueValue = (Neo4jUPlainAttrUniqueValue) uniqueValue; + this.uniqueValue = (JSONUPlainAttrUniqueValue) uniqueValue; } @Override public int hashCode() { return new HashCodeBuilder(). - append(schemaKey). - append(membershipKey). + appendSuper(super.hashCode()). + append(membership). append(values). append(uniqueValue). build(); @@ -131,10 +138,10 @@ public boolean equals(final Object obj) { if (getClass() != obj.getClass()) { return false; } - final Neo4jUPlainAttr other = (Neo4jUPlainAttr) obj; + final JSONUPlainAttr other = (JSONUPlainAttr) obj; return new EqualsBuilder(). - append(schemaKey, other.schemaKey). - append(membershipKey, other.membershipKey). + appendSuper(super.equals(obj)). + append(membership, other.membership). append(values, other.values). append(uniqueValue, other.uniqueValue). build(); diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUPlainAttrUniqueValue.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONUPlainAttrUniqueValue.java similarity index 88% rename from core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUPlainAttrUniqueValue.java rename to core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONUPlainAttrUniqueValue.java index a7c598b1bdb..30a97a2bfe2 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUPlainAttrUniqueValue.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONUPlainAttrUniqueValue.java @@ -26,13 +26,13 @@ import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue; import org.apache.syncope.core.persistence.neo4j.entity.AbstractPlainAttrValue; -public class Neo4jUPlainAttrUniqueValue extends AbstractPlainAttrValue implements UPlainAttrUniqueValue { +public class JSONUPlainAttrUniqueValue extends AbstractPlainAttrValue implements UPlainAttrUniqueValue { private static final long serialVersionUID = -4053996864791245312L; @JsonIgnore @NotNull - private Neo4jUPlainAttr attr; + private JSONUPlainAttr attr; @Override public UPlainAttr getAttr() { @@ -41,8 +41,7 @@ public UPlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, Neo4jUPlainAttr.class); - this.attr = (Neo4jUPlainAttr) attr; + this.attr = (JSONUPlainAttr) attr; } @JsonIgnore diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUPlainAttrValue.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONUPlainAttrValue.java similarity index 87% rename from core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUPlainAttrValue.java rename to core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONUPlainAttrValue.java index dff3814ccda..7e034a83bba 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUPlainAttrValue.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/JSONUPlainAttrValue.java @@ -25,13 +25,13 @@ import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue; import org.apache.syncope.core.persistence.neo4j.entity.AbstractPlainAttrValue; -public class Neo4jUPlainAttrValue extends AbstractPlainAttrValue implements UPlainAttrValue { +public class JSONUPlainAttrValue extends AbstractPlainAttrValue implements UPlainAttrValue { private static final long serialVersionUID = -8657212700294416428L; @JsonIgnore @NotNull - private Neo4jUPlainAttr attr; + private JSONUPlainAttr attr; @Override public UPlainAttr getAttr() { @@ -40,7 +40,6 @@ public UPlainAttr getAttr() { @Override public void setAttr(final PlainAttr attr) { - checkType(attr, Neo4jUPlainAttr.class); - this.attr = (Neo4jUPlainAttr) attr; + this.attr = (JSONUPlainAttr) attr; } } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jLinkedAccount.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jLinkedAccount.java index 6edde13cc56..3798c2808cb 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jLinkedAccount.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jLinkedAccount.java @@ -33,11 +33,9 @@ import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.persistence.common.validation.AttributableCheck; import org.apache.syncope.core.persistence.neo4j.entity.AbstractGeneratedKeyNode; -import org.apache.syncope.core.persistence.neo4j.entity.AttributableCheck; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jAttributable; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jExternalResource; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainAttr; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPrivilege; import org.apache.syncope.core.spring.ApplicationContextProvider; import org.apache.syncope.core.spring.security.AuthContextUtils; @@ -49,7 +47,7 @@ @Node(Neo4jLinkedAccount.NODE) @AttributableCheck -public class Neo4jLinkedAccount extends AbstractGeneratedKeyNode implements LinkedAccount, Neo4jAttributable { +public class Neo4jLinkedAccount extends AbstractGeneratedKeyNode implements LinkedAccount { private static final long serialVersionUID = -5141654998687601522L; @@ -77,7 +75,7 @@ public class Neo4jLinkedAccount extends AbstractGeneratedKeyNode implements Link private Boolean suspended = false; @CompositeProperty(converterRef = "laPlainAttrsConverter") - protected Map plainAttrs = new HashMap<>(); + protected Map plainAttrs = new HashMap<>(); @Relationship(direction = Relationship.Direction.OUTGOING) private Set privileges = new HashSet<>(); @@ -180,14 +178,12 @@ public Boolean isSuspended() { @Override public boolean add(final LAPlainAttr attr) { - checkType(attr, Neo4jLAPlainAttr.class); - return plainAttrs.put(((Neo4jPlainAttr) attr).getSchemaKey(), (Neo4jLAPlainAttr) attr) != null; + return plainAttrs.put(attr.getSchemaKey(), (JSONLAPlainAttr) attr) != null; } @Override public boolean remove(final LAPlainAttr attr) { - checkType(attr, Neo4jLAPlainAttr.class); - return plainAttrs.put(((Neo4jPlainAttr) attr).getSchemaKey(), null) != null; + return plainAttrs.put(attr.getSchemaKey(), null) != null; } @Override @@ -219,12 +215,12 @@ public void completePlainAttrs() { for (var itor = plainAttrs.entrySet().iterator(); itor.hasNext();) { var entry = itor.next(); Optional.ofNullable(entry.getValue()).ifPresent(attr -> { - attr.setSchemaKey(entry.getKey()); + attr.setSchema(entry.getKey()); if (attr.getSchema() == null) { itor.remove(); } else { - ((Neo4jLAPlainAttr) attr).setOwner(getOwner()); - ((Neo4jLAPlainAttr) attr).setAccount(this); + attr.setOwner(getOwner()); + attr.setAccount(this); attr.getValues().forEach(value -> value.setAttr(attr)); Optional.ofNullable(attr.getUniqueValue()).ifPresent(value -> value.setAttr(attr)); } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUMembership.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUMembership.java index c4a23a94921..e9680a05e81 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUMembership.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUMembership.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.MembershipType; import org.apache.syncope.core.persistence.api.entity.RelationshipType; import org.apache.syncope.core.persistence.api.entity.group.Group; @@ -31,7 +30,6 @@ import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.neo4j.entity.AbstractMembership; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainAttr; import org.apache.syncope.core.persistence.neo4j.entity.group.Neo4jGroup; import org.springframework.data.neo4j.core.schema.CompositeProperty; import org.springframework.data.neo4j.core.schema.Node; @@ -51,7 +49,7 @@ public class Neo4jUMembership extends AbstractMembership imple private Neo4jGroup rightEnd; @CompositeProperty(converterRef = "uPlainAttrsConverter") - protected Map plainAttrs = new HashMap<>(); + protected Map plainAttrs = new HashMap<>(); @Override public MembershipType getType() { @@ -86,12 +84,12 @@ public void setRightEnd(final Group rightEnd) { } @Override - protected Map>> plainAttrs() { + protected Map plainAttrs() { return plainAttrs; } @Override - public List getPlainAttrs() { + public List getPlainAttrs() { return plainAttrs.entrySet().stream(). filter(e -> e.getValue() != null). sorted(Comparator.comparing(Map.Entry::getKey)). @@ -99,14 +97,14 @@ public List getPlainAttrs() { } @Override - public Optional getPlainAttr(final String plainSchema) { + public Optional getPlainAttr(final String plainSchema) { return Optional.ofNullable(plainAttrs.get(plainSchema)); } @Override public boolean add(final UPlainAttr attr) { - checkType(attr, Neo4jUPlainAttr.class); - Neo4jUPlainAttr neo4jAttr = (Neo4jUPlainAttr) attr; + checkType(attr, JSONUPlainAttr.class); + JSONUPlainAttr neo4jAttr = (JSONUPlainAttr) attr; return getKey().equals(neo4jAttr.getMembershipKey()) && plainAttrs.put(neo4jAttr.getSchemaKey(), neo4jAttr) != null; } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUser.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUser.java index 6e66ce3560c..af8e463958e 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUser.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/user/Neo4jUser.java @@ -30,7 +30,6 @@ import org.apache.syncope.common.keymaster.client.api.ConfParamOps; import org.apache.syncope.common.lib.types.CipherAlgorithm; import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; -import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.persistence.api.entity.AnyTypeClass; import org.apache.syncope.core.persistence.api.entity.ExternalResource; @@ -43,12 +42,10 @@ import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.URelationship; import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.persistence.common.validation.AttributableCheck; import org.apache.syncope.core.persistence.neo4j.entity.AbstractGroupableRelatable; -import org.apache.syncope.core.persistence.neo4j.entity.AttributableCheck; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jAnyTypeClass; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jAttributable; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jExternalResource; -import org.apache.syncope.core.persistence.neo4j.entity.Neo4jPlainAttr; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jRole; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; import org.apache.syncope.core.spring.ApplicationContextProvider; @@ -63,7 +60,7 @@ @AttributableCheck public class Neo4jUser extends AbstractGroupableRelatable - implements User, Neo4jAttributable { + implements User { private static final long serialVersionUID = -3905046855521446823L; @@ -87,7 +84,7 @@ public class Neo4jUser protected String password; @CompositeProperty(converterRef = "uPlainAttrsConverter") - protected Map plainAttrs = new HashMap<>(); + protected Map plainAttrs = new HashMap<>(); protected String token; @@ -150,7 +147,7 @@ public class Neo4jUser protected List linkedAccounts = new ArrayList<>(); @Override - protected Map>> plainAttrs() { + protected Map plainAttrs() { return plainAttrs; } @@ -233,14 +230,14 @@ public boolean canDecodeSecrets() { } @Override - public Optional getPlainAttr(final String plainSchema) { - return Optional.ofNullable(plainAttrs.get(plainSchema)); + protected void setPlainAttrOwner(final UPlainAttr plainAttr) { + plainAttr.setOwner(this); } @Override public boolean add(final UPlainAttr attr) { - checkType(attr, Neo4jUPlainAttr.class); - Neo4jUPlainAttr neo4jAttr = (Neo4jUPlainAttr) attr; + checkType(attr, JSONUPlainAttr.class); + JSONUPlainAttr neo4jAttr = (JSONUPlainAttr) attr; if (neo4jAttr.getMembershipKey() == null) { return plainAttrs.put(neo4jAttr.getSchemaKey(), neo4jAttr) != null; diff --git a/core/persistence-neo4j/src/main/resources/indexes.xml b/core/persistence-neo4j/src/main/resources/META-INF/indexes.xml similarity index 100% rename from core/persistence-neo4j/src/main/resources/indexes.xml rename to core/persistence-neo4j/src/main/resources/META-INF/indexes.xml diff --git a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/UserTest.java b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/UserTest.java index d8180e6fbae..9edf88d694c 100644 --- a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/UserTest.java +++ b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/outer/UserTest.java @@ -42,12 +42,12 @@ import org.apache.syncope.core.persistence.api.entity.Delegation; import org.apache.syncope.core.persistence.api.entity.DerSchema; import org.apache.syncope.core.persistence.api.entity.Role; +import org.apache.syncope.core.persistence.api.entity.user.LAPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; import org.apache.syncope.core.persistence.api.entity.user.UMembership; import org.apache.syncope.core.persistence.api.entity.user.URelationship; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.neo4j.AbstractTest; -import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jLAPlainAttr; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jLinkedAccount; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -162,7 +162,7 @@ private LinkedAccount newLinkedAccount(final String connObjectKeyValue) { AnyUtils anyUtils = anyUtilsFactory.getLinkedAccountInstance(); - Neo4jLAPlainAttr attr = anyUtils.newPlainAttr(); + LAPlainAttr attr = anyUtils.newPlainAttr(); attr.setOwner(user); attr.setAccount(account); attr.setSchema(plainSchemaDAO.findById("obscure").orElseThrow()); diff --git a/core/pom.xml b/core/pom.xml index 71e07b9966e..4e61b390d83 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -83,7 +83,6 @@ under the License. persistence-api persistence-common persistence-jpa - persistence-jpa-json persistence-neo4j spring provisioning-api diff --git a/core/provisioning-java/pom.xml b/core/provisioning-java/pom.xml index 86227226441..aa2c485e8b9 100644 --- a/core/provisioning-java/pom.xml +++ b/core/provisioning-java/pom.xml @@ -128,13 +128,18 @@ under the License. test - org.slf4j - slf4j-simple + org.postgresql + postgresql + test + + + io.zonky.test + embedded-postgres test - com.h2database - h2 + org.slf4j + slf4j-simple test @@ -175,7 +180,7 @@ under the License. - + org.apache.maven.plugins maven-surefire-plugin @@ -183,6 +188,7 @@ under the License. ${project.build.directory}/test-classes file:${bundles.directory}/ + true @@ -207,6 +213,9 @@ under the License. ${basedir}/../persistence-jpa/src/test/resources true + + core-test.properties + diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java index 4a431503931..0b66606c993 100644 --- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java +++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/AbstractTest.java @@ -18,7 +18,11 @@ */ package org.apache.syncope.core.provisioning.java; +import static org.junit.jupiter.api.Assertions.fail; + +import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; import jakarta.persistence.EntityManager; +import java.util.function.Supplier; import org.apache.syncope.common.lib.types.AMEntitlement; import org.apache.syncope.common.lib.types.EntitlementsHolder; import org.apache.syncope.common.lib.types.IdMEntitlement; @@ -30,12 +34,41 @@ import org.mockito.MockitoAnnotations; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; @SpringJUnitConfig(classes = { MasterDomain.class, ProvisioningTestContext.class }) @ExtendWith(MockitoExtension.class) public abstract class AbstractTest { + private static Supplier JDBC_URL_SUPPLIER; + + private static final Supplier DB_CRED_SUPPLIER = () -> "syncope"; + + static { + try { + EmbeddedPostgres pg = EmbeddedPostgres.builder().start(); + JdbcTemplate jdbcTemplate = new JdbcTemplate(pg.getPostgresDatabase()); + jdbcTemplate.execute("CREATE DATABASE syncope"); + + jdbcTemplate.execute("CREATE USER syncope WITH PASSWORD 'syncope'"); + jdbcTemplate.execute("ALTER DATABASE syncope OWNER TO syncope"); + + JDBC_URL_SUPPLIER = () -> pg.getJdbcUrl("syncope", "syncope") + "&stringtype=unspecified"; + } catch (Exception e) { + fail("Could not setup PostgreSQL database", e); + } + } + + @DynamicPropertySource + static void configureProperties(final DynamicPropertyRegistry registry) { + registry.add("DB_URL", JDBC_URL_SUPPLIER); + registry.add("DB_USER", DB_CRED_SUPPLIER); + registry.add("DB_PASSWORD", DB_CRED_SUPPLIER); + } + @BeforeAll public static void init() { EntitlementsHolder.getInstance().addAll(IdRepoEntitlement.values()); diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ProvisioningTestContext.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ProvisioningTestContext.java index aa9809b59da..1d267510248 100644 --- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ProvisioningTestContext.java +++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/ProvisioningTestContext.java @@ -27,7 +27,10 @@ import org.apache.syncope.common.keymaster.client.api.model.JPADomain; import org.apache.syncope.core.persistence.api.DomainRegistry; import org.apache.syncope.core.persistence.api.content.ContentLoader; -import org.apache.syncope.core.persistence.jpa.MasterDomain; +import org.apache.syncope.core.persistence.jpa.MariaDBPersistenceContext; +import org.apache.syncope.core.persistence.jpa.MySQLPersistenceContext; +import org.apache.syncope.core.persistence.jpa.OraclePersistenceContext; +import org.apache.syncope.core.persistence.jpa.PGPersistenceContext; import org.apache.syncope.core.persistence.jpa.PersistenceContext; import org.apache.syncope.core.persistence.jpa.StartupDomainLoader; import org.apache.syncope.core.provisioning.api.ImplementationLookup; @@ -41,8 +44,16 @@ import org.springframework.mail.javamail.JavaMailSender; @PropertySource("classpath:core-test.properties") -@Import({ ProvisioningContext.class, SecurityContext.class, - PersistenceContext.class, MasterDomain.class, WorkflowContext.class }) +@Import({ + SecurityContext.class, + WorkflowContext.class, + PersistenceContext.class, + PGPersistenceContext.class, + MySQLPersistenceContext.class, + MariaDBPersistenceContext.class, + OraclePersistenceContext.class, + ProvisioningContext.class +}) @Configuration(proxyBeanMethods = false) public class ProvisioningTestContext { diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderTest.java index b65fd6a9bd0..97a0f9c48fb 100644 --- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderTest.java +++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderTest.java @@ -108,12 +108,12 @@ public void membershipWithAttr() { dataBinder.update(userDAO.findById(userUR.getKey()).orElseThrow(), userUR); User user = userDAO.findById(userUR.getKey()).orElseThrow(); - UMembership newM = user.getMembership("034740a9-fa10-453b-af37-dc7897e98fb1").get(); + UMembership newM = user.getMembership("034740a9-fa10-453b-af37-dc7897e98fb1").orElseThrow(); assertEquals(1, user.getPlainAttrs(newM).size()); - assertNull(user.getPlainAttr("obscure").get().getMembership()); + assertNull(user.getPlainAttr("obscure").orElseThrow().getMembership()); assertEquals(2, user.getPlainAttrs("obscure").size()); - assertTrue(user.getPlainAttrs("obscure").contains(user.getPlainAttr("obscure").get())); + assertTrue(user.getPlainAttrs("obscure").contains(user.getPlainAttr("obscure").orElseThrow())); assertTrue(user.getPlainAttrs("obscure").stream().anyMatch(a -> a.getMembership() == null)); assertTrue(user.getPlainAttrs("obscure").stream().anyMatch(a -> newM.equals(a.getMembership()))); } diff --git a/docker/core/src/main/resources/core-pgjsonb.properties b/core/provisioning-java/src/test/resources/core-test.properties similarity index 76% rename from docker/core/src/main/resources/core-pgjsonb.properties rename to core/provisioning-java/src/test/resources/core-test.properties index fc98210909a..6458168bbcc 100644 --- a/docker/core/src/main/resources/core-pgjsonb.properties +++ b/core/provisioning-java/src/test/resources/core-test.properties @@ -15,16 +15,18 @@ # specific language governing permissions and limitations # under the License. -persistence.indexesXML=classpath:pgjsonb/indexes.xml -persistence.viewsXML=classpath:pgjsonb/views.xml +security.adminUser=${adminUser} +security.anonymousUser=${anonymousUser} +security.jwsKey=${jwsKey} +security.secretKey=${secretKey} persistence.domain[0].key=Master -persistence.domain[0].content=classpath:domains/jpa-json/MasterContent.xml persistence.domain[0].jdbcDriver=org.postgresql.Driver persistence.domain[0].jdbcURL=${DB_URL} persistence.domain[0].dbUsername=${DB_USER} persistence.domain[0].dbPassword=${DB_PASSWORD} persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDictionary -persistence.domain[0].orm=META-INF/spring-orm-pgjsonb.xml -persistence.domain[0].poolMaxActive=${DB_POOL_MAX} -persistence.domain[0].poolMinIdle=${DB_POOL_MIN} +persistence.domain[0].poolMaxActive=20 +persistence.domain[0].poolMinIdle=5 + +provisioning.connIdLocation=${syncope.connid.location} diff --git a/core/self-keymaster-starter/pom.xml b/core/self-keymaster-starter/pom.xml index 95f9ed7320f..6957e32254a 100644 --- a/core/self-keymaster-starter/pom.xml +++ b/core/self-keymaster-starter/pom.xml @@ -63,23 +63,9 @@ under the License. org.apache.openjpa openjpa-maven-plugin true - - - com.h2database - h2 - ${h2.version} - - ${rootpom.basedir}/core/persistence-jpa/src/main/resources/persistence-enhance.xml org/apache/syncope/core/persistence/jpa/entity/**/*.class - org.springframework.jdbc.datasource.DriverManagerDataSource - - driverClassName=org.h2.Driver, - url=jdbc:h2:mem:syncopedb - username=sa, - password= - @@ -107,35 +93,6 @@ under the License. - - sqlgen - - - true - - - - clean verify - - - - org.apache.openjpa - openjpa-maven-plugin - true - - - sqlgen - process-classes - - sql - - - - - - - - debug @@ -151,20 +108,50 @@ under the License. - com.h2database - h2 + org.postgresql + postgresql - clean package + clean io.fabric8:docker-maven-plugin:start package + + io.fabric8 + docker-maven-plugin + + + + postgres + postgres:${docker.postgresql.version} + + + syncope + syncope + syncope + + + database system is ready to accept connections + + + + /var/lib/postgresql/data:rw + + + + + + + org.springframework.boot spring-boot-maven-plugin org.apache.syncope.core.starter.SyncopeCoreApplication + + ${docker.container.postgres.ip} + -Dsyncope.connid.location=file:${basedir}/../provisioning-java/target/bundles -XX:HotswapAgent=fatjar diff --git a/core/self-keymaster-starter/src/test/resources/core-debug.properties b/core/self-keymaster-starter/src/test/resources/core-debug.properties index 0d808650a3e..6328313cfd3 100644 --- a/core/self-keymaster-starter/src/test/resources/core-debug.properties +++ b/core/self-keymaster-starter/src/test/resources/core-debug.properties @@ -26,20 +26,16 @@ keymaster.address=http://localhost:9080/syncope/rest/keymaster keymaster.username=${anonymousUser} keymaster.password=${anonymousKey} -# H2 -spring.h2.console.enabled=true -spring.h2.console.path=/h2 - security.adminUser=${adminUser} security.anonymousUser=${anonymousUser} security.jwsKey=${jwsKey} security.secretKey=${secretKey} persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=org.h2.Driver -persistence.domain[0].jdbcURL=jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1 -persistence.domain[0].dbUsername=sa -persistence.domain[0].dbPassword= -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.H2Dictionary +persistence.domain[0].jdbcDriver=org.postgresql.Driver +persistence.domain[0].jdbcURL=jdbc:postgresql://${DB_CONTAINER_IP}:5432/syncope?stringtype=unspecified +persistence.domain[0].dbUsername=syncope +persistence.domain[0].dbPassword=syncope +persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDictionary persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 diff --git a/core/workflow-java/pom.xml b/core/workflow-java/pom.xml index 976b8f2f886..43311d1f0b7 100644 --- a/core/workflow-java/pom.xml +++ b/core/workflow-java/pom.xml @@ -71,13 +71,18 @@ under the License. test - org.slf4j - slf4j-simple + org.postgresql + postgresql test - com.h2database - h2 + io.zonky.test + embedded-postgres + test + + + org.slf4j + slf4j-simple test @@ -99,6 +104,18 @@ under the License. + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.build.directory}/test-classes + file:${bundles.directory}/ + true + + + + org.apache.maven.plugins maven-checkstyle-plugin @@ -117,14 +134,14 @@ under the License. true - ${basedir}/../persistence-jpa/src/main/resources - - persistence.properties - + ${basedir}/../persistence-jpa/src/test/resources true + + core-test.properties + - ${basedir}/../persistence-jpa/src/test/resources + ${basedir}/../provisioning-java/src/test/resources true diff --git a/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/AbstractTest.java b/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/AbstractTest.java new file mode 100644 index 00000000000..f4393ec0e90 --- /dev/null +++ b/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/AbstractTest.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.workflow.java; + +import static org.junit.jupiter.api.Assertions.fail; + +import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; +import java.util.function.Supplier; +import org.apache.syncope.core.persistence.jpa.MasterDomain; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +@SpringJUnitConfig(classes = { MasterDomain.class, WorkflowTestContext.class }) +public abstract class AbstractTest { + + private static Supplier JDBC_URL_SUPPLIER; + + private static final Supplier DB_CRED_SUPPLIER = () -> "syncope"; + + static { + try { + EmbeddedPostgres pg = EmbeddedPostgres.builder().start(); + JdbcTemplate jdbcTemplate = new JdbcTemplate(pg.getPostgresDatabase()); + jdbcTemplate.execute("CREATE DATABASE syncope"); + + jdbcTemplate.execute("CREATE USER syncope WITH PASSWORD 'syncope'"); + jdbcTemplate.execute("ALTER DATABASE syncope OWNER TO syncope"); + + JDBC_URL_SUPPLIER = () -> pg.getJdbcUrl("syncope", "syncope") + "&stringtype=unspecified"; + } catch (Exception e) { + fail("Could not setup PostgreSQL database", e); + } + } + + @DynamicPropertySource + static void configureProperties(final DynamicPropertyRegistry registry) { + registry.add("DB_URL", JDBC_URL_SUPPLIER); + registry.add("DB_USER", DB_CRED_SUPPLIER); + registry.add("DB_PASSWORD", DB_CRED_SUPPLIER); + } +} diff --git a/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapterTest.java b/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapterTest.java index 4b1dbf489dd..89ce2cf7e5b 100644 --- a/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapterTest.java +++ b/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapterTest.java @@ -41,12 +41,10 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.springframework.transaction.annotation.Transactional; -@SpringJUnitConfig(classes = { WorkflowTestContext.class }) @Transactional -public class DefaultUserWorkflowAdapterTest { +public class DefaultUserWorkflowAdapterTest extends AbstractTest { @BeforeAll public static void setAuthContext() { diff --git a/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/WorkflowTestContext.java b/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/WorkflowTestContext.java index 1b4c586decc..93df7c1b7a3 100644 --- a/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/WorkflowTestContext.java +++ b/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/WorkflowTestContext.java @@ -32,7 +32,10 @@ import org.apache.syncope.core.persistence.api.content.ContentLoader; import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO; import org.apache.syncope.core.persistence.api.entity.user.User; -import org.apache.syncope.core.persistence.jpa.MasterDomain; +import org.apache.syncope.core.persistence.jpa.MariaDBPersistenceContext; +import org.apache.syncope.core.persistence.jpa.MySQLPersistenceContext; +import org.apache.syncope.core.persistence.jpa.OraclePersistenceContext; +import org.apache.syncope.core.persistence.jpa.PGPersistenceContext; import org.apache.syncope.core.persistence.jpa.PersistenceContext; import org.apache.syncope.core.persistence.jpa.StartupDomainLoader; import org.apache.syncope.core.provisioning.api.ImplementationLookup; @@ -47,7 +50,15 @@ import org.springframework.context.annotation.PropertySource; @PropertySource("classpath:core-test.properties") -@Import({ SecurityContext.class, PersistenceContext.class, MasterDomain.class, WorkflowContext.class }) +@Import({ + SecurityContext.class, + WorkflowContext.class, + PersistenceContext.class, + PGPersistenceContext.class, + MySQLPersistenceContext.class, + MariaDBPersistenceContext.class, + OraclePersistenceContext.class +}) @Configuration(proxyBeanMethods = false) public class WorkflowTestContext { diff --git a/docker/core/pom.xml b/docker/core/pom.xml index 9edb7881b55..2a0f0d5425d 100644 --- a/docker/core/pom.xml +++ b/docker/core/pom.xml @@ -135,12 +135,6 @@ under the License. ${jdbc.mariadb.version} test - - com.microsoft.sqlserver - mssql-jdbc - ${jdbc.mssql.version} - test - com.oracle.database.jdbc ojdbc11 @@ -182,10 +176,7 @@ under the License. - - - diff --git a/docker/core/src/main/resources/Dockerfile b/docker/core/src/main/resources/Dockerfile index a37312b05e2..bbac177d70f 100644 --- a/docker/core/src/main/resources/Dockerfile +++ b/docker/core/src/main/resources/Dockerfile @@ -25,7 +25,6 @@ RUN mkdir /opt/syncope/bin RUN mkdir /opt/syncope/bundles RUN mkdir /opt/syncope/conf RUN mkdir /opt/syncope/lib -RUN mkdir /opt/syncope/jpa-json RUN mkdir /opt/syncope/log COPY *.properties /opt/syncope/conf/ @@ -34,7 +33,6 @@ COPY saml.keystore.jks /opt/syncope/conf/ COPY bundles/*.jar /opt/syncope/bundles/ COPY lib/*.jar /opt/syncope/lib/ -COPY jpa-json/*.jar /opt/syncope/jpa-json/ COPY lib/syncope-docker-core-*war /opt/syncope/lib/syncope.war diff --git a/docker/core/src/main/resources/core-majson.properties b/docker/core/src/main/resources/core-majson.properties deleted file mode 100644 index bf285635a07..00000000000 --- a/docker/core/src/main/resources/core-majson.properties +++ /dev/null @@ -1,32 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -persistence.indexesXML=classpath:majson/indexes.xml -persistence.viewsXML=classpath:majson/views.xml - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=org.mariadb.jdbc.Driver -persistence.domain[0].jdbcURL=${DB_URL} -persistence.domain[0].dbUsername=${DB_USER} -persistence.domain[0].dbPassword=${DB_PASSWORD} -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MariaDBDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3) -persistence.domain[0].orm=META-INF/spring-orm-majson.xml -persistence.domain[0].poolMaxActive=${DB_POOL_MAX} -persistence.domain[0].poolMinIdle=${DB_POOL_MIN} - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_mariadb.sql diff --git a/docker/core/src/main/resources/core-mariadb.properties b/docker/core/src/main/resources/core-mariadb.properties index f556e7d3aa3..0705e23302a 100644 --- a/docker/core/src/main/resources/core-mariadb.properties +++ b/docker/core/src/main/resources/core-mariadb.properties @@ -14,11 +14,19 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. + +persistence.indexesXML=classpath:META-INF/mariadb/indexes.xml +persistence.viewsXML=classpath:META-INF/mariadb/views.xml + persistence.domain[0].key=Master persistence.domain[0].jdbcDriver=org.mariadb.jdbc.Driver persistence.domain[0].jdbcURL=${DB_URL} -persistence.domain[0].dbUsername=${DB_USER} -persistence.domain[0].dbPassword=${DB_PASSWORD} +# keep the next two lines until https://jira.mariadb.org/browse/MDEV-27898 is fixed +persistence.domain[0].dbUsername=root +persistence.domain[0].dbPassword=password +#persistence.domain[0].dbUsername=${DB_USER} +#persistence.domain[0].dbPassword=${DB_PASSWORD} persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MariaDBDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3) +persistence.domain[0].orm=META-INF/mariadb/spring-orm.xml persistence.domain[0].poolMaxActive=${DB_POOL_MAX} persistence.domain[0].poolMinIdle=${DB_POOL_MIN} diff --git a/docker/core/src/main/resources/core-myjson.properties b/docker/core/src/main/resources/core-myjson.properties deleted file mode 100644 index 8c5d30d59f6..00000000000 --- a/docker/core/src/main/resources/core-myjson.properties +++ /dev/null @@ -1,30 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -persistence.indexesXML=classpath:myjson/indexes.xml -persistence.viewsXML=classpath:myjson/views.xml - -persistence.domain[0].key=Master -persistence.domain[0].content=classpath:domains/jpa-json/MasterContent.xml -persistence.domain[0].jdbcDriver=com.mysql.cj.jdbc.Driver -persistence.domain[0].jdbcURL=${DB_URL} -persistence.domain[0].dbUsername=${DB_USER} -persistence.domain[0].dbPassword=${DB_PASSWORD} -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3,useSetStringForClobs=true) -persistence.domain[0].orm=META-INF/spring-orm-myjson.xml -persistence.domain[0].poolMaxActive=${DB_POOL_MAX} -persistence.domain[0].poolMinIdle=${DB_POOL_MIN} diff --git a/docker/core/src/main/resources/core-mysql.properties b/docker/core/src/main/resources/core-mysql.properties index 22457f4d7a2..d4b73b5db65 100644 --- a/docker/core/src/main/resources/core-mysql.properties +++ b/docker/core/src/main/resources/core-mysql.properties @@ -14,11 +14,16 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. + +persistence.indexesXML=classpath:META-INF/mysql/indexes.xml +persistence.viewsXML=classpath:META-INF/mysql/views.xml + persistence.domain[0].key=Master persistence.domain[0].jdbcDriver=com.mysql.cj.jdbc.Driver persistence.domain[0].jdbcURL=${DB_URL} persistence.domain[0].dbUsername=${DB_USER} persistence.domain[0].dbPassword=${DB_PASSWORD} persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3,useSetStringForClobs=true) +persistence.domain[0].orm=META-INF/mysql/spring-orm.xml persistence.domain[0].poolMaxActive=${DB_POOL_MAX} persistence.domain[0].poolMinIdle=${DB_POOL_MIN} diff --git a/docker/core/src/main/resources/core-ojson.properties b/docker/core/src/main/resources/core-ojson.properties deleted file mode 100644 index ba9fb297a02..00000000000 --- a/docker/core/src/main/resources/core-ojson.properties +++ /dev/null @@ -1,30 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=oracle.jdbc.OracleDriver -persistence.domain[0].jdbcURL=${DB_URL} -persistence.domain[0].schema=${DB_SCHEMA} -persistence.domain[0].dbUsername=${DB_USER} -persistence.domain[0].dbPassword=${DB_PASSWORD} -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.OracleDictionary -persistence.domain[0].orm=META-INF/spring-orm-ojson.xml -persistence.domain[0].poolMaxActive=${DB_POOL_MAX} -persistence.domain[0].poolMinIdle=${DB_POOL_MIN} - -persistence.indexesXML=classpath:ojson/indexes.xml -persistence.viewsXML=classpath:ojson/views.xml diff --git a/docker/core/src/main/resources/core-oracle.properties b/docker/core/src/main/resources/core-oracle.properties index 09903f70868..b92ee099755 100644 --- a/docker/core/src/main/resources/core-oracle.properties +++ b/docker/core/src/main/resources/core-oracle.properties @@ -15,14 +15,17 @@ # specific language governing permissions and limitations # under the License. +persistence.indexesXML=classpath:META-INF/oracle/indexes.xml +persistence.viewsXML=classpath:META-INF/oracle/views.xml + persistence.domain[0].key=Master persistence.domain[0].jdbcDriver=oracle.jdbc.OracleDriver persistence.domain[0].jdbcURL=${DB_URL} -persistence.domain[0].schema=${DB_SCHEMA} +persistence.domain[0].dbSchema=${DB_SCHEMA} persistence.domain[0].dbUsername=${DB_USER} persistence.domain[0].dbPassword=${DB_PASSWORD} persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.OracleDictionary -persistence.domain[0].orm=META-INF/spring-orm-oracle.xml +persistence.domain[0].orm=META-INF/oracle/spring-orm.xml persistence.domain[0].poolMaxActive=${DB_POOL_MAX} persistence.domain[0].poolMinIdle=${DB_POOL_MIN} diff --git a/docker/core/src/main/resources/core-postgresql.properties b/docker/core/src/main/resources/core-postgresql.properties index dd47cf4cebe..82fb6ee0393 100644 --- a/docker/core/src/main/resources/core-postgresql.properties +++ b/docker/core/src/main/resources/core-postgresql.properties @@ -14,6 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. + persistence.domain[0].key=Master persistence.domain[0].jdbcDriver=org.postgresql.Driver persistence.domain[0].jdbcURL=${DB_URL} diff --git a/docker/core/src/main/resources/core-sqlserver.properties b/docker/core/src/main/resources/core-sqlserver.properties deleted file mode 100644 index 8c7461c720c..00000000000 --- a/docker/core/src/main/resources/core-sqlserver.properties +++ /dev/null @@ -1,29 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=com.microsoft.sqlserver.jdbc.SQLServerDriver -persistence.domain[0].jdbcURL=${DB_URL} -persistence.domain[0].schema=${DB_SCHEMA} -persistence.domain[0].dbUsername=${DB_USER} -persistence.domain[0].dbPassword=${DB_PASSWORD} -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.SQLServerDictionary -persistence.domain[0].orm=META-INF/spring-orm-sqlserver.xml -persistence.domain[0].poolMaxActive=${DB_POOL_MAX} -persistence.domain[0].poolMinIdle=${DB_POOL_MIN} - -persistence.viewsXML=classpath:sqlserver_views.xml diff --git a/docker/src/main/resources/docker-compose/docker-compose-all.yml b/docker/src/main/resources/docker-compose/docker-compose-all.yml index 403c12fe3dd..f6bc8c77b2f 100644 --- a/docker/src/main/resources/docker-compose/docker-compose-all.yml +++ b/docker/src/main/resources/docker-compose/docker-compose-all.yml @@ -22,11 +22,11 @@ services: keymaster: - image: zookeeper:3.8.1 + image: zookeeper:3.9.2 restart: always db: - image: postgres:16 + image: postgres:16-alpine restart: always environment: POSTGRES_DB: syncope diff --git a/docker/src/main/resources/docker-compose/docker-compose-ha.yml b/docker/src/main/resources/docker-compose/docker-compose-ha.yml index 129b1c707a5..d1dd728e4c9 100644 --- a/docker/src/main/resources/docker-compose/docker-compose-ha.yml +++ b/docker/src/main/resources/docker-compose/docker-compose-ha.yml @@ -20,7 +20,7 @@ services: db: - image: postgres:16 + image: postgres:16-alpine restart: always environment: POSTGRES_DB: syncope diff --git a/docker/src/main/resources/docker-compose/docker-compose-majson.yml b/docker/src/main/resources/docker-compose/docker-compose-majson.yml deleted file mode 100644 index 9331524fb01..00000000000 --- a/docker/src/main/resources/docker-compose/docker-compose-majson.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# Full deployment (Core, Console, Enduser) on MariaDB with JSON_TABLE support - -services: - db: - image: mariadb:11 - restart: always - environment: - MYSQL_ROOT_PASSWORD: password - MYSQL_DATABASE: syncope - MYSQL_USER: syncope - MYSQL_PASSWORD: syncope - - syncope: - depends_on: - - db - command: ["wait-for-it", "db:3306", "-t", "60", "--", "/opt/syncope/bin/startup.sh"] - image: apache/syncope:${SYNCOPE_VERSION} - ports: - - "18080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker,majson,saml2 - DB_URL: jdbc:mariadb://db:3306/syncope?characterEncoding=UTF-8&relaxAutoCommit=true&useSSL=false - DB_USER: root - DB_PASSWORD: password - DB_POOL_MAX: 20 - DB_POOL_MIN: 5 - OPENJPA_REMOTE_COMMIT: sjvm - KEYMASTER_ADDRESS: http://localhost:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope:8080/syncope/rest/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} - - syncope-console: - depends_on: - - syncope - image: apache/syncope-console:${SYNCOPE_VERSION} - ports: - - "28080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker - KEYMASTER_ADDRESS: http://syncope:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope-console:8080/syncope-console/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} - - syncope-enduser: - depends_on: - - syncope - image: apache/syncope-enduser:${SYNCOPE_VERSION} - ports: - - "38080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker - KEYMASTER_ADDRESS: http://syncope:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope-enduser:8080/syncope-enduser/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} diff --git a/docker/src/main/resources/docker-compose/docker-compose-myjson.yml b/docker/src/main/resources/docker-compose/docker-compose-myjson.yml deleted file mode 100644 index 8b906d123c1..00000000000 --- a/docker/src/main/resources/docker-compose/docker-compose-myjson.yml +++ /dev/null @@ -1,84 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# Full deployment (Core, Console, Enduser) on MySQL with JSON_TABLE support - -services: - db: - image: mysql:9.0 - restart: always - environment: - MYSQL_ROOT_PASSWORD: password - MYSQL_DATABASE: syncope - MYSQL_USER: syncope - MYSQL_PASSWORD: syncope - - syncope: - depends_on: - - db - command: ["wait-for-it", "db:3306", "-t", "60", "--", "/opt/syncope/bin/startup.sh"] - image: apache/syncope:${SYNCOPE_VERSION} - ports: - - "18080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker,myjson,saml2 - LOADER_PATH: "/opt/syncope/conf,/opt/syncope/lib,/opt/syncope/jpa-json" - DB_URL: jdbc:mysql://db:3306/syncope?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8 - DB_USER: syncope - DB_PASSWORD: syncope - DB_POOL_MAX: 20 - DB_POOL_MIN: 5 - OPENJPA_REMOTE_COMMIT: sjvm - KEYMASTER_ADDRESS: http://localhost:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope:8080/syncope/rest/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} - - syncope-console: - depends_on: - - syncope - image: apache/syncope-console:${SYNCOPE_VERSION} - ports: - - "28080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker - KEYMASTER_ADDRESS: http://syncope:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope-console:8080/syncope-console/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} - - syncope-enduser: - depends_on: - - syncope - image: apache/syncope-enduser:${SYNCOPE_VERSION} - ports: - - "38080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker - KEYMASTER_ADDRESS: http://syncope:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope-enduser:8080/syncope-enduser/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} diff --git a/docker/src/main/resources/docker-compose/docker-compose-ojson.yml b/docker/src/main/resources/docker-compose/docker-compose-ojson.yml deleted file mode 100644 index 5175b6327c5..00000000000 --- a/docker/src/main/resources/docker-compose/docker-compose-ojson.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# Full deployment (Core, Console, Enduser) on Oracle with JSON support - -services: - db: - image: gvenzl/oracle-xe:21-slim - restart: always - environment: - ORACLE_PASSWORD: password - APP_USER: syncope - APP_USER_PASSWORD: syncope - - syncope: - depends_on: - - db - command: ["wait-for-it", "db:3306", "-t", "60", "--", "/opt/syncope/bin/startup.sh"] - image: apache/syncope:${SYNCOPE_VERSION} - ports: - - "18080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker,ojson,saml2 - DB_URL: jdbc:oracle:thin:@db:1521/XEPDB1 - DB_SCHEMA: SYNCOPE - DB_USER: syncope - DB_PASSWORD: syncope - DB_POOL_MAX: 20 - DB_POOL_MIN: 5 - OPENJPA_REMOTE_COMMIT: sjvm - KEYMASTER_ADDRESS: http://localhost:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope:8080/syncope/rest/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} - - syncope-console: - depends_on: - - syncope - image: apache/syncope-console:${SYNCOPE_VERSION} - ports: - - "28080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker - KEYMASTER_ADDRESS: http://syncope:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope-console:8080/syncope-console/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} - - syncope-enduser: - depends_on: - - syncope - image: apache/syncope-enduser:${SYNCOPE_VERSION} - ports: - - "38080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker - KEYMASTER_ADDRESS: http://syncope:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope-enduser:8080/syncope-enduser/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} diff --git a/docker/src/main/resources/docker-compose/docker-compose-oracle.yml b/docker/src/main/resources/docker-compose/docker-compose-oracle.yml index 7cae51ac0f5..5954cc31c80 100644 --- a/docker/src/main/resources/docker-compose/docker-compose-oracle.yml +++ b/docker/src/main/resources/docker-compose/docker-compose-oracle.yml @@ -19,7 +19,7 @@ services: db: - image: gvenzl/oracle-xe:21-slim + image: gvenzl/oracle-free:23-slim-faststart restart: always environment: ORACLE_PASSWORD: password diff --git a/docker/src/main/resources/docker-compose/docker-compose-pgjsonb.yml b/docker/src/main/resources/docker-compose/docker-compose-pgjsonb.yml deleted file mode 100644 index e74f5e6c182..00000000000 --- a/docker/src/main/resources/docker-compose/docker-compose-pgjsonb.yml +++ /dev/null @@ -1,82 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# Full deployment (Core, Console, Enduser) on PostgreSQL with JSONB support - -services: - db: - image: postgres:16 - restart: always - environment: - POSTGRES_DB: syncope - POSTGRES_USER: syncope - POSTGRES_PASSWORD: syncope - - syncope: - depends_on: - - db - image: apache/syncope:${SYNCOPE_VERSION} - ports: - - "18080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker,pgjsonb,saml2 - LOADER_PATH: "/opt/syncope/conf,/opt/syncope/lib,/opt/syncope/jpa-json" - DB_URL: jdbc:postgresql://db:5432/syncope?stringtype=unspecified - DB_USER: syncope - DB_PASSWORD: syncope - DB_POOL_MAX: 20 - DB_POOL_MIN: 5 - OPENJPA_REMOTE_COMMIT: sjvm - KEYMASTER_ADDRESS: http://localhost:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope:8080/syncope/rest/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} - - syncope-console: - depends_on: - - syncope - image: apache/syncope-console:${SYNCOPE_VERSION} - ports: - - "28080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker - KEYMASTER_ADDRESS: http://syncope:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope-console:8080/syncope-console/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} - - syncope-enduser: - depends_on: - - syncope - image: apache/syncope-enduser:${SYNCOPE_VERSION} - ports: - - "38080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker - KEYMASTER_ADDRESS: http://syncope:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope-enduser:8080/syncope-enduser/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} diff --git a/docker/src/main/resources/docker-compose/docker-compose-postgresql.yml b/docker/src/main/resources/docker-compose/docker-compose-postgresql.yml index 50636da09b6..c00794d6fc2 100644 --- a/docker/src/main/resources/docker-compose/docker-compose-postgresql.yml +++ b/docker/src/main/resources/docker-compose/docker-compose-postgresql.yml @@ -19,7 +19,7 @@ services: db: - image: postgres:16 + image: postgres:16-alpine restart: always environment: POSTGRES_DB: syncope diff --git a/docker/src/main/resources/docker-compose/docker-compose-sqlserver.yml b/docker/src/main/resources/docker-compose/docker-compose-sqlserver.yml deleted file mode 100644 index 2b3bac439e5..00000000000 --- a/docker/src/main/resources/docker-compose/docker-compose-sqlserver.yml +++ /dev/null @@ -1,84 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# Full deployment (Core, Console, Enduser) on MS SQL Server - -services: - db: - image: mcmoe/mssqldocker:latest - restart: always - environment: - ACCEPT_EULA: Y - SA_PASSWORD: 2astazeY - MSSQL_DB: syncope - MSSQL_USER: syncope - MSSQL_PASSWORD: Syncope123 - - syncope: - depends_on: - - db - image: apache/syncope:${SYNCOPE_VERSION} - ports: - - "18080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker,sqlserver,saml2 - DB_URL: jdbc:sqlserver://db:1433;databaseName=syncope - DB_SCHEMA: dbo - DB_USER: syncope - DB_PASSWORD: Syncope123 - DB_POOL_MAX: 20 - DB_POOL_MIN: 5 - OPENJPA_REMOTE_COMMIT: sjvm - KEYMASTER_ADDRESS: http://localhost:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope:8080/syncope/rest/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} - - syncope-console: - depends_on: - - syncope - image: apache/syncope-console:${SYNCOPE_VERSION} - ports: - - "28080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker - KEYMASTER_ADDRESS: http://syncope:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope-console:8080/syncope-console/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} - - syncope-enduser: - depends_on: - - syncope - image: apache/syncope-enduser:${SYNCOPE_VERSION} - ports: - - "38080:8080" - restart: always - environment: - SPRING_PROFILES_ACTIVE: docker - KEYMASTER_ADDRESS: http://syncope:8080/syncope/rest/keymaster - KEYMASTER_USERNAME: ${KEYMASTER_USERNAME} - KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD} - SERVICE_DISCOVERY_ADDRESS: http://syncope-enduser:8080/syncope-enduser/ - ANONYMOUS_USER: ${ANONYMOUS_USER} - ANONYMOUS_KEY: ${ANONYMOUS_KEY} diff --git a/ext/elasticsearch/persistence/src/test/java/org/apache/syncope/core/persistence/elasticsearch/dao/ElasticsearchAnySearchDAOTest.java b/ext/elasticsearch/persistence/src/test/java/org/apache/syncope/core/persistence/elasticsearch/dao/ElasticsearchAnySearchDAOTest.java index a836462ebeb..4fc5a7fbbe9 100644 --- a/ext/elasticsearch/persistence/src/test/java/org/apache/syncope/core/persistence/elasticsearch/dao/ElasticsearchAnySearchDAOTest.java +++ b/ext/elasticsearch/persistence/src/test/java/org/apache/syncope/core/persistence/elasticsearch/dao/ElasticsearchAnySearchDAOTest.java @@ -58,8 +58,8 @@ import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.utils.RealmUtils; import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser; +import org.apache.syncope.core.persistence.jpa.entity.user.JSONUPlainAttrValue; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.ext.elasticsearch.client.ElasticsearchUtils; import org.junit.jupiter.api.BeforeEach; @@ -168,7 +168,7 @@ public void searchRequest4groupOwner() throws IOException { // 1. mock AnyUtils anyUtils = mock(AnyUtils.class); when(anyUtils.getField("key")).thenReturn(Optional.of(ReflectionUtils.findField(JPAUser.class, "id"))); - when(anyUtils.newPlainAttrValue()).thenReturn(new JPAUPlainAttrValue()); + when(anyUtils.newPlainAttrValue()).thenReturn(new JSONUPlainAttrValue()); when(anyUtilsFactory.getInstance(AnyTypeKind.USER)).thenReturn(anyUtils); @@ -210,7 +210,7 @@ public void issueSYNCOPE1725() throws IOException { // 1. mock AnyUtils anyUtils = mock(AnyUtils.class); when(anyUtils.getField("key")).thenReturn(Optional.of(ReflectionUtils.findField(JPAUser.class, "id"))); - JPAUPlainAttrValue value = new JPAUPlainAttrValue(); + JSONUPlainAttrValue value = new JSONUPlainAttrValue(); when(anyUtils.newPlainAttrValue()).thenReturn(value); when(anyUtilsFactory.getInstance(AnyTypeKind.USER)).thenReturn(anyUtils); diff --git a/ext/oidcc4ui/persistence-jpa/pom.xml b/ext/oidcc4ui/persistence-jpa/pom.xml index 0aa2ebca3ad..8bd1e84b39c 100644 --- a/ext/oidcc4ui/persistence-jpa/pom.xml +++ b/ext/oidcc4ui/persistence-jpa/pom.xml @@ -56,23 +56,9 @@ under the License. org.apache.openjpa openjpa-maven-plugin true - - - com.h2database - h2 - ${h2.version} - - ${rootpom.basedir}/core/persistence-jpa/src/main/resources/persistence-enhance.xml org/apache/syncope/core/persistence/jpa/entity/**/*.class - org.springframework.jdbc.datasource.DriverManagerDataSource - - driverClassName=org.h2.Driver, - url=jdbc:h2:mem:syncopedb - username=sa, - password= - diff --git a/ext/opensearch/persistence/src/test/java/org/apache/syncope/core/persistence/opensearch/dao/OpenSearchAnySearchDAOTest.java b/ext/opensearch/persistence/src/test/java/org/apache/syncope/core/persistence/opensearch/dao/OpenSearchAnySearchDAOTest.java index 8eb93024223..2afeb424eaa 100644 --- a/ext/opensearch/persistence/src/test/java/org/apache/syncope/core/persistence/opensearch/dao/OpenSearchAnySearchDAOTest.java +++ b/ext/opensearch/persistence/src/test/java/org/apache/syncope/core/persistence/opensearch/dao/OpenSearchAnySearchDAOTest.java @@ -52,8 +52,8 @@ import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.utils.RealmUtils; import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema; -import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser; +import org.apache.syncope.core.persistence.jpa.entity.user.JSONUPlainAttrValue; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.ext.opensearch.client.OpenSearchUtils; import org.junit.jupiter.api.BeforeEach; @@ -169,7 +169,7 @@ public void searchRequest4groupOwner() throws IOException { // 1. mock AnyUtils anyUtils = mock(AnyUtils.class); when(anyUtils.getField("key")).thenReturn(Optional.of(ReflectionUtils.findField(JPAUser.class, "id"))); - when(anyUtils.newPlainAttrValue()).thenReturn(new JPAUPlainAttrValue()); + when(anyUtils.newPlainAttrValue()).thenReturn(new JSONUPlainAttrValue()); when(anyUtilsFactory.getInstance(AnyTypeKind.USER)).thenReturn(anyUtils); @@ -211,7 +211,7 @@ public void issueSYNCOPE1725() throws IOException { // 1. mock AnyUtils anyUtils = mock(AnyUtils.class); when(anyUtils.getField("key")).thenReturn(Optional.of(ReflectionUtils.findField(JPAUser.class, "id"))); - JPAUPlainAttrValue value = new JPAUPlainAttrValue(); + JSONUPlainAttrValue value = new JSONUPlainAttrValue(); when(anyUtils.newPlainAttrValue()).thenReturn(value); when(anyUtilsFactory.getInstance(AnyTypeKind.USER)).thenReturn(anyUtils); diff --git a/ext/saml2sp4ui/persistence-jpa/pom.xml b/ext/saml2sp4ui/persistence-jpa/pom.xml index fc25f85628f..112aba9e9dc 100644 --- a/ext/saml2sp4ui/persistence-jpa/pom.xml +++ b/ext/saml2sp4ui/persistence-jpa/pom.xml @@ -56,23 +56,9 @@ under the License. org.apache.openjpa openjpa-maven-plugin true - - - com.h2database - h2 - ${h2.version} - - ${rootpom.basedir}/core/persistence-jpa/src/main/resources/persistence-enhance.xml org/apache/syncope/core/persistence/jpa/entity/**/*.class - org.springframework.jdbc.datasource.DriverManagerDataSource - - driverClassName=org.h2.Driver, - url=jdbc:h2:mem:syncopedb - username=sa, - password= - diff --git a/fit/console-reference/pom.xml b/fit/console-reference/pom.xml index 96ec65d0a70..e893aad8273 100644 --- a/fit/console-reference/pom.xml +++ b/fit/console-reference/pom.xml @@ -82,11 +82,6 @@ under the License. - - com.h2database - h2 - test - org.apache.syncope.fit syncope-fit-build-tools @@ -101,6 +96,11 @@ under the License. war test + + org.postgresql + postgresql + test + @@ -137,13 +137,11 @@ under the License. file:/dev/./urandom true - - true - com.h2database - h2 + org.postgresql + postgresql @@ -248,7 +246,6 @@ under the License. - hotswap diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml index 34621154933..7b16eba8744 100644 --- a/fit/core-reference/pom.xml +++ b/fit/core-reference/pom.xml @@ -38,8 +38,8 @@ under the License. none - com.h2database - h2 + org.postgresql + postgresql obscureSecretKeyValue @@ -76,6 +76,12 @@ under the License. ${project.version} + + org.apache.syncope.fit + persistence-embedded + ${project.version} + + org.apache.syncope.fit @@ -84,11 +90,6 @@ under the License. war test - - com.h2database - h2 - test - org.apache.syncope.common.keymaster.self syncope-common-keymaster-client-self @@ -185,6 +186,16 @@ under the License. ${project.version} test + + org.postgresql + postgresql + test + + + com.h2database + h2 + test + org.apache.wicket wicket-tester @@ -292,13 +303,11 @@ under the License. ${settings.localRepository}/org/codehaus/cargo/cargo-container-archives ${project.build.directory}/cargo/extract - 300000 + 1800000 file:/dev/./urandom true - true - ${obscureSecretKey} @@ -722,26 +731,19 @@ under the License. - pgjsonb-it + mysql-it - org.postgresql - postgresql + com.mysql + mysql-connector-j - embedded,pgjsonb + embedded,mysql - org.apache.syncope.core - syncope-core-persistence-jpa-json - ${project.version} - - - - org.postgresql - postgresql - ${jdbc.postgresql.version} + com.mysql + mysql-connector-j test @@ -750,14 +752,6 @@ under the License. clean verify - - org.apache.maven.plugins - maven-war-plugin - - WEB-INF/classes/domains/Two* - - - org.apache.maven.plugins maven-failsafe-plugin @@ -775,35 +769,42 @@ under the License. - postgres - postgres:${docker.postgresql.version} + mysql + mysql:${docker.mysql.version} + --skip-log-bin --server-id=1 --sort_buffer_size=348M - syncope - syncope - syncope + password + syncope + syncope + syncope + + /var/lib/mysql:rw + + + + ${basedir}/src/test/resources/mysql_init.sql:/docker-entrypoint-initdb.d/mysql_init.sql:ro + + - database system is ready to accept connections + MySQL init process done. Ready for start up. - - /var/lib/postgresql/data:rw - - start-postgres + start-mysql pre-integration-test start - stop-postgres + stop-mysql post-integration-test stop @@ -820,38 +821,29 @@ under the License. - ${docker.container.postgres.ip} + ${docker.container.mysql.ip} - - - - ${basedir}/../../core/persistence-jpa-json/src/test/resources/domains - ${project.build.outputDirectory}/domains - true - - - postgres-it + mariadb-it - org.postgresql - postgresql + org.mariadb.jdbc + mariadb-java-client - embedded,postgres + embedded,mariadb - org.postgresql - postgresql - ${jdbc.postgresql.version} + org.mariadb.jdbc + mariadb-java-client test @@ -877,35 +869,41 @@ under the License. - postgres - postgres:${docker.postgresql.version} + mariadb + mariadb:${docker.mariadb.version} - syncope - syncope - syncope + password + syncope + syncope + syncope + + /var/lib/mysql:rw + + + + ${basedir}/src/test/resources/mysql_init.sql:/docker-entrypoint-initdb.d/mysql_init.sql:ro + + - database system is ready to accept connections + MariaDB init process done. Ready for start up. - - /var/lib/postgresql/data:rw - - start-postgres + start-mariadb pre-integration-test start - stop-postgres + stop-mariadb post-integration-test stop @@ -914,7 +912,7 @@ under the License. - + org.codehaus.cargo cargo-maven3-plugin @@ -922,7 +920,7 @@ under the License. - ${docker.container.postgres.ip} + ${docker.container.mariadb.ip} @@ -932,26 +930,20 @@ under the License. - myjson-it + oracle-it - com.mysql - mysql-connector-j + com.oracle.database.jdbc + ojdbc11 + 120000 - embedded,myjson + embedded,oracle - org.apache.syncope.core - syncope-core-persistence-jpa-json - ${project.version} - - - - com.mysql - mysql-connector-j - ${jdbc.mysql.version} + com.oracle.database.jdbc + ojdbc11 test @@ -960,14 +952,6 @@ under the License. clean verify - - org.apache.maven.plugins - maven-war-plugin - - WEB-INF/classes/domains/Two* - - - org.apache.maven.plugins maven-failsafe-plugin @@ -985,22 +969,23 @@ under the License. - mysql - mysql:${docker.mysql.version} + oracle + gvenzl/oracle-free:${docker.oracle.version} - --skip-log-bin --server-id=1 --sort_buffer_size=348M - password - syncope - syncope - syncope + password + syncope + syncope - - /var/lib/mysql:rw - + + + ${basedir}/src/test/resources/1_oracle_init.sql:/container-entrypoint-initdb.d/1_oracle_init.sql:ro + ${basedir}/src/test/resources/2_oracle_init.sql:/container-entrypoint-initdb.d/2_oracle_init.sql:ro + + - MySQL init process done. Ready for start up. - + DATABASE IS READY TO USE + @@ -1008,14 +993,21 @@ under the License. - start-mysql + buid-oracle + initialize + + build + + + + start-oracle pre-integration-test start - stop-mysql + stop-oracle post-integration-test stop @@ -1032,39 +1024,39 @@ under the License. - ${docker.container.mysql.ip} + ${docker.container.oracle.ip} - - - - ${basedir}/../../core/persistence-jpa-json/src/test/resources/domains - ${project.build.outputDirectory}/domains - true - - - mysql-it + neo4j-it - com.mysql - mysql-connector-j - - embedded,mysql + embedded,neo4j - com.mysql - mysql-connector-j - ${jdbc.mysql.version} - test + org.apache.syncope.core + syncope-core-self-keymaster-starter + ${project.version} + + + org.apache.syncope.core + syncope-core-persistence-jpa + + + + + + org.apache.syncope.core + syncope-core-persistence-neo4j + ${project.version} @@ -1076,11 +1068,6 @@ under the License. org.apache.maven.plugins maven-failsafe-plugin true - - - **/org/apache/syncope/fit/core/*ITCase.java - - @@ -1089,37 +1076,59 @@ under the License. - mysql - mysql:${docker.mysql.version} + neo4j + neo4j:${docker.neo4j.version} - --skip-log-bin --server-id=1 --sort_buffer_size=348M - password - syncope - syncope - syncope + none + ["apoc"] + + Started. + + - /var/lib/mysql:rw + /data:rw + /logs:rw + /var/lib/neo4j/data:rw + /var/lib/neo4j/logs:rw + /var/lib/neo4j/metrics:rw + + + + neo4jTwo + neo4j:${docker.neo4j.version} + + + none + ["apoc"] + - MySQL init process done. Ready for start up. + Started. + + /data:rw + /logs:rw + /var/lib/neo4j/data:rw + /var/lib/neo4j/logs:rw + /var/lib/neo4j/metrics:rw + - + - start-mysql + start-neo4j pre-integration-test start - stop-mysql + stop-neo4j post-integration-test stop @@ -1136,669 +1145,31 @@ under the License. - ${docker.container.mysql.ip} + ${docker.container.neo4j.ip} + ${docker.container.neo4jTwo.ip} + + + + ${basedir}/../../core/persistence-neo4j/src/test/resources/domains + ${project.build.outputDirectory}/domains + true + + - majson-it - - - org.mariadb.jdbc - mariadb-java-client - - embedded,majson - + payara-it org.apache.syncope.core - syncope-core-persistence-jpa-json - ${project.version} - - - - org.mariadb.jdbc - mariadb-java-client - ${jdbc.mariadb.version} - test - - - - - clean verify - - - - org.apache.maven.plugins - maven-war-plugin - - WEB-INF/classes/domains/Two* - - - - - org.apache.maven.plugins - maven-failsafe-plugin - true - - - **/org/apache/syncope/fit/core/*ITCase.java - - - - - - io.fabric8 - docker-maven-plugin - - - - mariadb - mariadb:${docker.mariadb.version} - - - password - syncope - syncope - syncope - - - /var/lib/mysql:rw - - - MariaDB init process done. Ready for start up. - - - - - - - - - start-mariadb - pre-integration-test - - start - - - - stop-mariadb - post-integration-test - - stop - remove - - - - - - - org.codehaus.cargo - cargo-maven3-plugin - true - - - - ${docker.container.mariadb.ip} - - - - - - - - - ${basedir}/../../core/persistence-jpa-json/src/test/resources/domains - ${project.build.outputDirectory}/domains - true - - - - - - - mariadb-it - - - org.mariadb.jdbc - mariadb-java-client - - embedded,mariadb - - - - - org.mariadb.jdbc - mariadb-java-client - ${jdbc.mariadb.version} - test - - - - - clean verify - - - - org.apache.maven.plugins - maven-failsafe-plugin - true - - - **/org/apache/syncope/fit/core/*ITCase.java - - - - - - io.fabric8 - docker-maven-plugin - - - - mariadb - mariadb:${docker.mariadb.version} - - - password - syncope - syncope - syncope - - - /var/lib/mysql:rw - - - MariaDB init process done. Ready for start up. - - - - - - - - - start-mariadb - pre-integration-test - - start - - - - stop-mariadb - post-integration-test - - stop - remove - - - - - - - org.codehaus.cargo - cargo-maven3-plugin - true - - - - ${docker.container.mariadb.ip} - - - - - - - - - - ojson-it - - - com.oracle.database.jdbc - ojdbc11 - 120000 - - embedded,ojson - - - - - org.apache.syncope.core - syncope-core-persistence-jpa-json - ${project.version} - - - - com.oracle.database.jdbc - ojdbc11 - ${jdbc.oracle.version} - test - - - - - clean verify - - - - org.apache.maven.plugins - maven-failsafe-plugin - true - - - **/org/apache/syncope/fit/core/*ITCase.java - - - - - - io.fabric8 - docker-maven-plugin - - - - oracle - gvenzl/oracle-xe:21-slim - - - password - syncope - syncope - - - DATABASE IS READY TO USE - - - - - - - - - buid-oracle - initialize - - build - - - - start-oracle - pre-integration-test - - start - - - - stop-oracle - post-integration-test - - stop - remove - - - - - - - org.codehaus.cargo - cargo-maven3-plugin - true - - - - ${docker.container.oracle.ip} - - - - - - - - - ${basedir}/../../core/persistence-jpa-json/src/test/resources/domains - ${project.build.outputDirectory}/domains - true - - - - - - - oracle-it - - - com.oracle.database.jdbc - ojdbc11 - 120000 - - embedded,oracle - - - - - com.oracle.database.jdbc - ojdbc11 - ${jdbc.oracle.version} - test - - - - - clean verify - - - - org.apache.maven.plugins - maven-failsafe-plugin - true - - - **/org/apache/syncope/fit/core/*ITCase.java - - - - - - io.fabric8 - docker-maven-plugin - - - - oracle - gvenzl/oracle-xe:21-slim - - - password - syncope - syncope - - - DATABASE IS READY TO USE - - - - - - - - - buid-oracle - initialize - - build - - - - start-oracle - pre-integration-test - - start - - - - stop-oracle - post-integration-test - - stop - remove - - - - - - - org.codehaus.cargo - cargo-maven3-plugin - true - - - - ${docker.container.oracle.ip} - - - - - - - - - - sqlserver-it - - - com.microsoft.sqlserver - mssql-jdbc - - embedded,sqlserver - - - - - com.microsoft.sqlserver - mssql-jdbc - ${jdbc.mssql.version} - test - - - - - clean verify - - - - org.apache.maven.plugins - maven-failsafe-plugin - true - - - **/org/apache/syncope/fit/core/*ITCase.java - - - - - - io.fabric8 - docker-maven-plugin - - - - sqlserver - mcmoe/mssqldocker:latest - - - Y - 2astazeY - syncope - syncope - Syncope123 - - - MSSQL CONFIG COMPLETE - - - - - - - - - start-sqlserver - pre-integration-test - - start - - - - stop-sqlserver - post-integration-test - - stop - remove - - - - - - - org.codehaus.cargo - cargo-maven3-plugin - true - - - - ${docker.container.sqlserver.ip} - - - - - - - - - - neo4j-it - - - embedded,neo4j - - - - - org.apache.syncope.core - syncope-core-self-keymaster-starter - ${project.version} - - - org.apache.syncope.core - syncope-core-persistence-jpa - - - - - - org.apache.syncope.core - syncope-core-persistence-neo4j - ${project.version} - - - - - clean verify - - - - org.apache.maven.plugins - maven-failsafe-plugin - true - - - - io.fabric8 - docker-maven-plugin - - - - neo4j - neo4j:${docker.neo4j.version} - - - none - ["apoc"] - - - Started. - - - - /data:rw - /logs:rw - /var/lib/neo4j/data:rw - /var/lib/neo4j/logs:rw - /var/lib/neo4j/metrics:rw - - - - - neo4jTwo - neo4j:${docker.neo4j.version} - - - none - ["apoc"] - - - Started. - - - - /data:rw - /logs:rw - /var/lib/neo4j/data:rw - /var/lib/neo4j/logs:rw - /var/lib/neo4j/metrics:rw - - - - - - - - start-neo4j - pre-integration-test - - start - - - - stop-neo4j - post-integration-test - - stop - remove - - - - - - - org.codehaus.cargo - cargo-maven3-plugin - true - - - - ${docker.container.neo4j.ip} - ${docker.container.neo4jTwo.ip} - - - - - - - - - ${basedir}/../../core/persistence-neo4j/src/test/resources/domains - ${project.build.outputDirectory}/domains - true - - - - - - - payara-it - - - - org.apache.syncope.core - syncope-core-starter + syncope-core-starter ${project.version} @@ -1933,8 +1304,8 @@ under the License. - com.h2database - h2 + org.postgresql + postgresql @@ -1948,7 +1319,7 @@ under the License. true - wildfly31x + wildfly32x https://github.com/wildfly/wildfly/releases/download/${wildfly.version}/wildfly-${wildfly.version}.zip ${settings.localRepository}/org/codehaus/cargo/cargo-container-archives @@ -2017,7 +1388,6 @@ under the License. - hotswap diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/EnableFlowableForTestUsers.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/EnableFlowableForTestUsers.java index 78d01480781..481892964b0 100644 --- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/EnableFlowableForTestUsers.java +++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/EnableFlowableForTestUsers.java @@ -46,7 +46,7 @@ public void init(final DataSource datasource) { String procDef = null; try (Connection conn = datasource.getConnection(); PreparedStatement stmt = conn.prepareStatement( - "SELECT ID_ FROM ACT_RE_PROCDEF WHERE KEY_=?")) { + "SELECT ID_ FROM ACT_RE_PROCDEF WHERE KEY_=?")) { stmt.setString(1, "userWorkflow"); ResultSet rs = stmt.executeQuery(); @@ -66,7 +66,7 @@ public void init(final DataSource datasource) { for (User user : userDAO.findAll()) { int value = counter.addAndGet(1); try (Connection conn = datasource.getConnection(); PreparedStatement stmt = conn.prepareStatement( - """ + """ INSERT INTO ACT_RU_EXECUTION(ID_,REV_,PROC_INST_ID_,BUSINESS_KEY_,PROC_DEF_ID_,ACT_ID_, IS_ACTIVE_,IS_CONCURRENT_,IS_SCOPE_,IS_EVENT_SCOPE_,SUSPENSION_STATE_) VALUES(?,?,?,?,?,?,?,?,?,?,?) @@ -82,7 +82,7 @@ INSERT INTO ACT_RU_EXECUTION(ID_,REV_,PROC_INST_ID_,BUSINESS_KEY_,PROC_DEF_ID_,A stmt.setBoolean(8, false); stmt.setBoolean(9, true); stmt.setBoolean(10, false); - stmt.setBoolean(11, true); + stmt.setInt(11, 0); stmt.executeUpdate(); } catch (Exception e) { @@ -91,7 +91,7 @@ INSERT INTO ACT_RU_EXECUTION(ID_,REV_,PROC_INST_ID_,BUSINESS_KEY_,PROC_DEF_ID_,A value = counter.addAndGet(1); try (Connection conn = datasource.getConnection(); PreparedStatement stmt = conn.prepareStatement( - """ + """ INSERT INTO ACT_RU_TASK(ID_,REV_,EXECUTION_ID_,PROC_INST_ID_,PROC_DEF_ID_,NAME_,TASK_DEF_KEY_, PRIORITY_,CREATE_TIME_) VALUES(?,?,?,?,?,?,?,?,?) diff --git a/fit/core-reference/src/main/resources/core-embedded.properties b/fit/core-reference/src/main/resources/core-embedded.properties index 1cbd7e0262d..ae526112808 100644 --- a/fit/core-reference/src/main/resources/core-embedded.properties +++ b/fit/core-reference/src/main/resources/core-embedded.properties @@ -14,6 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +embedded.databases=syncope,syncopetwo,syncopetest management.endpoints.web.exposure.include=health,info,beans,env,loggers,entityCache @@ -26,36 +27,26 @@ service.discovery.address=http://localhost:9080/syncope/rest/ spring.devtools.livereload.enabled=false spring.devtools.restart.enabled=false -# H2 -spring.h2.console.enabled=true -spring.h2.console.path=/h2 - -spring.datasource.url=jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1 -spring.datasource.username=sa -spring.datasource.password= -spring.datasource.driver-class-name=org.h2.Driver - - security.adminUser=${adminUser} security.anonymousUser=${anonymousUser} security.jwsKey=${jwsKey} security.secretKey=${secretKey} persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=org.h2.Driver -persistence.domain[0].jdbcURL=jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1 -persistence.domain[0].dbUsername=sa -persistence.domain[0].dbPassword= -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.H2Dictionary +persistence.domain[0].jdbcDriver=org.postgresql.Driver +persistence.domain[0].jdbcURL=jdbc:postgresql://localhost:5432/syncope?stringtype=unspecified +persistence.domain[0].dbUsername=syncope +persistence.domain[0].dbPassword=syncope +persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDictionary persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 persistence.domain[1].key=Two -persistence.domain[1].jdbcDriver=org.h2.Driver -persistence.domain[1].jdbcURL=jdbc:h2:mem:syncopetwo;DB_CLOSE_DELAY=-1 -persistence.domain[1].dbUsername=sa -persistence.domain[1].dbPassword= -persistence.domain[1].databasePlatform=org.apache.openjpa.jdbc.sql.H2Dictionary +persistence.domain[1].jdbcDriver=org.postgresql.Driver +persistence.domain[1].jdbcURL=jdbc:postgresql://localhost:5432/syncopetwo?stringtype=unspecified +persistence.domain[1].dbUsername=syncopetwo +persistence.domain[1].dbPassword=syncopetwo +persistence.domain[1].databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDictionary persistence.domain[1].poolMaxActive=20 persistence.domain[1].poolMinIdle=5 persistence.domain[1].adminPassword=2AA60A8FF7FCD473D321E0146AFD9E26DF395147 diff --git a/fit/core-reference/src/main/resources/core-majson.properties b/fit/core-reference/src/main/resources/core-majson.properties deleted file mode 100644 index e9857c287b2..00000000000 --- a/fit/core-reference/src/main/resources/core-majson.properties +++ /dev/null @@ -1,34 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -persistence.indexesXML=classpath:majson/indexes.xml -persistence.viewsXML=classpath:majson/views.xml - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=org.mariadb.jdbc.Driver -persistence.domain[0].jdbcURL=jdbc:mariadb://${DB_CONTAINER_IP}:3306/syncope?characterEncoding=UTF-8 -# keep the next two lines until https://jira.mariadb.org/browse/MDEV-27898 is fixed -persistence.domain[0].dbUsername=root -persistence.domain[0].dbPassword=password -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MariaDBDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3) -persistence.domain[0].orm=META-INF/spring-orm-majson.xml -persistence.domain[0].poolMaxActive=10 -persistence.domain[0].poolMinIdle=2 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_mariadb.sql - diff --git a/fit/core-reference/src/main/resources/core-mariadb.properties b/fit/core-reference/src/main/resources/core-mariadb.properties index 87039637fbc..7af7cf533ca 100644 --- a/fit/core-reference/src/main/resources/core-mariadb.properties +++ b/fit/core-reference/src/main/resources/core-mariadb.properties @@ -15,11 +15,29 @@ # specific language governing permissions and limitations # under the License. +persistence.indexesXML=classpath:META-INF/mariadb/indexes.xml +persistence.viewsXML=classpath:META-INF/mariadb/views.xml + persistence.domain[0].key=Master persistence.domain[0].jdbcDriver=org.mariadb.jdbc.Driver persistence.domain[0].jdbcURL=jdbc:mariadb://${DB_CONTAINER_IP}:3306/syncope?characterEncoding=UTF-8 -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=syncope +# keep the next two lines until https://jira.mariadb.org/browse/MDEV-27898 is fixed +persistence.domain[0].dbUsername=root +persistence.domain[0].dbPassword=password persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MariaDBDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3) -persistence.domain[0].poolMaxActive=20 -persistence.domain[0].poolMinIdle=5 +persistence.domain[0].orm=META-INF/mariadb/spring-orm.xml +persistence.domain[0].poolMaxActive=10 +persistence.domain[0].poolMinIdle=2 + +persistence.domain[1].key=Two +persistence.domain[1].jdbcDriver=org.mariadb.jdbc.Driver +persistence.domain[1].jdbcURL=jdbc:mariadb://${DB_CONTAINER_IP}:3306/syncopetwo?characterEncoding=UTF-8 +# keep the next two lines until https://jira.mariadb.org/browse/MDEV-27898 is fixed +persistence.domain[1].dbUsername=root +persistence.domain[1].dbPassword=password +persistence.domain[1].databasePlatform=org.apache.openjpa.jdbc.sql.MariaDBDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3) +persistence.domain[1].orm=META-INF/mariadb/spring-orm.xml +persistence.domain[1].poolMaxActive=20 +persistence.domain[1].poolMinIdle=5 +persistence.domain[1].adminPassword=2AA60A8FF7FCD473D321E0146AFD9E26DF395147 +persistence.domain[1].adminCipherAlgorithm=SHA diff --git a/fit/core-reference/src/main/resources/core-myjson.properties b/fit/core-reference/src/main/resources/core-myjson.properties deleted file mode 100644 index ad627bafd5a..00000000000 --- a/fit/core-reference/src/main/resources/core-myjson.properties +++ /dev/null @@ -1,29 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -persistence.indexesXML=classpath:myjson/indexes.xml -persistence.viewsXML=classpath:myjson/views.xml - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=com.mysql.cj.jdbc.Driver -persistence.domain[0].jdbcURL=jdbc:mysql://${DB_CONTAINER_IP}:3306/syncope?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8 -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=syncope -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3,useSetStringForClobs=true) -persistence.domain[0].orm=META-INF/spring-orm-myjson.xml -persistence.domain[0].poolMaxActive=20 -persistence.domain[0].poolMinIdle=5 diff --git a/fit/core-reference/src/main/resources/core-mysql.properties b/fit/core-reference/src/main/resources/core-mysql.properties index e8ca635e718..f18b05d3100 100644 --- a/fit/core-reference/src/main/resources/core-mysql.properties +++ b/fit/core-reference/src/main/resources/core-mysql.properties @@ -15,11 +15,27 @@ # specific language governing permissions and limitations # under the License. +persistence.indexesXML=classpath:META-INF/mysql/indexes.xml +persistence.viewsXML=classpath:META-INF/mysql/views.xml + persistence.domain[0].key=Master persistence.domain[0].jdbcDriver=com.mysql.cj.jdbc.Driver persistence.domain[0].jdbcURL=jdbc:mysql://${DB_CONTAINER_IP}:3306/syncope?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8 persistence.domain[0].dbUsername=syncope persistence.domain[0].dbPassword=syncope persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3,useSetStringForClobs=true) +persistence.domain[0].orm=META-INF/mysql/spring-orm.xml persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 + +persistence.domain[1].key=Two +persistence.domain[1].jdbcDriver=com.mysql.cj.jdbc.Driver +persistence.domain[1].jdbcURL=jdbc:mysql://${DB_CONTAINER_IP}:3306/syncopetwo?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8 +persistence.domain[1].dbUsername=syncopetwo +persistence.domain[1].dbPassword=syncopetwo +persistence.domain[1].databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3,useSetStringForClobs=true) +persistence.domain[1].orm=META-INF/mysql/spring-orm.xml +persistence.domain[1].poolMaxActive=20 +persistence.domain[1].poolMinIdle=5 +persistence.domain[1].adminPassword=2AA60A8FF7FCD473D321E0146AFD9E26DF395147 +persistence.domain[1].adminCipherAlgorithm=SHA diff --git a/fit/core-reference/src/main/resources/core-ojson.properties b/fit/core-reference/src/main/resources/core-ojson.properties deleted file mode 100644 index 221b3577896..00000000000 --- a/fit/core-reference/src/main/resources/core-ojson.properties +++ /dev/null @@ -1,30 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -persistence.indexesXML=classpath:ojson/indexes.xml -persistence.viewsXML=classpath:ojson/views.xml - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=oracle.jdbc.OracleDriver -persistence.domain[0].jdbcURL=jdbc:oracle:thin:@${DB_CONTAINER_IP}:1521/XEPDB1 -persistence.domain[0].schema=SYNCOPE -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=syncope -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.OracleDictionary -persistence.domain[0].orm=META-INF/spring-orm-ojson.xml -persistence.domain[0].poolMaxActive=20 -persistence.domain[0].poolMinIdle=5 diff --git a/fit/core-reference/src/main/resources/core-oracle.properties b/fit/core-reference/src/main/resources/core-oracle.properties index 3b2a2d04f76..d341779e1a9 100644 --- a/fit/core-reference/src/main/resources/core-oracle.properties +++ b/fit/core-reference/src/main/resources/core-oracle.properties @@ -15,15 +15,29 @@ # specific language governing permissions and limitations # under the License. +persistence.indexesXML=classpath:META-INF/oracle/indexes.xml +persistence.viewsXML=classpath:META-INF/oracle/views.xml + persistence.domain[0].key=Master persistence.domain[0].jdbcDriver=oracle.jdbc.OracleDriver -persistence.domain[0].jdbcURL=jdbc:oracle:thin:@${DB_CONTAINER_IP}:1521/XEPDB1 -persistence.domain[0].schema=SYNCOPE +persistence.domain[0].jdbcURL=jdbc:oracle:thin:@${DB_CONTAINER_IP}:1521/FREEPDB1 +persistence.domain[0].dbSchema=SYNCOPE persistence.domain[0].dbUsername=syncope persistence.domain[0].dbPassword=syncope persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.OracleDictionary -persistence.domain[0].orm=META-INF/spring-orm-oracle.xml +persistence.domain[0].orm=META-INF/oracle/spring-orm.xml persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 -persistence.indexesXML=classpath:oracle_indexes.xml +persistence.domain[1].key=Two +persistence.domain[1].jdbcDriver=oracle.jdbc.OracleDriver +persistence.domain[1].jdbcURL=jdbc:oracle:thin:@${DB_CONTAINER_IP}:1521/FREEPDB1 +persistence.domain[1].dbSchema=SYNCOPETWO +persistence.domain[1].dbUsername=syncopetwo +persistence.domain[1].dbPassword=syncopetwo +persistence.domain[1].databasePlatform=org.apache.openjpa.jdbc.sql.OracleDictionary +persistence.domain[1].orm=META-INF/oracle/spring-orm.xml +persistence.domain[1].poolMaxActive=20 +persistence.domain[1].poolMinIdle=5 +persistence.domain[1].adminPassword=2AA60A8FF7FCD473D321E0146AFD9E26DF395147 +persistence.domain[1].adminCipherAlgorithm=SHA diff --git a/fit/core-reference/src/main/resources/core-pgjsonb.properties b/fit/core-reference/src/main/resources/core-pgjsonb.properties deleted file mode 100644 index 7ed206cbbe2..00000000000 --- a/fit/core-reference/src/main/resources/core-pgjsonb.properties +++ /dev/null @@ -1,29 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -persistence.indexesXML=classpath:pgjsonb/indexes.xml -persistence.viewsXML=classpath:pgjsonb/views.xml - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=org.postgresql.Driver -persistence.domain[0].jdbcURL=jdbc:postgresql://${DB_CONTAINER_IP}:5432/syncope?stringtype=unspecified -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=syncope -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDictionary -persistence.domain[0].orm=META-INF/spring-orm-pgjsonb.xml -persistence.domain[0].poolMaxActive=20 -persistence.domain[0].poolMinIdle=5 diff --git a/fit/core-reference/src/main/resources/core-postgres.properties b/fit/core-reference/src/main/resources/core-postgres.properties deleted file mode 100644 index 08845c110c3..00000000000 --- a/fit/core-reference/src/main/resources/core-postgres.properties +++ /dev/null @@ -1,25 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=org.postgresql.Driver -persistence.domain[0].jdbcURL=jdbc:postgresql://${DB_CONTAINER_IP}:5432/syncope?stringtype=unspecified -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=syncope -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDictionary -persistence.domain[0].poolMaxActive=20 -persistence.domain[0].poolMinIdle=5 diff --git a/fit/core-reference/src/main/resources/core-sqlserver.properties b/fit/core-reference/src/main/resources/core-sqlserver.properties deleted file mode 100644 index 522472d441b..00000000000 --- a/fit/core-reference/src/main/resources/core-sqlserver.properties +++ /dev/null @@ -1,29 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=com.microsoft.sqlserver.jdbc.SQLServerDriver -persistence.domain[0].jdbcURL=jdbc:sqlserver://${DB_CONTAINER_IP}:1433;databaseName=syncope -persistence.domain[0].schema=dbo -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=Syncope123 -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.SQLServerDictionary -persistence.domain[0].orm=META-INF/spring-orm-sqlserver.xml -persistence.domain[0].poolMaxActive=20 -persistence.domain[0].poolMinIdle=5 - -persistence.viewsXML=classpath:sqlserver_views.xml diff --git a/fit/core-reference/src/main/resources/core-wildfly.properties b/fit/core-reference/src/main/resources/core-wildfly.properties index 454c92984c2..25a0d7d7aa4 100644 --- a/fit/core-reference/src/main/resources/core-wildfly.properties +++ b/fit/core-reference/src/main/resources/core-wildfly.properties @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -persistence.metaDataFactory=jpa(URLs=vfs:${project.build.directory}/cargo/configurations/wildfly31x/deployments/syncope.war/WEB-INF/lib/syncope-core-persistence-jpa-${syncope.version}.jar; vfs:${project.build.directory}/cargo/configurations/wildfly31x/deployments/syncope.war/WEB-INF/lib/syncope-core-self-keymaster-starter-${syncope.version}.jar, Resources=##orm##) +persistence.metaDataFactory=jpa(URLs=vfs:${project.build.directory}/cargo/configurations/wildfly32x/deployments/syncope.war/WEB-INF/lib/syncope-core-persistence-jpa-${syncope.version}.jar; vfs:${project.build.directory}/cargo/configurations/wildfly32x/deployments/syncope.war/WEB-INF/lib/syncope-core-self-keymaster-starter-${syncope.version}.jar, Resources=##orm##) javadocPaths=/WEB-INF/lib/syncope-common-idrepo-rest-api-${syncope.version}-javadoc.jar,\ /WEB-INF/lib/syncope-common-idm-rest-api-${syncope.version}-javadoc.jar,\ diff --git a/fit/core-reference/src/main/resources/log4j2.xml b/fit/core-reference/src/main/resources/log4j2.xml index 37ab4dd580d..3694e4dddf1 100644 --- a/fit/core-reference/src/main/resources/log4j2.xml +++ b/fit/core-reference/src/main/resources/log4j2.xml @@ -67,7 +67,7 @@ under the License. - + diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/KeymasterITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/KeymasterITCase.java index 9a3e368d40b..7a6de1efeaf 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/KeymasterITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/KeymasterITCase.java @@ -216,22 +216,27 @@ public void domainCRUD() throws Exception { assumeTrue(initial.stream().anyMatch(domain -> "Two".equals(domain.getKey()))); assumeTrue(initial.get(0) instanceof JPADomain); + JPADomain two = (JPADomain) initial.get(0); + String newdb = "syncopetest"; + // 1. create new domain String newDomain = UUID.randomUUID().toString(); domainOps.create(new JPADomain.Builder(newDomain). - jdbcDriver("org.h2.Driver"). - jdbcURL("jdbc:h2:mem:syncopetest" + newDomain + ";DB_CLOSE_DELAY=-1"). - dbUsername("sa"). - dbPassword(""). - databasePlatform("org.apache.openjpa.jdbc.sql.H2Dictionary"). - transactionIsolation(JPADomain.TransactionIsolation.TRANSACTION_READ_UNCOMMITTED). + jdbcDriver(two.getJdbcDriver()). + jdbcURL(two.getJdbcURL().replace("/syncopetwo", "/" + newdb)). + dbSchema("SYNCOPETWO".equals(two.getDbSchema()) ? newdb.toUpperCase() : null). + dbUsername(newdb). + dbPassword(newdb). + databasePlatform(two.getDatabasePlatform()). + orm(two.getOrm()). + transactionIsolation(two.getTransactionIsolation()). adminPassword(Encryptor.getInstance().encode("password", CipherAlgorithm.BCRYPT)). adminCipherAlgorithm(CipherAlgorithm.BCRYPT). build()); JPADomain domain = (JPADomain) domainOps.read(newDomain); - assertEquals(JPADomain.TransactionIsolation.TRANSACTION_READ_UNCOMMITTED, domain.getTransactionIsolation()); + assertEquals(two.getTransactionIsolation(), domain.getTransactionIsolation()); assertEquals(CipherAlgorithm.BCRYPT, domain.getAdminCipherAlgorithm()); assertEquals(10, domain.getPoolMaxActive()); assertEquals(2, domain.getPoolMinIdle()); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java index e92a7783e17..7b524478455 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/MembershipITCase.java @@ -89,25 +89,25 @@ public void misc() throws JsonProcessingException { } // remove fullname and try again - membership.getPlainAttrs().remove(membership.getPlainAttr("fullname").get()); + membership.getPlainAttrs().remove(membership.getPlainAttr("fullname").orElseThrow()); UserTO userTO = null; try { userTO = createUser(userCR).getEntity(); // 1. verify that 'aLong' is correctly populated for user - assertEquals(1, userTO.getPlainAttr("aLong").get().getValues().size()); - assertEquals("1976", userTO.getPlainAttr("aLong").get().getValues().get(0)); + assertEquals(1, userTO.getPlainAttr("aLong").orElseThrow().getValues().size()); + assertEquals("1976", userTO.getPlainAttr("aLong").orElseThrow().getValues().get(0)); // 2. verify that 'aLong' is correctly populated for user's membership assertEquals(1, userCR.getMemberships().size()); - membership = userTO.getMembership("034740a9-fa10-453b-af37-dc7897e98fb1").get(); + membership = userTO.getMembership("034740a9-fa10-453b-af37-dc7897e98fb1").orElseThrow(); assertNotNull(membership); - assertEquals(1, membership.getPlainAttr("aLong").get().getValues().size()); - assertEquals("1977", membership.getPlainAttr("aLong").get().getValues().get(0)); + assertEquals(1, membership.getPlainAttr("aLong").orElseThrow().getValues().size()); + assertEquals("1977", membership.getPlainAttr("aLong").orElseThrow().getValues().get(0)); // 3. verify that derived attrbutes from 'csv' and 'other' are also populated for user's membership - assertFalse(membership.getDerAttr("csvuserid").get().getValues().isEmpty()); - assertFalse(membership.getDerAttr("noschema").get().getValues().isEmpty()); + assertFalse(membership.getDerAttr("csvuserid").orElseThrow().getValues().isEmpty()); + assertFalse(membership.getDerAttr("noschema").orElseThrow().getValues().isEmpty()); // update user - change some values and add new membership attribute UserUR userUR = new UserUR(); @@ -124,19 +124,19 @@ public void misc() throws JsonProcessingException { userTO = updateUser(userUR).getEntity(); // 4. verify that 'aLong' is correctly populated for user - assertEquals(1, userTO.getPlainAttr("aLong").get().getValues().size()); - assertEquals("1977", userTO.getPlainAttr("aLong").get().getValues().get(0)); + assertEquals(1, userTO.getPlainAttr("aLong").orElseThrow().getValues().size()); + assertEquals("1977", userTO.getPlainAttr("aLong").orElseThrow().getValues().get(0)); assertFalse(userTO.getPlainAttr("ctype").isPresent()); // 5. verify that 'aLong' is correctly populated for user's membership assertEquals(1, userCR.getMemberships().size()); - membership = userTO.getMembership("034740a9-fa10-453b-af37-dc7897e98fb1").get(); + membership = userTO.getMembership("034740a9-fa10-453b-af37-dc7897e98fb1").orElseThrow(); assertNotNull(membership); - assertEquals(1, membership.getPlainAttr("aLong").get().getValues().size()); - assertEquals("1976", membership.getPlainAttr("aLong").get().getValues().get(0)); + assertEquals(1, membership.getPlainAttr("aLong").orElseThrow().getValues().size()); + assertEquals("1976", membership.getPlainAttr("aLong").orElseThrow().getValues().get(0)); // 6. verify that 'ctype' is correctly populated for user's membership - assertEquals("membership type", membership.getPlainAttr("ctype").get().getValues().get(0)); + assertEquals("membership type", membership.getPlainAttr("ctype").orElseThrow().getValues().get(0)); // finally remove membership userUR = new UserUR(); @@ -196,14 +196,14 @@ public void onGroupDelete() { // verify that 'aLong' is correctly populated for user's membership assertEquals(1, user.getMemberships().size()); - membership = user.getMembership(groupTO.getKey()).get(); + membership = user.getMembership(groupTO.getKey()).orElseThrow(); assertNotNull(membership); - assertEquals(1, membership.getPlainAttr("aLong").get().getValues().size()); - assertEquals("1454", membership.getPlainAttr("aLong").get().getValues().get(0)); + assertEquals(1, membership.getPlainAttr("aLong").orElseThrow().getValues().size()); + assertEquals("1454", membership.getPlainAttr("aLong").orElseThrow().getValues().get(0)); // verify that derived attrbutes from 'csv' and 'other' are also populated for user's membership - assertFalse(membership.getDerAttr("csvuserid").get().getValues().isEmpty()); - assertFalse(membership.getDerAttr("noschema").get().getValues().isEmpty()); + assertFalse(membership.getDerAttr("csvuserid").orElseThrow().getValues().isEmpty()); + assertFalse(membership.getDerAttr("noschema").orElseThrow().getValues().isEmpty()); // now remove the group -> all related memberships should have been removed as well GROUP_SERVICE.delete(groupTO.getKey()); @@ -219,15 +219,15 @@ public void pull() { ResourceTO newResource = RESOURCE_SERVICE.read(RESOURCE_NAME_DBPULL); newResource.setKey(getUUIDString()); - Item item = newResource.getProvision("USER").get().getMapping().getItems().stream(). - filter(object -> "firstname".equals(object.getIntAttrName())).findFirst().get(); + Item item = newResource.getProvision("USER").orElseThrow().getMapping().getItems().stream(). + filter(object -> "firstname".equals(object.getIntAttrName())).findFirst().orElseThrow(); assertNotNull(item); assertEquals("ID", item.getExtAttrName()); item.setIntAttrName("memberships[additional].aLong"); item.setPurpose(MappingPurpose.BOTH); - item = newResource.getProvision("USER").get().getMapping().getItems().stream(). - filter(object -> "fullname".equals(object.getIntAttrName())).findFirst().get(); + item = newResource.getProvision("USER").orElseThrow().getMapping().getItems().stream(). + filter(object -> "fullname".equals(object.getIntAttrName())).findFirst().orElseThrow(); item.setPurpose(MappingPurpose.PULL); PullTaskTO newTask = null; @@ -294,7 +294,7 @@ public void pull() { assertEquals(1, users.getTotalCount()); assertEquals(1, users.getResult().get(0).getMemberships().size()); assertEquals("5432", users.getResult().get(0).getMemberships().get(0). - getPlainAttr("aLong").get().getValues().get(0)); + getPlainAttr("aLong").orElseThrow().getValues().get(0)); } catch (Exception e) { LOG.error("Unexpected error", e); fail(e::getMessage); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java index 360e3a94c37..ac1369061f3 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java @@ -288,7 +288,7 @@ public void fromCSV() throws Exception { IOUtils.copy(src, dst); } } catch (IOException e) { - fail(e::getMessage); + fail(e.getMessage(), e); } // ----------------------------- @@ -1445,7 +1445,7 @@ public void issueSYNCOPE313LDAP() throws Exception { self = CLIENT_FACTORY.create(user.getUsername(), oldCleanPassword).self(); assertNotNull(self); } catch (Exception e) { - fail(e::getMessage); + fail(e.getMessage(), e); } finally { // Delete PullTask + user + reset the connector if (pullTask != null && pullTask.getKey() != null) { @@ -1556,7 +1556,7 @@ public void issueSYNCOPE1062() { assertEquals(2, propagationTasks.getSize()); } catch (Exception e) { LOG.error("Unexpected during issueSYNCOPE1062()", e); - fail(e::getMessage); + fail(e.getMessage(), e); } finally { Optional.ofNullable(pullTask).ifPresent(t -> TASK_SERVICE.delete(TaskType.PULL, t.getKey())); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java index dbffadd5af6..6c7870945d0 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java @@ -796,6 +796,14 @@ public void issueSYNCOPE1419() { assertNotNull(rossini); assertEquals("2009-05-26", rossini.getPlainAttr("loginDate").orElseThrow().getValues().get(0)); + if (IS_EXT_SEARCH_ENABLED) { + try { + Thread.sleep(2000); + } catch (InterruptedException ex) { + // ignore + } + } + PagedResult total = USER_SERVICE.search( new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).page(1).size(1).build()); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java index dec27d4b5d1..ed4a977f156 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java @@ -707,22 +707,16 @@ public void issueSYNCOPE15() { // Users with group 0cbcabd2-4410-4b6b-8f05-a052b451d18f are defined in workflow as subject to approval userCR.getMemberships().add(new MembershipTO.Builder("0cbcabd2-4410-4b6b-8f05-a052b451d18f").build()); - // 1. create user with group 9 (and verify that no propagation occurred) - UserTO userTO = createUser(userCR).getEntity(); - assertNotNull(userTO); - assertNotEquals(0L, userTO.getKey()); - assertNotNull(userTO.getCreationDate()); - assertNotNull(userTO.getCreator()); - assertNotNull(userTO.getLastChangeDate()); - assertNotNull(userTO.getLastModifier()); - assertEquals(userTO.getCreationDate(), userTO.getLastChangeDate()); + // 1. create user with group 0cbcabd2-4410-4b6b-8f05-a052b451d18f (and verify that no propagation occurred) + ProvisioningResult userTO = createUser(userCR); + assertTrue(userTO.getPropagationStatuses().isEmpty()); // 2. request if there is any pending form for user just created forms = USER_REQUEST_SERVICE.listForms(new UserRequestQuery.Builder().build()); assertEquals(preForms + 1, forms.getTotalCount()); UserRequestForm form = USER_REQUEST_SERVICE.listForms( - new UserRequestQuery.Builder().user(userTO.getKey()).build()).getResult().get(0); + new UserRequestQuery.Builder().user(userTO.getEntity().getKey()).build()).getResult().get(0); assertNotNull(form); // 3. first claim by bellini .... @@ -745,7 +739,7 @@ public void issueSYNCOPE15() { assertEquals(preForms, USER_REQUEST_SERVICE.listForms(new UserRequestQuery.Builder().build()).getTotalCount()); assertTrue(USER_REQUEST_SERVICE.listForms( - new UserRequestQuery.Builder().user(userTO.getKey()).build()).getResult().isEmpty()); + new UserRequestQuery.Builder().user(userTO.getEntity().getKey()).build()).getResult().isEmpty()); // 7.check that no more forms are still to be processed forms = USER_REQUEST_SERVICE.listForms(new UserRequestQuery.Builder().build()); diff --git a/fit/core-reference/src/test/resources/1_oracle_init.sql b/fit/core-reference/src/test/resources/1_oracle_init.sql new file mode 100644 index 00000000000..1752bea317a --- /dev/null +++ b/fit/core-reference/src/test/resources/1_oracle_init.sql @@ -0,0 +1,23 @@ +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at + +-- http://www.apache.org/licenses/LICENSE-2.0 + +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. +ALTER SESSION SET CONTAINER=FREEPDB1; + +CREATE TABLESPACE syncopetwo DATAFILE 'syncopetwo.dat' SIZE 10M AUTOEXTEND ON; +CREATE USER syncopetwo IDENTIFIED BY syncopetwo DEFAULT TABLESPACE syncopetwo QUOTA UNLIMITED ON USERS; + +CREATE TABLESPACE syncopetest DATAFILE 'syncopetest.dat' SIZE 10M AUTOEXTEND ON; +CREATE USER syncopetest IDENTIFIED BY syncopetest DEFAULT TABLESPACE syncopetest QUOTA UNLIMITED ON USERS; diff --git a/fit/core-reference/src/test/resources/2_oracle_init.sql b/fit/core-reference/src/test/resources/2_oracle_init.sql new file mode 100644 index 00000000000..1c65b645723 --- /dev/null +++ b/fit/core-reference/src/test/resources/2_oracle_init.sql @@ -0,0 +1,25 @@ +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at + +-- http://www.apache.org/licenses/LICENSE-2.0 + +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. +ALTER SESSION SET CONTAINER=FREEPDB1; + +GRANT CREATE SESSION TO syncopetwo; +GRANT ALL PRIVILEGES TO syncopetwo; +GRANT UNLIMITED TABLESPACE TO syncopetwo; + +GRANT CREATE SESSION TO syncopetest; +GRANT ALL PRIVILEGES TO syncopetest; +GRANT UNLIMITED TABLESPACE TO syncopetest; diff --git a/fit/core-reference/src/test/resources/mysql_init.sql b/fit/core-reference/src/test/resources/mysql_init.sql new file mode 100644 index 00000000000..fa03f20020e --- /dev/null +++ b/fit/core-reference/src/test/resources/mysql_init.sql @@ -0,0 +1,23 @@ +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at + +-- http://www.apache.org/licenses/LICENSE-2.0 + +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. +CREATE DATABASE `syncopetwo`; +CREATE USER 'syncopetwo'@'%' IDENTIFIED BY 'syncopetwo'; +GRANT ALL ON syncopetwo.* TO 'syncopetwo'@'%'; + +CREATE DATABASE `syncopetest`; +CREATE USER 'syncopetest'@'%' IDENTIFIED BY 'syncopetest'; +GRANT ALL ON syncopetest.* TO 'syncopetest'@'%'; diff --git a/fit/enduser-reference/pom.xml b/fit/enduser-reference/pom.xml index 20fd961cd30..ae50c55e202 100644 --- a/fit/enduser-reference/pom.xml +++ b/fit/enduser-reference/pom.xml @@ -70,11 +70,6 @@ under the License. - - com.h2database - h2 - test - org.apache.syncope.fit syncope-fit-build-tools @@ -96,6 +91,11 @@ under the License. war test + + org.postgresql + postgresql + test + @@ -132,13 +132,11 @@ under the License. file:/dev/./urandom true - - true - com.h2database - h2 + org.postgresql + postgresql @@ -249,7 +247,6 @@ under the License. - hotswap diff --git a/fit/persistence-embedded/LICENSE b/fit/persistence-embedded/LICENSE new file mode 100644 index 00000000000..408c99bd5b3 --- /dev/null +++ b/fit/persistence-embedded/LICENSE @@ -0,0 +1,228 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +== + +For Embedded Postgres (https://github.com/zonkyio/embedded-postgres): +This is licensed under the AL 2.0, see above. + +== + +For Embedded Postgres Binaries (https://github.com/zonkyio/embedded-postgres-binaries): +This is licensed under the AL 2.0, see above. + +== + +For XZ Utils (https://tukaani.org/xz/): +This is licensed under the BSD Zero Clause License (0BSD): + +Permission to use, copy, modify, and/or distribute this software for +any purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE +FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN +AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/fit/persistence-embedded/NOTICE b/fit/persistence-embedded/NOTICE new file mode 100644 index 00000000000..5df93eaf0f7 --- /dev/null +++ b/fit/persistence-embedded/NOTICE @@ -0,0 +1,21 @@ +Apache Syncope +Copyright 2012-2023 The Apache Software Foundation + +This product includes software developed by: +The Apache Software Foundation (http://www.apache.org/). + +The following copyright notice(s) were affixed to portions of this code +with which this file is now or was at one time distributed. + +== + +This product includes software developed by the Embedded Postgres project. + +== + +This product includes software developed by the Embedded Postgres Binaries project. + +== + +This product includes software developed by the XZ Utils project. +Copyright (C) The XZ Utils authors and contributors. diff --git a/fit/persistence-embedded/pom.xml b/fit/persistence-embedded/pom.xml new file mode 100644 index 00000000000..5b4876e22fb --- /dev/null +++ b/fit/persistence-embedded/pom.xml @@ -0,0 +1,81 @@ + + + + + 4.0.0 + + + org.apache.syncope + syncope-fit + 4.0.0-SNAPSHOT + + + Apache Syncope FIT Persistence Embedded + Apache Syncope FIT Persistence Embedded + org.apache.syncope.fit + persistence-embedded + jar + + + none + + ${basedir}/../.. + + + + + org.springframework.boot + spring-boot-autoconfigure + provided + + + + io.zonky.test + embedded-postgres + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + + org.apache.maven.plugins + maven-assembly-plugin + + + src/main/resources/assembly.xml + + + + + package + + single + + + + + + + diff --git a/fit/persistence-embedded/src/main/java/org/apache/syncope/fit/persistence/embedded/EmbeddedPostgreSQLContext.java b/fit/persistence-embedded/src/main/java/org/apache/syncope/fit/persistence/embedded/EmbeddedPostgreSQLContext.java new file mode 100644 index 00000000000..aeb6891fc40 --- /dev/null +++ b/fit/persistence-embedded/src/main/java/org/apache/syncope/fit/persistence/embedded/EmbeddedPostgreSQLContext.java @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.fit.persistence.embedded; + +import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; +import java.io.IOException; +import java.net.Socket; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; +import java.util.Map; +import javax.sql.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Bean; +import org.springframework.core.env.Environment; +import org.springframework.jndi.JndiObjectFactoryBean; +import org.springframework.util.ReflectionUtils; + +public class EmbeddedPostgreSQLContext { + + private static final Logger LOG = LoggerFactory.getLogger(EmbeddedPostgreSQLContext.class); + + private static final String DEFAULT_POSTGRES_HOST = "localhost"; + + private static final int DEFAULT_POSTGRES_PORT = 5432; + + private static final String DEFAULT_POSTGRES_USER = "postgres"; + + private static final String DEFAULT_POSTGRES_PASSWORD = "root"; + + @Value("${embedded.databases:syncope}") + private String[] embeddedDatabases; + + private void initDatabases(final Connection conn) throws SQLException { + LOG.info("Creating embedded databases: {}", List.of(embeddedDatabases)); + + try { + for (String key : embeddedDatabases) { + try (Statement stmt = conn.createStatement()) { + ResultSet resultSet = stmt.executeQuery( + "SELECT COUNT(*) FROM pg_database WHERE datname = '" + key + "'"); + resultSet.next(); + if (resultSet.getInt(1) <= 0) { + stmt.execute("CREATE DATABASE " + key); + } else { + LOG.info("Database {} exists", key); + } + + resultSet = stmt.executeQuery("SELECT COUNT(*) FROM pg_user WHERE usename = '" + key + "'"); + resultSet.next(); + if (resultSet.getInt(1) <= 0) { + stmt.execute("CREATE USER " + key + " WITH PASSWORD '" + key + "'"); + stmt.execute("ALTER DATABASE " + key + " OWNER TO " + key); + } else { + LOG.info("User {} exists", key); + } + } catch (SQLException e) { + LOG.error("While creating database {}", key, e); + } + } + } finally { + if (conn != null) { + conn.close(); + } + } + } + + @ConditionalOnClass(name = "org.postgresql.Driver") + @Bean(name = "MasterDataSource") + public JndiObjectFactoryBean masterDataSource(final Environment env) throws SQLException { + String dbhost = env.getProperty("POSTGRES_HOST", DEFAULT_POSTGRES_HOST); + int dbport = env.getProperty("POSTGRES_PORT", int.class, DEFAULT_POSTGRES_PORT); + + Connection conn; + DataSource defaultMasterDS; + try (Socket s = new Socket(dbhost, dbport)) { + LOG.info("PostgreSQL instance found"); + + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection( + "jdbc:postgresql://" + dbhost + ":" + dbport + "/postgres", + env.getProperty("POSTGRES_USER", DEFAULT_POSTGRES_USER), + env.getProperty("POSTGRES_PASSWORD", DEFAULT_POSTGRES_PASSWORD)); + + initDatabases(conn); + + Class clazz = Class.forName("org.postgresql.ds.PGSimpleDataSource"); + defaultMasterDS = (DataSource) clazz.getConstructor().newInstance(); + ReflectionUtils.findMethod(clazz, "setUrl", String.class).invoke( + defaultMasterDS, + "jdbc:postgresql://" + dbhost + ":" + dbport + "/syncope?stringtype=unspecified"); + ReflectionUtils.findMethod(clazz, "setUser", String.class).invoke(defaultMasterDS, "syncope"); + ReflectionUtils.findMethod(clazz, "setPassword", String.class).invoke(defaultMasterDS, "syncope"); + } catch (IOException ioe) { + LOG.info("Starting embedded PostgreSQL"); + + try { + EmbeddedPostgres pg = EmbeddedPostgres.builder().setPort(dbport).start(); + conn = pg.getPostgresDatabase().getConnection(); + + initDatabases(conn); + + defaultMasterDS = pg.getDatabase("syncope", "syncope", Map.of("stringtype", "unspecified")); + } catch (IOException e) { + throw new IllegalStateException("Could not start embedded PostgreSQL", e); + } + } catch (Exception e) { + throw new IllegalStateException("Unexpected error while setting up embedded persistence", e); + } + + JndiObjectFactoryBean masterDataSource = new JndiObjectFactoryBean(); + masterDataSource.setJndiName("java:comp/env/jdbc/syncopeMasterDataSource"); + masterDataSource.setDefaultObject(defaultMasterDS); + return masterDataSource; + } +} diff --git a/core/persistence-jpa-json/src/test/resources/META-INF/spring.factories b/fit/persistence-embedded/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports similarity index 84% rename from core/persistence-jpa-json/src/test/resources/META-INF/spring.factories rename to fit/persistence-embedded/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 3131eed47d0..bf4b90779a7 100644 --- a/core/persistence-jpa-json/src/test/resources/META-INF/spring.factories +++ b/fit/persistence-embedded/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -14,6 +14,4 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. - -org.springframework.test.context.ContextCustomizerFactory=\ - org.apache.syncope.core.persistence.jpa.JPAJSONTestContextCustomizerFactory +org.apache.syncope.fit.persistence.embedded.EmbeddedPostgreSQLContext diff --git a/fit/persistence-embedded/src/main/resources/assembly.xml b/fit/persistence-embedded/src/main/resources/assembly.xml new file mode 100644 index 00000000000..da3bc144bbb --- /dev/null +++ b/fit/persistence-embedded/src/main/resources/assembly.xml @@ -0,0 +1,52 @@ + + + + + bundle + + + jar + + + false + + + + ${project.build.outputDirectory} + + + + + + + false + true + + org.apache.commons:commons-lang3 + commons-io:commons-io + commons-codec:commons-codec + org.slf4j:slf4j-api + + + + diff --git a/fit/pom.xml b/fit/pom.xml index 42029c1ff1d..7fd94f925db 100644 --- a/fit/pom.xml +++ b/fit/pom.xml @@ -78,6 +78,7 @@ under the License. build-tools + persistence-embedded core-reference console-reference enduser-reference diff --git a/fit/wa-reference/pom.xml b/fit/wa-reference/pom.xml index 2794dcd5921..a52f6a39ddf 100644 --- a/fit/wa-reference/pom.xml +++ b/fit/wa-reference/pom.xml @@ -130,6 +130,11 @@ under the License. war test + + org.postgresql + postgresql + test + org.jsoup jsoup @@ -217,15 +222,13 @@ under the License. file:/dev/./urandom true - true - ${basedir}/src/test/resources/keystore.jks password - com.h2database - h2 + org.postgresql + postgresql @@ -415,7 +418,6 @@ under the License. - hotswap diff --git a/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/OIDCC4UIITCase.java b/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/OIDCC4UIITCase.java index cd73d896485..6505af11725 100644 --- a/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/OIDCC4UIITCase.java +++ b/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/OIDCC4UIITCase.java @@ -261,6 +261,12 @@ protected void sso(final String baseURL, final String username, final String pas // 3. verify that user is now authenticated assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); assertTrue(EntityUtils.toString(response.getEntity()).contains(username)); + + // 4. logout + get = new HttpGet(CONSOLE_ADDRESS.equals(baseURL) + ? baseURL + "wicket/bookmarkable/org.apache.syncope.client.console.pages.Logout" + : baseURL + "wicket/bookmarkable/org.apache.syncope.client.enduser.pages.Logout"); + httpclient.execute(get, context); } @Override diff --git a/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/SAML2SP4UIITCase.java b/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/SAML2SP4UIITCase.java index f4fbfde9914..929824c8c4b 100644 --- a/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/SAML2SP4UIITCase.java +++ b/fit/wa-reference/src/test/java/org/apache/syncope/fit/ui/SAML2SP4UIITCase.java @@ -297,6 +297,12 @@ protected void sso(final String baseURL, final String username, final String pas assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); assertTrue(EntityUtils.toString(response.getEntity()).contains(username)); } + + // 4. logout + get = new HttpGet(CONSOLE_ADDRESS.equals(baseURL) + ? baseURL + "wicket/bookmarkable/org.apache.syncope.client.console.pages.Logout" + : baseURL + "wicket/bookmarkable/org.apache.syncope.client.enduser.pages.Logout"); + httpclient.execute(get, context); } @Override diff --git a/pom.xml b/pom.xml index 06d381d108d..ddabe089491 100644 --- a/pom.xml +++ b/pom.xml @@ -440,8 +440,6 @@ under the License. 7.1.0 4.0.4 - 2.3.232 - 2.2.23 5.17.14 @@ -469,6 +467,9 @@ under the License. 5.7.0 3.9.2 + 2.0.7 + 16.3.0 + o=isp uid=admin,ou=system secret @@ -498,16 +499,16 @@ under the License. 6.2024.9 4.1.1 - 16 + 16-alpine 9.0 11 + 23-slim-faststart 5.23.0 42.7.4 9.0.0 3.4.1 - 12.6.1.jre11 - 23.4.0.24.05 + 23.5.0.24.07 ${project.build.directory}/bundles @@ -1264,12 +1265,52 @@ under the License. 1.6.5 + + io.zonky.test + embedded-postgres + ${zonky.embedded-postgres.version} + + + org.postgresql + postgresql + + + + + io.zonky.test.postgres + embedded-postgres-binaries-bom + ${zonky.embedded-postgres-binaries.version} + pom + import + + org.jsoup jsoup 1.18.1 + + org.postgresql + postgresql + ${jdbc.postgresql.version} + + + com.mysql + mysql-connector-j + ${jdbc.mysql.version} + + + org.mariadb.jdbc + mariadb-java-client + ${jdbc.mariadb.version} + + + com.oracle.database.jdbc + ojdbc11 + ${jdbc.oracle.version} + + com.icegreen greenmail @@ -1319,7 +1360,7 @@ under the License. - sonatype + sonatype-nexus-snapshots https://oss.sonatype.org/content/repositories/snapshots false @@ -1349,27 +1390,7 @@ under the License. - sonatype - https://oss.sonatype.org/content/repositories/releases - - true - - - false - - - - apache.snapshots - https://repository.apache.org/snapshots - - false - - - true - - - - sonatype.snapshots + sonatype-nexus-snapshots https://oss.sonatype.org/content/repositories/snapshots false @@ -1394,6 +1415,7 @@ under the License. false true true + full -Xlint:unchecked -parameters @@ -2128,11 +2150,11 @@ under the License. ${docker.postgresql.version} ${docker.mysql.version} ${docker.mariadb.version} + ${docker.oracle.version} ${jdbc.postgresql.version} ${jdbc.mysql.version} ${jdbc.mariadb.version} ${jdbc.oracle.version} - ${jdbc.mssql.version} ${year} true font diff --git a/src/main/asciidoc/getting-started/obtain.adoc b/src/main/asciidoc/getting-started/obtain.adoc index ae0da7aaf9a..02db0248102 100644 --- a/src/main/asciidoc/getting-started/obtain.adoc +++ b/src/main/asciidoc/getting-started/obtain.adoc @@ -62,39 +62,6 @@ instructions. The set of provided components, including access URLs and credentials, is the same as reported for <>, with the exception of log files, available here under `$CATALINA_HOME/logs`. -[TIP] -.Internal Storage -==== -By default, the standalone distribution is configured to use an in-memory database instance. -This means that every time Tomcat is shut down all changes that have been made are lost. - -If you want instead to make your changes persistent, replace - -[source,java] -jdbc:h2:mem:syncopedb;DB_CLOSE_DELAY=-1 - -with - -[source,java] -jdbc:h2:~/syncopedb;DB_CLOSE_DELAY=-1 - -in `webapps/syncope/WEB-INF/classes/core-embedded.properties` for `persistence.domain[0].jdbcURL` property (`Master` -domain) and / or - -[source,java] -jdbc:h2:mem:syncopetwo;DB_CLOSE_DELAY=-1 - -with - -[source,java] -jdbc:h2:~/syncopetwo;DB_CLOSE_DELAY=-1 - -for `persistence.domain[1].jdbcURL` property (`Two` domain), from the Apache Tomcat directory. -This will create H2 database files in the home directory of the user running Apache Syncope. - -Please refer to the http://www.h2database.com/[H2 documentation^] for more options. -==== - === Docker https://www.docker.com/[Docker^] images ready to use, published to https://hub.docker.com[Docker Hub^]. @@ -272,7 +239,7 @@ containers. ---- services: keymaster: // <1> - image: zookeeper:3.7.0 + image: zookeeper:latest restart: always db: // <2> @@ -672,11 +639,8 @@ Credentials: `admin` / `password` | http://localhost:8080/ | Internal storage -| A SQL web interface is available at https://localhost:9443/syncope/h2 + - + - Choose configuration 'Generic H2 (Embedded)' + - Insert `jdbc:h2:mem:syncopedb` as JDBC URL + - Click 'Connect' button +| `jdbc:postgresql://localhost:5432/syncope?stringtype=unspecified` + +Credentials: `syncope` / `syncope` | External resource: LDAP | An embedded instance is available. + @@ -698,7 +662,7 @@ You can configure any LDAP client (such as http://jxplorer.org/[JXplorer^], for + Choose configuration 'Generic H2 (Server)' + Insert `jdbc:h2:tcp://localhost:9092/mem:testdb` as JDBC URL + - Set 'sa' as password + + Set `sa` as password + Click 'Connect' button |=== diff --git a/src/main/asciidoc/getting-started/systemRequirements.adoc b/src/main/asciidoc/getting-started/systemRequirements.adoc index 9ef15c23956..fb65618e547 100644 --- a/src/main/asciidoc/getting-started/systemRequirements.adoc +++ b/src/main/asciidoc/getting-started/systemRequirements.adoc @@ -25,12 +25,12 @@ The hardware requirements depend greatly on the given deployment, in particular managed entities (Users, Groups and Any Objects), their attributes and resources. * CPU: dual core, 2 GHz (minimum) - * RAM: 4 GB (minimum) + * RAM: 8 GB (minimum) * Disk: 200 MB (minimum) === Java -Apache Syncope {docVersion} requires the latest JDK 17 that is available. Works with JDK 20. +Apache Syncope {docVersion} requires the latest JDK 21 that is available. Works with later versions. === Java EE Container @@ -38,14 +38,13 @@ Apache Syncope {docVersion} is verified with the following Java EE containers: . https://tomcat.apache.org/download-10.cgi[Apache Tomcat 10^] . https://www.payara.fish/[Payara Server 6^] - . https://www.wildfly.org/[Wildfly 32^] + . https://www.wildfly.org/[Wildfly 33^] === Internal Storage Apache Syncope {docVersion} is verified with the recent versions of the following DBMSes, for internal storage: - . http://www.postgresql.org/[PostgreSQL^] (>= {postgresql}, JDBC driver >= {postgresqlJDBC}) + . https://www.postgresql.org/[PostgreSQL^] (>= {postgresql}, JDBC driver >= {postgresqlJDBC}) . https://mariadb.org/[MariaDB^] (>= {mariadb}, JDBC driver >= {mariadbJDBC}) - . http://www.mysql.com/[MySQL^] (>= {mysql}, JDBC driver >= {mysqlJDBC}) - . https://www.oracle.com/database/index.html[Oracle Database^] (>= 19c, JDBC driver >= ojdbc11 {oracleJDBC}) - . http://www.microsoft.com/en-us/server-cloud/products/sql-server/[MS SQL Server^] (>= 2017, JDBC driver >= {sqlserverJDBC}11) + . https://www.mysql.com/[MySQL^] (>= {mysql}, JDBC driver >= {mysqlJDBC}) + . https://www.oracle.com/database/index.html[Oracle Database^] (>= {oracle}, JDBC driver >= ojdbc11 {oracleJDBC}) diff --git a/src/main/asciidoc/reference-guide/concepts/externalresources.adoc b/src/main/asciidoc/reference-guide/concepts/externalresources.adoc index 6482ddb24fa..952193fcb84 100644 --- a/src/main/asciidoc/reference-guide/concepts/externalresources.adoc +++ b/src/main/asciidoc/reference-guide/concepts/externalresources.adoc @@ -39,6 +39,7 @@ Several Connector Bundles come included with Apache Syncope: * https://connid.atlassian.net/wiki/display/BASE/Database[Database^] * https://connid.atlassian.net/wiki/display/BASE/Google+Apps[Google Apps^] * https://connid.atlassian.net/wiki/display/BASE/LDAP[LDAP^] +* https://connid.atlassian.net/wiki/display/BASE/Okta[Okta^] * https://connid.atlassian.net/wiki/display/BASE/REST[Scripted REST^] * https://connid.atlassian.net/wiki/display/BASE/ServiceNow[ServiceNow^] * https://connid.atlassian.net/wiki/display/BASE/SCIM[SCIM^] diff --git a/src/main/asciidoc/reference-guide/configuration/dbms.adoc b/src/main/asciidoc/reference-guide/configuration/dbms.adoc index 9d7da3d1bf0..4e1099092f1 100644 --- a/src/main/asciidoc/reference-guide/configuration/dbms.adoc +++ b/src/main/asciidoc/reference-guide/configuration/dbms.adoc @@ -37,57 +37,9 @@ persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 .... -as `core/src/main/resources/core-postgres.properties`. +as `core/src/main/resources/core-postgresql.properties`. -Do not forget to include `postgres` as -https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.profiles.adding-active-profiles[Spring Boot profile^] -for the Core application. - -[WARNING] -This assumes that you have a PostgreSQL instance running on localhost, listening on its default port 5432 with a -database `syncope` fully accessible by user `syncope` with password `syncope`. - -==== PostgreSQL (JSONB) - -[NOTE] -With the configurations reported below, Apache Syncope will leverage the -https://www.postgresql.org/docs/current/datatype-json.html[JSONB^] column type for attribute storage. - -[NOTE] -Apache Syncope {docVersion} is verified with PostgreSQL server >= {postgresql} and JDBC driver >= {postgresqlJDBC}. - -Add the following dependency to `core/pom.xml`: - -[source,xml,subs="verbatim,attributes"] ----- - - org.apache.syncope.core - syncope-core-persistence-jpa-json - ${syncope.version} - ----- - -Create - -[source] -.... -persistence.indexesXML=classpath:pgjsonb/indexes.xml -persistence.viewsXML=classpath:pgjsonb/views.xml - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=org.postgresql.Driver -persistence.domain[0].jdbcURL=jdbc:postgresql://${DB_CONTAINER_IP}:5432/syncope?stringtype=unspecified -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=syncope -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDictionary -persistence.domain[0].orm=META-INF/spring-orm-pgjsonb.xml -persistence.domain[0].poolMaxActive=20 -persistence.domain[0].poolMinIdle=5 -.... - -as `core/src/main/resources/core-pgjsonb.properties`. - -Do not forget to include `pgjsonb` as +Do not forget to include `postgresql` as https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.profiles.adding-active-profiles[Spring Boot profile^] for the Core application. @@ -104,12 +56,16 @@ Create [source] .... +persistence.indexesXML=classpath:META-INF/mysql/indexes.xml +persistence.viewsXML=classpath:META-INF/mysql/views.xml + persistence.domain[0].key=Master persistence.domain[0].jdbcDriver=com.mysql.cj.jdbc.Driver persistence.domain[0].jdbcURL=jdbc:mysql://localhost:3306/syncope?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8 persistence.domain[0].dbUsername=syncope persistence.domain[0].dbPassword=syncope persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3,useSetStringForClobs=true) +persistence.domain[0].orm=META-INF/mysql/spring-orm.xml persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 .... @@ -127,60 +83,6 @@ It is important to set the collation to `utf8_general_ci` after creation of `syn This assumes that you have a MySQL instance running on localhost, listening on its default port 3306 with a database `syncope` fully accessible by user `syncope` with password `syncope`. -==== MySQL (JSON) - -[NOTE] -With the configurations reported below, Apache Syncope will leverage the -https://dev.mysql.com/doc/refman/9.0/en/json-table-functions.html[JSON_TABLE^] function. - -[NOTE] -Apache Syncope {docVersion} is verified with MySQL server >= {mysql} and JDBC driver >= {mysqlJDBC}. - -Add the following dependency to `core/pom.xml`: - -[source,xml,subs="verbatim,attributes"] ----- - - org.apache.syncope.core - syncope-core-persistence-jpa-json - ${syncope.version} - ----- - -Create - -[source] -.... -persistence.indexesXML=classpath:myjson/indexes.xml -persistence.viewsXML=classpath:myjson/views.xml - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=com.mysql.cj.jdbc.Driver -persistence.domain[0].jdbcURL=jdbc:mysql://localhost:3306/syncope?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8 -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=syncope -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3,useSetStringForClobs=true) -persistence.domain[0].orm=META-INF/spring-orm-myjson.xml -persistence.domain[0].poolMaxActive=20 -persistence.domain[0].poolMinIdle=5 -.... - -as `core/src/main/resources/core-myjson.properties`. - -Do not forget to include `myjson` as -https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.profiles.adding-active-profiles[Spring Boot profile^] -for the Core application. - -[WARNING] -This assumes that the InnoDB engine is enabled in your MySQL instance. - -[CAUTION] -It is important to set the collation to `utf8_general_ci` after creation of `syncope` database. - -[WARNING] -This assumes that you have a MySQL instance running on localhost, listening on its default port 3306 with a database -`syncope` fully accessible by user `syncope` with password `syncope`. - ==== MariaDB [NOTE] @@ -190,12 +92,17 @@ Create [source] .... +persistence.indexesXML=classpath:META-INF/mariadb/indexes.xml +persistence.viewsXML=classpath:META-INF/mariadb/views.xml + persistence.domain[0].key=Master persistence.domain[0].jdbcDriver=org.mariadb.jdbc.Driver persistence.domain[0].jdbcURL=jdbc:mariadb://localhost:3306/syncope?characterEncoding=UTF-8 -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=syncope +# keep the next two lines until https://jira.mariadb.org/browse/MDEV-27898 is fixed +persistence.domain[0].dbUsername=root +persistence.domain[0].dbPassword=password persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MariaDBDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3,useSetStringForClobs=true) +persistence.domain[0].orm=META-INF/mariadb/spring-orm.xml persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 .... @@ -222,93 +129,31 @@ https://mariadb.com/kb/en/configuring-mariadb-with-option-files/[option file^]. [WARNING] This assumes that you have a MariaDB instance running on localhost, listening on its default port 3306 with a database -`syncope` fully accessible by user `syncope` with password `syncope`. - -==== MariaDB (JSON) - -[NOTE] -With the configurations reported below, Apache Syncope will leverage the -https://mariadb.com/kb/en/json_table/[JSON_TABLE^] function. - -[NOTE] -Apache Syncope {docVersion} is verified with MariaDB server >= {mariadb} and JDBC driver >= {mariadbJDBC}. - -Add the following dependency to `core/pom.xml`: - -[source,xml,subs="verbatim,attributes"] ----- - - org.apache.syncope.core - syncope-core-persistence-jpa-json - ${syncope.version} - ----- - -Create - -[source] -.... -persistence.indexesXML=classpath:majson/indexes.xml -persistence.viewsXML=classpath:majson/views.xml -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=org.mariadb.jdbc.Driver -persistence.domain[0].jdbcURL=jdbc:mariadb://localhost:3306/syncope?characterEncoding=UTF-8 -persistence.domain[0].dbUsername=root -persistence.domain[0].dbPassword=password -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MariaDBDictionary(blobTypeName=LONGBLOB,dateFractionDigits=3) -persistence.domain[0].orm=META-INF/spring-orm-majson.xml -persistence.domain[0].poolMaxActive=10 -persistence.domain[0].poolMinIdle=2 -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_mariadb.sql -.... - -as `core/src/main/resources/core-majson.properties`. - -Do not forget to include `majson` as -https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.profiles.adding-active-profiles[Spring Boot profile^] -for the Core application. - -[CAUTION] -It is important to set the collation to `utf8_general_ci` after creation of `syncope` database. - -[WARNING] -==== -It is necessary to use `utf8mb4_unicode_ci` instead of `utf8mb4_general_ci` if case-sensitive queries are required. -In this case, set -.... -init_connect = "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci" -.... -under either the `[mysqld]` section or the `[mariadb]` section of your -https://mariadb.com/kb/en/configuring-mariadb-with-option-files/[option file^]. -==== - -[WARNING] -This assumes that you have a MariaDB instance running on localhost, listening on its default port 3306 with a database -`syncope` and super-admin user `root` with password `password`. +`syncope` and super-admin user `root` with password `password`. + Super-admin user is required until https://jira.mariadb.org/browse/MDEV-27898[this bug^] is fixed. ==== Oracle Database [NOTE] -Apache Syncope {docVersion} is verified with Oracle database >= 19c and JDBC driver >= ojdbc11 {oracleJDBC}. +Apache Syncope {docVersion} is verified with Oracle database >= {oracle} and JDBC driver >= ojdbc11 {oracleJDBC}. Create [source] .... +persistence.indexesXML=classpath:META-INF/oracle/indexes.xml +persistence.viewsXML=classpath:META-INF/oracle/views.xml + persistence.domain[0].key=Master persistence.domain[0].jdbcDriver=oracle.jdbc.OracleDriver -persistence.domain[0].jdbcURL=jdbc:oracle:thin:@localhost:1521:XE -persistence.domain[0].schema=SYNCOPE +persistence.domain[0].jdbcURL=jdbc:oracle:thin:@localhost}:1521/FREEPDB1 +persistence.domain[0].dbSchema=SYNCOPE persistence.domain[0].dbUsername=syncope persistence.domain[0].dbPassword=syncope persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.OracleDictionary -persistence.domain[0].orm=META-INF/spring-orm-oracle.xml +persistence.domain[0].orm=META-INF/oracle/spring-orm.xml persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -persistence.indexesXML=classpath:oracle_indexes.xml .... as `core/src/main/resources/core-oracle.properties`. @@ -320,85 +165,3 @@ for the Core application. [WARNING] This assumes that you have an Oracle instance running on localhost, listening on its default port 1521 with a database `syncope` under tablespace `SYNCOPE`, fully accessible by user `syncope` with password `syncope`. - -==== Oracle Database (JSON) - -[NOTE] -With the configurations reported below, Apache Syncope will leverage the -https://docs.oracle.com/en/database/oracle/oracle-database/19/adjsn/[JSON^] features. - -[NOTE] -Apache Syncope {docVersion} is verified with Oracle database >= 19c and JDBC driver >= ojdbc11 {oracleJDBC}. - -Add the following dependency to `core/pom.xml`: - -[source,xml,subs="verbatim,attributes"] ----- - - org.apache.syncope.core - syncope-core-persistence-jpa-json - ${syncope.version} - ----- - -Create - -[source] -.... -persistence.indexesXML=classpath:ojson/indexes.xml -persistence.viewsXML=classpath:ojson/views.xml - -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=oracle.jdbc.OracleDriver -persistence.domain[0].jdbcURL=jdbc:postgresql://${DB_CONTAINER_IP}:5432/syncope?stringtype=unspecified -persistence.domain[0].schema=SYNCOPE -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=syncope -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.OracleDictionary -persistence.domain[0].orm=META-INF/spring-orm-ojson.xml -persistence.domain[0].poolMaxActive=20 -persistence.domain[0].poolMinIdle=5 -.... - -as `core/src/main/resources/core-ojson.properties`. - -Do not forget to include `ojson` as -https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.profiles.adding-active-profiles[Spring Boot profile^] -for the Core application. - -[WARNING] -This assumes that you have an Oracle instance running on localhost, listening on its default port 1521 with a database -`syncope` under tablespace `SYNCOPE`, fully accessible by user `syncope` with password `syncope`. - -==== MS SQL Server - -[NOTE] -Apache Syncope {docVersion} is verified with MS SQL server >= 2017 and JDBC driver >= {sqlserverJDBC}11. - -Create - -[source] -.... -persistence.domain[0].key=Master -persistence.domain[0].jdbcDriver=com.microsoft.sqlserver.jdbc.SQLServerDriver -persistence.domain[0].jdbcURL=jdbc:sqlserver://localhost:1433;databaseName=syncope -persistence.domain[0].schema=dbo -persistence.domain[0].dbUsername=syncope -persistence.domain[0].dbPassword=Syncope123 -persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.SQLServerDictionary -persistence.domain[0].orm=META-INF/spring-orm-sqlserver.xml -persistence.domain[0].poolMaxActive=20 -persistence.domain[0].poolMinIdle=5 - -persistence.viewsXML=classpath:sqlserver_views.xml -.... - -as `core/src/main/resources/core-sqlserver.properties`. - -Do not forget to include `sqlserver` as -https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.profiles.adding-active-profiles[Spring Boot profile^] -for the Core application. - -[WARNING] -This assumes that you have a MS SQL Server instance running on localhost, listening on its default port 1433 with a -database `syncope` fully accessible by user `syncope` with password `syncope`. diff --git a/src/main/asciidoc/reference-guide/configuration/deployment.adoc b/src/main/asciidoc/reference-guide/configuration/deployment.adoc index 20937072af3..8a2bc6e41ce 100644 --- a/src/main/asciidoc/reference-guide/configuration/deployment.adoc +++ b/src/main/asciidoc/reference-guide/configuration/deployment.adoc @@ -103,7 +103,7 @@ for the Master domain. Each JavaEE Container provides its own way to accomplish this task: * https://tomcat.apache.org/tomcat-10.0-doc/jdbc-pool.html[Apache Tomcat 10^] * https://docs.payara.fish/community/docs/Technical%20Documentation/Payara%20Server%20Documentation/Server%20Configuration%20And%20Management/JDBC%20Resource%20Management/JDBC.html[Payara Server 6^] - * https://docs.wildfly.org/32/Admin_Guide.html#DataSource[Wildfly 32^] + * https://docs.wildfly.org/33/Admin_Guide.html#DataSource[Wildfly 33^] **** ==== Apache Tomcat 10 @@ -200,7 +200,7 @@ For better performance under GNU / Linux, do not forget to include the system pr .... ==== -==== Wildfly 32 +==== Wildfly 33 Add diff --git a/src/main/asciidoc/reference-guide/howto/importexport.adoc b/src/main/asciidoc/reference-guide/howto/importexport.adoc index 95d863cb8bd..bdcf8e1bc48 100644 --- a/src/main/asciidoc/reference-guide/howto/importexport.adoc +++ b/src/main/asciidoc/reference-guide/howto/importexport.adoc @@ -24,13 +24,13 @@ schemas, connectors, resources, mapping, roles, groups, tasks and other paramete During the implementation phase of an Apache Syncope-based project, it might be useful to move such configuration back and forth from one Apache Syncope instance to another (say developer's laptop and production server). + One option is clearly to act at a low level by empowering DBMS' dump & restore capabilities, but what if the developer -is running MySQL (or even in-memory H2) while the sysadmin features Oracle? +is running MySQL while the sysadmin features Oracle? [CAUTION] .Wipe existing content ===== -When not running in-memory H2, the internal storage's data must be wiped before starting Apache Syncope, otherwise -the provided content will be just ignored. +The internal storage's data must be wiped before starting Apache Syncope, otherwise the provided content will be just +ignored. Check `core-persistence.log` for message diff --git a/src/main/asciidoc/reference-guide/usage/customization.adoc b/src/main/asciidoc/reference-guide/usage/customization.adoc index 4cdabb379a3..0257dd29c01 100644 --- a/src/main/asciidoc/reference-guide/usage/customization.adoc +++ b/src/main/asciidoc/reference-guide/usage/customization.adoc @@ -292,12 +292,6 @@ endif::[] ifeval::["{snapshotOrRelease}" == "snapshot"] * https://github.com/apache/syncope/blob/master/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/MasterDomain.java[MasterDomain^] endif::[] -ifeval::["{snapshotOrRelease}" == "release"] -* https://github.com/apache/syncope/blob/syncope-{docVersion}/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/DomainConfFactory.java[DomainConfFactory^] -endif::[] -ifeval::["{snapshotOrRelease}" == "snapshot"] -* https://github.com/apache/syncope/blob/master/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/DomainConfFactory.java[DomainConfFactory^] -endif::[] The `@Bean` declarations from these classes can be customized as explained <>. diff --git a/src/site/xdoc/building.xml b/src/site/xdoc/building.xml index 638ebf2f197..637bdb10605 100644 --- a/src/site/xdoc/building.xml +++ b/src/site/xdoc/building.xml @@ -180,10 +180,6 @@ under the License. Perform the full test suite against a real Oracle database via $ mvn -Poracle-it or $ mvn -Pojson-it (for JSON support) -
MS SQL Server
- Prform the full test suite against a real MS SQL Server database via - $ mvn -Psqlserver-it -
Neo4j
Prform the full test suite against a real Neo4j instance via $ mvn -Pneo4j-it diff --git a/standalone/pom.xml b/standalone/pom.xml index 1d1702844f6..a6df0832c89 100644 --- a/standalone/pom.xml +++ b/standalone/pom.xml @@ -42,6 +42,11 @@ under the License. + + org.postgresql + postgresql + test + org.apache.syncope.fit syncope-fit-build-tools @@ -139,7 +144,7 @@ under the License. - + diff --git a/standalone/src/main/resources/setenv.bat b/standalone/src/main/resources/setenv.bat index 14fd4c56bdd..e58be0879e9 100644 --- a/standalone/src/main/resources/setenv.bat +++ b/standalone/src/main/resources/setenv.bat @@ -14,4 +14,4 @@ rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. rem See the License for the specific language governing permissions and rem limitations under the License. -set JAVA_OPTS=-Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djavax.net.ssl.trustStore=%CATALINA_HOME%\conf\keystore.jks -Dsyncope.connid.location=connid://${testconnectorserver.key}@localhost:${testconnectorserver.port} -Dsyncope.conf.dir=%CATALINA_HOME%\webapps\syncope\WEB-INF\classes -Dsyncope.log.dir=%CATALINA_HOME%\logs -Dspring.profiles.active=embedded,all -server -Xms2048m -Xmx2048m -XX:NewSize=256m -XX:MaxNewSize=256m -DCATALINA_HOME=%CATALINA_HOME% -Dh2.returnOffsetDateTime=true +set JAVA_OPTS=-Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djavax.net.ssl.trustStore=%CATALINA_HOME%\conf\keystore.jks -Dsyncope.connid.location=connid://${testconnectorserver.key}@localhost:${testconnectorserver.port} -Dsyncope.conf.dir=%CATALINA_HOME%\webapps\syncope\WEB-INF\classes -Dsyncope.log.dir=%CATALINA_HOME%\logs -Dspring.profiles.active=embedded,all -server -Xms2048m -Xmx2048m -XX:NewSize=256m -XX:MaxNewSize=256m -DCATALINA_HOME=%CATALINA_HOME% diff --git a/standalone/src/main/resources/setenv.sh b/standalone/src/main/resources/setenv.sh index c5b642f8fb6..fe44497a265 100755 --- a/standalone/src/main/resources/setenv.sh +++ b/standalone/src/main/resources/setenv.sh @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djavax.net.ssl.trustStore=$CATALINA_HOME/conf/keystore.jks -Djavax.net.ssl.trustStorePassword=password -Dsyncope.conf.dir=$CATALINA_HOME/webapps/syncope/WEB-INF/classes -Dsyncope.connid.location=connid://${testconnectorserver.key}@localhost:${testconnectorserver.port} -Dsyncope.log.dir=$CATALINA_HOME/logs -Dspring.profiles.active=embedded,all -server -Xms2048m -Xmx2048m -XX:NewSize=256m -XX:MaxNewSize=256m -DCATALINA_HOME=$CATALINA_HOME -Dh2.returnOffsetDateTime=true" +JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djavax.net.ssl.trustStore=$CATALINA_HOME/conf/keystore.jks -Djavax.net.ssl.trustStorePassword=password -Dsyncope.conf.dir=$CATALINA_HOME/webapps/syncope/WEB-INF/classes -Dsyncope.connid.location=connid://${testconnectorserver.key}@localhost:${testconnectorserver.port} -Dsyncope.log.dir=$CATALINA_HOME/logs -Dspring.profiles.active=embedded,all -server -Xms2048m -Xmx2048m -XX:NewSize=256m -XX:MaxNewSize=256m -DCATALINA_HOME=$CATALINA_HOME"