You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2018/04/26 12:13:13 UTC
[2/2] syncope git commit: [SYNCOPE-1307] Forcing tree visit for
Realms to ensure correct order
[SYNCOPE-1307] Forcing tree visit for Realms to ensure correct order
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/761399c4
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/761399c4
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/761399c4
Branch: refs/heads/master
Commit: 761399c46b69b5e27e5ff0e47a7ed5ddb6489f3b
Parents: c0e2aed
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Apr 26 14:06:28 2018 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Apr 26 14:13:06 2018 +0200
----------------------------------------------------------------------
.../jpa/content/MultiParentNode.java | 3 +-
.../jpa/content/XMLContentExporter.java | 95 ++++++++++----------
.../jpa/outer/XMLContentExporterTest.java | 11 ++-
3 files changed, 55 insertions(+), 54 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/761399c4/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNode.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNode.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNode.java
index 57f83d1..232e22a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNode.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNode.java
@@ -27,7 +27,7 @@ class MultiParentNode<T> {
private final T object;
- private Set<MultiParentNode<T>> children;
+ private final Set<MultiParentNode<T>> children = new HashSet<>();
private int level;
@@ -35,7 +35,6 @@ class MultiParentNode<T> {
MultiParentNode(final T object) {
this.object = object;
- children = new HashSet<>();
}
public int getLevel() {
http://git-wip-us.apache.org/repos/asf/syncope/blob/761399c4/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
index 4909ed3..44f1411 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/XMLContentExporter.java
@@ -35,6 +35,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -55,7 +56,9 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.content.ContentExporter;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.jpa.entity.JPAAccessToken;
+import org.apache.syncope.core.persistence.jpa.entity.JPARealm;
import org.apache.syncope.core.persistence.jpa.entity.JPAReportExec;
import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership;
import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttr;
@@ -70,6 +73,7 @@ import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueVa
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.stereotype.Component;
import org.xml.sax.SAXException;
@@ -95,6 +99,9 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
protected static final Map<String, Set<String>> COLUMNS_TO_BE_NULLIFIED =
Collections.singletonMap("SYNCOPEGROUP", Collections.singleton("USEROWNER_ID"));
+ @Autowired
+ private RealmDAO realmDAO;
+
private boolean isTableAllowed(final String tableName) {
return TABLE_PREFIXES_TO_BE_EXCLUDED.stream().
allMatch(prefix -> !tableName.toUpperCase().startsWith(prefix.toUpperCase()));
@@ -105,10 +112,10 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
Set<MultiParentNode<String>> roots = new HashSet<>();
- final DatabaseMetaData meta = conn.getMetaData();
+ DatabaseMetaData meta = conn.getMetaData();
- final Map<String, MultiParentNode<String>> exploited = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
- final Set<String> pkTableNames = new HashSet<>();
+ Map<String, MultiParentNode<String>> exploited = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ Set<String> pkTableNames = new HashSet<>();
for (String tableName : tableNames) {
MultiParentNode<String> node = exploited.get(tableName);
@@ -156,7 +163,7 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
}
}
- final List<String> sortedTableNames = new ArrayList<>(tableNames.size());
+ List<String> sortedTableNames = new ArrayList<>(tableNames.size());
MultiParentNodeOp.traverseTree(roots, sortedTableNames);
// remove from sortedTableNames any table possibly added during lookup
@@ -221,17 +228,14 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
return res;
}
- private void doExportTable(
+ private void exportTable(
final TransformerHandler handler,
- final String dbSchema,
final Connection conn,
final String tableName,
final String whereClause) throws SQLException, SAXException {
LOG.debug("Export table {}", tableName);
- AttributesImpl attrs = new AttributesImpl();
-
PreparedStatement stmt = null;
ResultSet rs = null;
try {
@@ -239,34 +243,8 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
DatabaseMetaData meta = conn.getMetaData();
- // ------------------------------------
- // retrieve foreign keys (linked to the same table) to perform an ordered select
- ResultSet pkeyRS = null;
- try {
- pkeyRS = meta.getImportedKeys(conn.getCatalog(), dbSchema, tableName);
- while (pkeyRS.next()) {
- if (tableName.equals(pkeyRS.getString("PKTABLE_NAME"))) {
- String columnName = pkeyRS.getString("FKCOLUMN_NAME");
- if (columnName != null) {
- if (orderBy.length() > 0) {
- orderBy.append(",");
- }
-
- orderBy.append(columnName);
- }
- }
- }
- } finally {
- if (pkeyRS != null) {
- try {
- pkeyRS.close();
- } catch (SQLException e) {
- LOG.error("While closing result set", e);
- }
- }
- }
-
// retrieve primary keys to perform an ordered select
+ ResultSet pkeyRS = null;
try {
pkeyRS = meta.getPrimaryKeys(null, null, tableName);
while (pkeyRS.next()) {
@@ -300,28 +278,49 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
}
stmt = conn.prepareStatement(query.toString());
+ List<Map<String, String>> rows = new ArrayList<>();
+
rs = stmt.executeQuery();
while (rs.next()) {
- attrs.clear();
+ Map<String, String> row = new HashMap<>();
+ rows.add(row);
- final ResultSetMetaData rsMeta = rs.getMetaData();
+ ResultSetMetaData rsMeta = rs.getMetaData();
for (int i = 0; i < rsMeta.getColumnCount(); i++) {
- final String columnName = rsMeta.getColumnName(i + 1);
- final Integer columnType = rsMeta.getColumnType(i + 1);
+ String columnName = rsMeta.getColumnName(i + 1);
+ Integer columnType = rsMeta.getColumnType(i + 1);
// Retrieve value taking care of binary values.
String value = getValues(rs, columnName, columnType);
if (value != null && (!COLUMNS_TO_BE_NULLIFIED.containsKey(tableName)
|| !COLUMNS_TO_BE_NULLIFIED.get(tableName).contains(columnName))) {
- attrs.addAttribute("", "", columnName, "CDATA", value);
+ row.put(columnName, value);
+ LOG.debug("Add for table {}: {}=\"{}\"", tableName, columnName, value);
}
}
+ }
+
+ if (tableName.equalsIgnoreCase(JPARealm.TABLE)) {
+ List<Map<String, String>> realmRows = new ArrayList<>(rows);
+ rows.clear();
+ realmDAO.findAll().forEach(realm -> {
+ realmRows.stream().filter(row -> {
+ String id = row.get("ID");
+ if (id == null) {
+ id = row.get("id");
+ }
+ return realm.getKey().equals(id);
+ }).findFirst().ifPresent(row -> rows.add(row));
+ });
+ }
+
+ for (Map<String, String> row : rows) {
+ AttributesImpl attrs = new AttributesImpl();
+ row.forEach((key, value) -> attrs.addAttribute("", "", key, "CDATA", value));
handler.startElement("", "", tableName, attrs);
handler.endElement("", "", tableName);
-
- LOG.debug("Add record {}", attrs);
}
} finally {
if (rs != null) {
@@ -335,7 +334,7 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
try {
stmt.close();
} catch (SQLException e) {
- LOG.error("While closing result set", e);
+ LOG.error("While closing statement", e);
}
}
}
@@ -377,8 +376,7 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
throw new IllegalArgumentException("Could not find DataSource for domain " + domain);
}
- String dbSchema = ApplicationContextProvider.getBeanFactory().getBean(domain + "DatabaseSchema",
- String.class);
+ String schema = ApplicationContextProvider.getBeanFactory().getBean(domain + "DatabaseSchema", String.class);
Connection conn = null;
ResultSet rs = null;
@@ -386,7 +384,7 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
conn = DataSourceUtils.getConnection(dataSource);
final DatabaseMetaData meta = conn.getMetaData();
- rs = meta.getTables(null, StringUtils.isBlank(dbSchema) ? null : dbSchema, null,
+ rs = meta.getTables(null, StringUtils.isBlank(schema) ? null : schema, null,
new String[] { "TABLE" });
final Set<String> tableNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
@@ -402,10 +400,9 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
LOG.debug("Tables to be exported {}", tableNames);
// then sort tables based on foreign keys and dump
- for (String tableName : sortByForeignKeys(dbSchema, conn, tableNames)) {
+ for (String tableName : sortByForeignKeys(schema, conn, tableNames)) {
try {
- doExportTable(
- handler, dbSchema, conn, tableName, TABLES_TO_BE_FILTERED.get(tableName.toUpperCase()));
+ exportTable(handler, conn, tableName, TABLES_TO_BE_FILTERED.get(tableName.toUpperCase()));
} catch (Exception e) {
LOG.error("Failure exporting table {}", tableName, e);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/761399c4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/XMLContentExporterTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/XMLContentExporterTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/XMLContentExporterTest.java
index a0aa326..03a5313 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/XMLContentExporterTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/XMLContentExporterTest.java
@@ -39,6 +39,11 @@ public class XMLContentExporterTest extends AbstractTest {
@Autowired
private ContentExporter exporter;
+ /**
+ * Also checks for SYNCOPE-1307.
+ *
+ * @throws Exception
+ */
@Test
public void issueSYNCOPE1128() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -53,9 +58,9 @@ public class XMLContentExporterTest extends AbstractTest {
filter(row -> row.startsWith("<REALM")).collect(Collectors.toList());
assertEquals(4, realms.size());
assertTrue(realms.get(0).contains("NAME=\"/\""));
- assertTrue(realms.get(1).contains("NAME=\"two\""));
- assertTrue(realms.get(2).contains("NAME=\"odd\""));
- assertTrue(realms.get(3).contains("NAME=\"even\""));
+ assertTrue(realms.get(1).contains("NAME=\"odd\""));
+ assertTrue(realms.get(2).contains("NAME=\"even\""));
+ assertTrue(realms.get(3).contains("NAME=\"two\""));
}
}